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.