0

I'm using a Swift class that assembles into a video which can be found here: https://stackoverflow.com/a/41159403

I make an array of 70 images. I previously validated these were fine by individually saving them to the camera roll, which I have since commented out.

There is a closure in the method call movieMaker.createMovieFrom where it makes an asset and player item which I commented out, because I don't need the video to play in the app, I just need to save it to my camera roll. I'm unsure if I can get the rendered video to save inside the closure or if I should do it in the CXEImagesToVideo class.

        var uiImages = [UIImage]()

        /** add image to uiImages */
        for _ in 0 ... 30 {
            uiImages.append(UIImage(cgImage: image.cgImage!))
        }

        let settings = CXEImagesToVideo.videoSettings(codec: AVVideoCodecH264, width: (uiImages[0].cgImage?.width)!, height: (uiImages[0].cgImage?.height)!)
        let movieMaker = CXEImagesToVideo(videoSettings: settings)
        movieMaker.createMovieFrom(images: uiImages){ (fileURL:URL) in
//              let video = AVAsset(url: fileURL)
//              let playerItem = AVPlayerItem(asset: video)
//              let player = CXEPlayer()
//              player.setPlayerItem(playerItem: playerItem)
}

I've tried saving the video to the camera roll inside the closure both with:

1) PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: fileURL) - returns Cocoa error -1

2) UISaveVideoAtPathToSavedPhotosAlbum(fileURL.path, nil, nil, nil) - says the video was saved, but there is no video in my camera roll.

            PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: fileURL)
                //UISaveVideoAtPathToSavedPhotosAlbum(fileURL.path, nil, nil, nil)

            }) { saved, error in
                if saved {
                    let alertController = UIAlertController(title: "Your video was successfully saved", message: nil, preferredStyle: .alert)
                    let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
                    alertController.addAction(defaultAction)
                    self.present(alertController, animated: true, completion: nil)
                }else{

                    print("Fetch failed: \(error!.localizedDescription)")

                }
            }

I've also tried various ways (including the ones inside the closure) of saving the video inside the CXEImagesToVideo class inside the self.assetWriter.finishWriting inside DispatchQueue.main.sync. I've also tried creating an asset, and saving it, but it never actually gets to the completion handler:

                let currentAsset = AVMutableComposition(url: self.fileURL)

                let exportPath = self.fileURL.path
                let exportURL = URL(fileURLWithPath: exportPath)

                let exporter = AVAssetExportSession(asset: currentAsset, presetName: AVAssetExportPresetHighestQuality)
                exporter?.outputURL = exportURL

                exporter?.exportAsynchronously(completionHandler: {
                    PHPhotoLibrary.shared().performChanges({
                        PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: exportURL)
                    }) { saved, error in
                        if saved {
                            print("Saved")
                        }else{

                            print("Fetch failed: \(error!.localizedDescription)")

                        }

                    }
                })

I can confirm the class is writing the images by printing messages in the class's newPixelBufferFrom function, and see that it's complete by printing a message in self.assetWriter.finishWriting.

So I've dealt with saving photos, but with using AVAssetWriter to create a video to save to the camera roll, I am completely stumped.

Chewie The Chorkie
  • 4,896
  • 9
  • 46
  • 90

1 Answers1

1

So I finally figured out that nothing was really wrong with the way I was trying to make the video from still images, except that the video was waaaay too large, (resolution) giving me the vague "-1" error upon saving. Interestingly enough, it was able to say it was assembling the video and that it did exist. The only way I was able to get it to crash was to apply my video effect to each frame which was also vague - it just gave me a "Lost connection" to device error in Xcode!

This works fine:

PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: self.fileURL) 

I'll have to figure out a better way of assembling the frames without running out of memory for larger res and longer videos.

Chewie The Chorkie
  • 4,896
  • 9
  • 46
  • 90