ios - 如何使用委托(delegate)方法从捕获 session 中提取视频?

标签 ios swift avcapturesession avcapturemoviefileoutput

我正在尝试学习相机如何快速工作,所以我创建了一个简单的 viewController 设置 session 、输入和输出实例,然后我开始录制,但视频的长度始终为零且 AVCaptureOutput。 isRunning 始终为假...这是我的代码

class cameraViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

    let recordButton: UIButton = {
        let button = UIButton()
        button.layer.cornerRadius = 30
        button.backgroundColor = UIColor.black
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(startRecording), for: UIControl.Event.touchUpInside)
        return button
    }()

    let session = AVCaptureSession()
    lazy var previewLayer = AVCaptureVideoPreviewLayer(session: session)


    override func viewDidLoad() {
        super.viewDidLoad()
        previewLayer.frame = view.frame
        view.layer.addSublayer(previewLayer)
        setUpSession()
        setUpViewsAndConstraints()
    }


    func setUpViewsAndConstraints(){
        view.addSubview(recordButton)

        recordButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        recordButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -80).isActive = true
        recordButton.widthAnchor.constraint(equalToConstant: 60).isActive = true
        recordButton.heightAnchor.constraint(equalToConstant: 60).isActive = true


    }

    @objc func startRecording(button: UIButton){
        let url = Bundle.main.bundleURL
        let output = (session.outputs[0] as! AVCaptureMovieFileOutput)
        print(output.isRecording)

        if output.isRecording == false {
            print("recording is about to start")
            output.startRecording(to: url, recordingDelegate: self)
        } else {
            print("recording is about to stop")
            output.stopRecording()
        }
    }


    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
        print("recorded duration:",output.recordedDuration)
    }


    func setUpSession(){
        session.beginConfiguration()

        // setting devices and inputs

        guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInDualCamera, for: AVMediaType.video, position: AVCaptureDevice.Position.unspecified) else {return}
        guard let input = try? AVCaptureDeviceInput(device: device) else {print("input failed");return}
        session.addInput(input)

        // setting outputs...

        let videoOutput = AVCaptureMovieFileOutput()
        session.sessionPreset = AVCaptureSession.Preset.high
        session.addOutput(videoOutput)
        session.commitConfiguration()
        session.startRunning()
    }

}

我可以正常地在我的 View 层上看到来自摄像头的输入视频,但是当我按下记录按钮时似乎没有任何效果,委托(delegate)方法立即打印记录的持续时间为零,并且 @objc func startRecording(button: UIButton) 永远不会打印出“录音即将停止”但总是“录音即将开始”..

我应该在方法 output.startRecording(to: url, recordingDelegate: self) 上放置哪个 url?一旦数据进入委托(delegate)方法,我就有点困惑为什么我需要指定这个 URL 我应该把什么放在那里?

我在这里错过了什么?

提前感谢您的回答!!

最佳答案

这里

output.startRecording(to: url, recordingDelegate: self)

您应该输入输出视频的 url,因为您将其设置为

let url = Bundle.main.bundleURL

因为不能写到main bundle中,所以记录没有开始,你可以通过检查打印的错误来验证

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
    print(error)
}

您需要在文档中创建一个 url 并提供它

 let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] 
 let completeMovie = URL(fileURLWithPath: documentsURL.path).appendingPathComponent("video.mp4")

关于ios - 如何使用委托(delegate)方法从捕获 session 中提取视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53585045/

相关文章:

ios - 将未知格式(任何格式)的字符串转换为日期

ios - 将 UIDatePicker 结果转换为 unix 时间戳

ios - 处理有关方向的 AVCaptureVideoDataOutput 图像数据的推荐方法是什么

iphone - 使用 AVCaptureVideoDataOutput 和 AVCaptureAudioDataOutput 时的性能问题

swift - 如何在不中断视频预览的情况下仅在录制时将音频输入添加到 AVCaptureSession?

ios - 在 iOS 应用程序中创建、读取和写入纯文本文件

ios - 应用程序因将数据库存储在文档目录中而被拒绝

ios - 基于 UICollectionViewFlowLayout 的 CoverFlow 布局

ios - 我可以将文本字段分组在一起吗

iOS Swift 到 Objective-C 如何将弱引用传递给数组?