如何使用应用内按钮将 ReplayKit 视频保存到相机胶卷 [英] How to Save ReplayKit Video to Camera Roll with In-App Button

查看:46
本文介绍了如何使用应用内按钮将 ReplayKit 视频保存到相机胶卷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am relatively new to iOS development and Swift but I have an app I'm working on which is supposed to record the activity on the screen and save the resulting video to the camera roll. I am using ReplayKit.

现在的工作:

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

This is the code I have beginning the recording and ending the recording the startRecording() function is run by a button that says "start" and the stopRecording() function is called by a button that says "stop".

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)
        }
    }

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

The screen records fine. I have a button which says "Finish" which will call the stopRecording() function. When that button is clicked, a preview will show up which will play the recorded video and allow the user to manually edit and save the video.

我想做什么:

我需要让按钮简单地将视频按原样保存到相机胶卷中.我想绕过允许用户编辑和手动保存的预览屏幕.这可能吗?如果是这样,您将如何解决这个问题?

I need to make the button simply save the video as is to the camera roll. I want to bypass the preview screen which allows the user to edit and manually save. Is this possible? If so, how would you approach the problem?

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

The preview is of type RPPreviewViewController? and try as I might, I just can't seem to access the video for saving. Since ReplayKit is an extension of UIKit, I tried using the

UISaveVideoAtPathToSavedPhotosAlbum(_ videoPath: String, _ completionTarget: AnyObject?, _ completionSelector: Selector, _ contextInfo: UnsafeMutablePointer<Void>)

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

method but none of those attributes exist!

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

If you need anymore info, please let me know. If I'm an idiot, please let me know! This is my first post here so be nice! and Thanks.

推荐答案

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

As mentioned by Geoff H, Replay Kit 2 now allows you to record the screen and save it either within your app or to the gallery without having to use the preview.

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

The documentation is sparse but after some trial and experiment the below code works in iOS 12.

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

Note this only captures video and not audio, although that should be straightforward to add, and you may want to add more error checking if using it. The functions below can be triggered by UI buttons, for example.

 @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");
                }
            }
        }

这篇关于如何使用应用内按钮将 ReplayKit 视频保存到相机胶卷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆