I'm attempting to use ReplayKit and save the video of the screen capture to my camera roll.
However I'm getting an error when I try to save it at the very bottom of my code, that last error check: "Video did not save for some reason"
Optional(Error Domain=NSCocoaErrorDomain Code=-1 “(null)“)
“The operation couldn’t be completed. (Cocoa error -1.)”
I've looked around at a number of other questions similar to this but most of them have a trail of unanswered comments similar to "I'm getting this too, did you ever get an answer to this"
Would love some help on this. Thanks!
private func startRecording() {
//Create the file path to write to
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
self.videoOutputURL = URL(fileURLWithPath: documentsPath.appendingPathComponent(UUID.init().description + ".mp4"))
//Check the file does not already exist by deleting it if it does
do {
try FileManager.default.removeItem(at: videoOutputURL!)
} catch {}
do {
try videoWriter = AVAssetWriter(outputURL: videoOutputURL!, fileType: .mp4)
} catch let writerError as NSError {
print("Error opening video file", writerError);
videoWriter = nil;
return;
}
//Create the video settings
let videoSettings: [String : Any] = [
AVVideoCodecKey: AVVideoCodecType.h264,
AVVideoWidthKey: view.bounds.width,
AVVideoHeightKey: view.bounds.height
]
//Create the asset writer input object whihc is actually used to write out the video
//with the video settings we have created
videoWriterInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings);
videoWriterInput!.expectsMediaDataInRealTime = true
videoWriter?.add(videoWriterInput!);
let recorder = RPScreenRecorder.shared()
guard recorder.isAvailable else { return } // or throw error
recorder.startCapture(handler: { (buffer, sampleType, error) in
guard error == nil else {
return DispatchQueue.main.async { self.presentError(error!) }
}
switch sampleType {
case .video:
print("writing sample....")
switch self.videoWriter!.status {
case .unknown:
if self.videoWriter?.startWriting != nil {
print("Starting writing")
self.videoWriter!.startWriting()
self.videoWriter!.startSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(buffer))
}
case .writing:
if self.videoWriterInput!.isReadyForMoreMediaData {
print("Writing a sample")
if self.videoWriterInput!.append(buffer) == false {
print(" we have a problem writing video")
}
}
default: break
}
default:
print("not a video sample, so ignore");
}
})
}
private func stopRecording() {
let recorder = RPScreenRecorder.shared()
recorder.stopCapture { [unowned self] error in
guard error == nil else {
return DispatchQueue.main.async { self.presentError(error!) }
}
self.saveVideoToCameraRoll(completion: completion)
}
}
func saveVideoToCameraRoll(completion: (() -> Void)?) {
//Now save the video
PHPhotoLibrary.shared().performChanges({
print(self.videoOutputURL!)
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: self.videoOutputURL!)
}) { 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) { _ in
completion?()
}
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
if error != nil {
print("Video did not save for some reason", error.debugDescription)
debugPrint(error?.localizedDescription ?? "error is nil")
}
}
}
```
Seems like you forgot to finish writing to the file when you stop recording:
private func stopRecording() {
let recorder = RPScreenRecorder.shared()
recorder.stopCapture { [unowned self] error in
...
self.videoWriter?.finishWriting {
self.saveVideoToCameraRoll(completion: completion)
}
}
}