如何使用应用程序按钮将ReplayKit视频保存到相机胶卷

eri*_*ess 16 ios swift swift2

我对iOS开发和Swift相对较新,但我有一个我正在研究的应用程序应该在屏幕上记录活动并将生成的视频保存到相机胶卷.我正在使用ReplayKit.

什么在现在:

这是我开始录制和结束录制的代码,该startRecording()功能由一个显示"开始"的按钮运行,该stopRecording()功能由一个显示"停止"的按钮调用.

var preview : RPPreviewViewController?

    func startRecording() {
        let recorder = RPScreenRecorder.sharedRecorder()
        recorder.startRecordingWithMicrophoneEnabled(true) { 
            [unowned self] (error) in
            print(recorder)
            if let unwrappedError = error {
                print(unwrappedError.localizedDescription)
            }
        }
    }

    func stopRecording() {
        let recorder = RPScreenRecorder.sharedRecorder()
        recorder.stopRecordingWithHandler {
            [unowned self] (preview, error) in
                if let unwrappedError = error {
                    print(unwrappedError.localizedDescription)
                }

        if let unwrappedPreview = preview {
            print("end")
            unwrappedPreview.previewControllerDelegate = self
    unwrappedPreview.modalPresentationStyle=UIModalPresentationStyle.FullScreen
            self.presentViewController(unwrappedPreview, animated: true, completion: nil)
        }
    }
Run Code Online (Sandbox Code Playgroud)

屏幕记录正常.我有一个按钮,上面写着"完成",它会调用stopRecording()函数.单击该按钮时,将显示预览,播放录制的视频并允许用户手动编辑和保存视频.

我正在做的事情:

我需要将按钮简单地保存为相机胶卷.我想绕过预览屏幕,允许用户编辑和手动保存.这可能吗?如果是这样,你会如何处理这个问题?

预览是类型,RPPreviewViewController?并尽可能尝试,我似乎无法访问视频进行保存.由于ReplayKit是UIKit的扩展,我尝试使用

UISaveVideoAtPathToSavedPhotosAlbum(_ videoPath: String, _ completionTarget: AnyObject?, _ completionSelector: Selector, _ contextInfo: UnsafeMutablePointer<Void>)
Run Code Online (Sandbox Code Playgroud)

方法,但这些属性都不存在!

如果您需要更多信息,请告诉我.如果我是白痴,请告诉我!这是我在这里的第一篇文章,所以要好!谢谢.

Mic*_*ick 8

正如 Geoff H 所提到的,Replay Kit 2 现在允许您录制屏幕并将其保存在您的应用程序或画廊中,而无需使用预览。

文档很少,但经过一些试验和实验,下面的代码可以在 iOS 12 中运行。

请注意,这仅捕获视频而不是音频,尽管添加应该很简单,如果使用它,您可能需要添加更多错误检查。例如,以下功能可以由 UI 按钮触发。

 @objc func startRecording() {
        //Use ReplayKit to record the screen

        //Create the file path to write to
        let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
        self.videoOutputURL = URL(fileURLWithPath: documentsPath.appendingPathComponent("MyVideo.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: AVFileType.mp4)
        } catch let writerError as NSError {
            os_log("Error opening video file", writerError);
            videoWriter = nil;
            return;
        }

        //Create the video settings
        let videoSettings: [String : Any] = [
            AVVideoCodecKey  : AVVideoCodecType.h264,
            AVVideoWidthKey  : 1920,  //Replace as you need
            AVVideoHeightKey : 1080   //Replace as you need
        ]

        //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: AVMediaType.video, outputSettings: videoSettings);
        videoWriter.add(videoWriterInput);

        //Tell the screen recorder to start capturing and to call the handler when it has a
        //sample 
        RPScreenRecorder.shared().startCapture(handler: { (cmSampleBuffer, rpSampleType, error) in

            guard error == nil else {
                //Handle error
                os_log("Error starting capture");
                return;
            }

            switch rpSampleType {
                case RPSampleBufferType.video:
                    os_log("writing sample....");
                    if self.videoWriter.status == AVAssetWriter.Status.unknown {

                        if (( self.videoWriter?.startWriting ) != nil) {
                            os_log("Starting writing");
                            self.videoWriter.startWriting()
                            self.videoWriter.startSession(atSourceTime:  CMSampleBufferGetPresentationTimeStamp(cmSampleBuffer))
                        }
                    }

                    if self.videoWriter.status == AVAssetWriter.Status.writing {
                        if (self.videoWriterInput.isReadyForMoreMediaData == true) {
                            os_log("Writting a sample");
                            if  self.videoWriterInput.append(cmSampleBuffer) == false {
                                print(" we have a problem writing video")
                            }
                        }
                }

                default:
                    os_log("not a video sample, so ignore");
            }
        } )
    }

    @objc func stoprecording() {
        //Stop Recording the screen
        RPScreenRecorder.shared().stopCapture( handler: { (error) in
            os_log("stopping recording");
        })

        self.videoWriterInput.markAsFinished();
        self.videoWriter.finishWriting {
            os_log("finished writing video");

            //Now save the video
            PHPhotoLibrary.shared().performChanges({
                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, handler: nil)
                    alertController.addAction(defaultAction)
                    self.present(alertController, animated: true, completion: nil)
                }
                if error != nil {
                    os_log("Video did not save for some reason", error.debugDescription);
                    debugPrint(error?.localizedDescription ?? "error is nil");
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)


Vip*_*ney 3

我也想做你所要求的,但到目前为止RPScreenRecorder还没有提供任何这些功能。