So the use case I want to do is easy.
1.) Select a video from library
2.) Trim video and apply a CIFilter
2.1 Confirm filter and redirect to the view controller where I do the upload
The exception I get is:
"The file “editedVideo.mov” couldn’t be opened because there is no such file."
The approach above works with videos which are about 30-35 sec. (without trmming). If I upload a video which is about two minutes, then it always fails.
I need your help. Thank you and stay healthy!
) Select a video from library
) Trim video and apply a CIFilter
) Upload it to FireStore
1.) Select a video from library
Code Block func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { var image = UIImage() let applyEffectController = STORYBOARD.instantiateViewController(withIdentifier: "applyEffects") as! ApplyEffectsViewController if let mediaType = info[UIImagePickerController.InfoKey.mediaType] as? String { if mediaType == "public.image" { let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage image = pickedImage! } if mediaType == "public.movie" { let videoURL = info[.mediaURL] as! URL image = AVUtil.createThumbnail(videoURL: videoURL) let avAsset = AVUtil.trimVideo(videoURL: videoURL) let fileManager = FileManager.default let documents = try! fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) try! avAsset.export(to: documents.appendingPathComponent(VIDEO_NAME)) applyEffectController.avAsset = avAsset applyEffectController.IS_VIDEO_SELECTED = true } } self.dismiss(animated: true, completion: nil) applyEffectController.challengeImage = image self.navigationController?.pushViewController(applyEffectController, animated: true) }
2.) Trim video and apply a CIFilter
Code Block func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { var chosenFilter = filterImagesArray[indexPath.row] chosenFilter = stripFileExtension(chosenFilter) let contentFilter = CIFilter(name: chosenFilter) let challengeCIImage = CIImage(image: challengeImage) contentFilter!.setValue(challengeCIImage, forKey: kCIInputImageKey) let editedChallengeImage = contentFilter!.value(forKey: kCIOutputImageKey) as! CIImage challengeImageView.image = UIImage(ciImage: editedChallengeImage) if (IS_VIDEO_SELECTED) { playerItem?.videoComposition = AVVideoComposition(asset: avAsset!, applyingCIFiltersWithHandler: { (request) in let source = request.sourceImage.clampedToExtent() contentFilter?.setValue(source, forKey: kCIInputImageKey) _ = CMTimeGetSeconds(request.compositionTime) let output = contentFilter?.outputImage!.cropped(to: request.sourceImage.extent) request.finish(with: output!, context: nil) }) } }
2.1 Confirm filter and redirect to the view controller where I do the upload
Code Block @objc func confirmButton_clicked() { let createChallengeController = STORYBOARD.instantiateViewController(withIdentifier: "createChallenge") as! CreateChallengeViewController createChallengeController.IS_VIDEO_SELECTED = IS_VIDEO_SELECTED createChallengeController.challengeImage = challengeImageView.image! createChallengeController.challengeObject = challengeObject if (IS_VIDEO_SELECTED) { let fileManager = FileManager.default let documents = try! fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) if (fileManager.fileExists(atPath: documents.appendingPathComponent(EDITED_VIDEO_NAME).path)) { DispatchQueue.main.async(execute: { try! fileManager.removeItem(atPath: documents.appendingPathComponent(EDITED_VIDEO_NAME).path) }) } let videoExport = AVAssetExportSession(asset: (playerItem?.asset)!, presetName: AVAssetExportPresetMediumQuality) videoExport?.outputFileType = .mov videoExport?.outputURL = documents.appendingPathComponent(EDITED_VIDEO_NAME) videoExport?.videoComposition = playerItem?.videoComposition createChallengeController.challengeImage = self.challengeImageView.image! print(videoExport?.outputURL) let group = DispatchGroup() group.enter() self.view.addSubview(activityView) videoExport?.exportAsynchronously(completionHandler: { createChallengeController.videoURL = videoExport?.outputURL group.leave() }) group.notify(queue: .main) { self.navigationController?.pushViewController(createChallengeController, animated: true) self.activityView.removeFromSuperview() } } else { self.navigationController?.pushViewController(createChallengeController, animated: true) } }
*3.) Upload it to FireStore
Code Block var videoData = NSData() do { videoData = try NSData(contentsOf: self.videoURL!, options: .dataReadingMapped) } catch { cancelChallenge(challengeId: challengeId) // always goes here -> it fails return }
The exception I get is:
"The file “editedVideo.mov” couldn’t be opened because there is no such file."
The approach above works with videos which are about 30-35 sec. (without trmming). If I upload a video which is about two minutes, then it always fails.
I need your help. Thank you and stay healthy!
*