Как извлечь видео из сеанса захвата с помощью метода делегата? - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь узнать, как работает камера в swift, поэтому я создал простой viewController, установил сеанс, экземпляры ввода и вывода, а затем я начал запись, но длина видео всегда равна нулю и 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()
    }

}

Я могу нормально видеть входное видео с камеры на слое просмотра, но когда я нажимаю кнопку записи, кажется, что ничего не работает, метод делегата печатается правильнопрочтем, что записанная длительность равна нулю, и @objc func startRecording(button: UIButton) никогда не печатает «запись вот-вот остановится», но всегда «запись вот-вот начнется» ..

и какой URL я должен указать в методе output.startRecording(to: url, recordingDelegate: self)?Я был немного смущен, когда данные переходят к методу делегата. Почему мне нужно указать этот URL-адрес, что мне нужно указать там?

что мне здесь не хватает?

Заранее благодарим вас заответ !!

1 Ответ

0 голосов
/ 03 декабря 2018

Здесь

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

вы должны указать URL-адрес выходного видео, а поскольку вы установили его на

let url = Bundle.main.bundleURL

, который не может записываться в основной пакет, поэтому запись не выполняется.Вначале вы можете убедиться, что, проверив напечатанную ошибку

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")
...