web-dev-qa-db-ja.com

AVFoundationでビデオをキャプチャする

私はStackを見て回っていて、これと似たような質問を見つけましたが、私にとってはうまくいきませんでした。私はSwift 3.0。これまでのところ

func beginSession() {
    do {
        let deviceInput = try  AVCaptureDeviceInput(device: captureDevice) as AVCaptureDeviceInput
        if captureSession.inputs.isEmpty {
            self.captureSession.addInput(deviceInput)
        }
        stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]

        if captureSession.canAddOutput(stillImageOutput) {
            captureSession.addOutput(stillImageOutput)
        }

    }
    catch {
        print("error: \(error.localizedDescription)")
    }

    guard let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) else {
        print("no preview layer")
        return
    }

    self.view.layer.addSublayer(previewLayer)
    previewLayer.frame = self.view.layer.frame
    captureSession.startRunning()

    // Subviews
    self.view.addSubview(imgOverlay)
    self.view.addSubview(blur)
    self.view.addSubview(label)
    self.view.addSubview(Flip)
    self.view.addSubview(btnCapture)
}

そして

 // SAVE PHOTO
func saveToCamera() {
    if let videoConnection = stillImageOutput.connection(withMediaType: AVMediaTypeVideo) {
        stillImageOutput.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (CMSampleBuffer, Error) in
            if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(CMSampleBuffer) {
                if let cameraImage = UIImage(data: imageData) {
                    self.flippedImage = UIImage(cgImage: cameraImage.cgImage!, scale: cameraImage.scale, orientation: UIImageOrientation.rightMirrored)
                    UIImageWriteToSavedPhotosAlbum(self.flippedImage, nil, nil, nil)

                }
            }
        })
    }

}
21
Adam Allard

AVFoundationでビデオレコーダーを作成するために必要なコード全体を投稿することで、簡単にできるようにします。このコードは、そのままコピーして貼り付けるだけで機能します。覚えておく必要があるのは、camPreviewアウトレットをStoryBoardのViewControllerのUIViewに接続する必要があることだけです。このUIViewは、画面のコンテンツ全体を占有する必要があります。コードの説明をフォローアップして、独自の調査を行い、アプリのニーズに合わせてビデオレコーダーを変更できるようにします。また、info.plistに関連するプライバシー権限を必ず設定する必要があります。これらは、プライバシー-マイク使用説明とプライバシー-カメラ使用説明です。そうでない場合は、黒い画面しか表示されません。

注:右下に、「録画済みビデオの再生」というタイトルの下に録画済みビデオの再生方法を追加しました。

編集-録音中にクラッシュする2つのことを忘れていましたが、それらを追加しました。

Swift 4

import UIKit

import AVFoundation

class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

    @IBOutlet weak var camPreview: UIView!

    let cameraButton = UIView()

    let captureSession = AVCaptureSession()

    let movieOutput = AVCaptureMovieFileOutput()

    var previewLayer: AVCaptureVideoPreviewLayer!

    var activeInput: AVCaptureDeviceInput!

    var outputURL: URL!

    override func viewDidLoad() {
        super.viewDidLoad()

        if setupSession() {
            setupPreview()
            startSession()
        }

        cameraButton.isUserInteractionEnabled = true

        let cameraButtonRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.startCapture))

        cameraButton.addGestureRecognizer(cameraButtonRecognizer)

        cameraButton.frame = CGRect(x: 0, y: 0, width: 100, height: 100)

        cameraButton.backgroundColor = UIColor.red

        camPreview.addSubview(cameraButton)

    }

    func setupPreview() {
        // Configure previewLayer
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = camPreview.bounds
        previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        camPreview.layer.addSublayer(previewLayer)
    }

    //MARK:- Setup Camera

    func setupSession() -> Bool {

        captureSession.sessionPreset = AVCaptureSession.Preset.high

        // Setup Camera
        let camera = AVCaptureDevice.default(for: AVMediaType.video)!

        do {

            let input = try AVCaptureDeviceInput(device: camera)

            if captureSession.canAddInput(input) {
                captureSession.addInput(input)
                activeInput = input
            }
        } catch {
            print("Error setting device video input: \(error)")
            return false
        }

        // Setup Microphone
        let microphone = AVCaptureDevice.default(for: AVMediaType.audio)!

        do {
            let micInput = try AVCaptureDeviceInput(device: microphone)
            if captureSession.canAddInput(micInput) {
                captureSession.addInput(micInput)
            }
        } catch {
            print("Error setting device audio input: \(error)")
            return false
        }


        // Movie output
        if captureSession.canAddOutput(movieOutput) {
            captureSession.addOutput(movieOutput)
        }

        return true
    }

    func setupCaptureMode(_ mode: Int) {
        // Video Mode

    }

    //MARK:- Camera Session
    func startSession() {

        if !captureSession.isRunning {
            videoQueue().async {
                self.captureSession.startRunning()
            }
        }
    }

    func stopSession() {
        if captureSession.isRunning {
            videoQueue().async {
                self.captureSession.stopRunning()
            }
        }
    }

    func videoQueue() -> DispatchQueue {
        return DispatchQueue.main
    }

    func currentVideoOrientation() -> AVCaptureVideoOrientation {
        var orientation: AVCaptureVideoOrientation

        switch UIDevice.current.orientation {
            case .portrait:
                orientation = AVCaptureVideoOrientation.portrait
            case .landscapeRight:
                orientation = AVCaptureVideoOrientation.landscapeLeft
            case .portraitUpsideDown:
                orientation = AVCaptureVideoOrientation.portraitUpsideDown
            default:
                 orientation = AVCaptureVideoOrientation.landscapeRight
         }

         return orientation
     }

    @objc func startCapture() {

        startRecording()

    }

    //EDIT 1: I FORGOT THIS AT FIRST

    func tempURL() -> URL? {
        let directory = NSTemporaryDirectory() as NSString

        if directory != "" {
            let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
            return URL(fileURLWithPath: path)
        }

        return nil
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        let vc = segue.destination as! VideoPlaybackViewController

        vc.videoURL = sender as? URL

    }

    func startRecording() {

        if movieOutput.isRecording == false {

            let connection = movieOutput.connection(with: AVMediaType.video)

            if (connection?.isVideoOrientationSupported)! {
                connection?.videoOrientation = currentVideoOrientation()
            }

            if (connection?.isVideoStabilizationSupported)! {
                connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
            }

            let device = activeInput.device

            if (device.isSmoothAutoFocusSupported) {

                do {
                    try device.lockForConfiguration()
                    device.isSmoothAutoFocusEnabled = false
                    device.unlockForConfiguration()
                } catch {
                   print("Error setting configuration: \(error)")
                }

            }

            //EDIT2: And I forgot this
            outputURL = tempURL()
            movieOutput.startRecording(to: outputURL, recordingDelegate: self)

            }
            else {
                stopRecording()
            }

       }    

   func stopRecording() {

       if movieOutput.isRecording == true {
           movieOutput.stopRecording()
        }
   }

    func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {

    }

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

        if (error != nil) {

            print("Error recording movie: \(error!.localizedDescription)")

        } else {

            let videoRecorded = outputURL! as URL

            performSegue(withIdentifier: "showVideo", sender: videoRecorded)

        }

    }

}

Swift 3

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

@IBOutlet weak var camPreview: UIView!

let cameraButton = UIView()

let captureSession = AVCaptureSession()

let movieOutput = AVCaptureMovieFileOutput()

var previewLayer: AVCaptureVideoPreviewLayer!

var activeInput: AVCaptureDeviceInput!

var outputURL: URL!

override func viewDidLoad() {
    super.viewDidLoad()

    if setupSession() {
        setupPreview()
        startSession()
    }

    cameraButton.isUserInteractionEnabled = true

    let cameraButtonRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.startCapture))

    cameraButton.addGestureRecognizer(cameraButtonRecognizer)

    cameraButton.frame = CGRect(x: 0, y: 0, width: 100, height: 100)

    cameraButton.backgroundColor = UIColor.red

    camPreview.addSubview(cameraButton)

}

func setupPreview() {
    // Configure previewLayer
    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = camPreview.bounds
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
    camPreview.layer.addSublayer(previewLayer)
}

//MARK:- Setup Camera

func setupSession() -> Bool {

    captureSession.sessionPreset = AVCaptureSessionPresetHigh

    // Setup Camera
    let camera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    do {
        let input = try AVCaptureDeviceInput(device: camera)
        if captureSession.canAddInput(input) {
            captureSession.addInput(input)
            activeInput = input
        }
    } catch {
        print("Error setting device video input: \(error)")
        return false
    }

    // Setup Microphone
    let microphone = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)

    do {
        let micInput = try AVCaptureDeviceInput(device: microphone)
        if captureSession.canAddInput(micInput) {
            captureSession.addInput(micInput)
        }
    } catch {
        print("Error setting device audio input: \(error)")
        return false
    }


    // Movie output
    if captureSession.canAddOutput(movieOutput) {
        captureSession.addOutput(movieOutput)
    }

    return true
}

func setupCaptureMode(_ mode: Int) {
        // Video Mode

}

//MARK:- Camera Session
func startSession() {


    if !captureSession.isRunning {
        videoQueue().async {
            self.captureSession.startRunning()
        }
    }
}

func stopSession() {
    if captureSession.isRunning {
        videoQueue().async {
            self.captureSession.stopRunning()
        }
    }
}

func videoQueue() -> DispatchQueue {
    return DispatchQueue.main
}



func currentVideoOrientation() -> AVCaptureVideoOrientation {
    var orientation: AVCaptureVideoOrientation

    switch UIDevice.current.orientation {
    case .portrait:
        orientation = AVCaptureVideoOrientation.portrait
    case .landscapeRight:
        orientation = AVCaptureVideoOrientation.landscapeLeft
    case .portraitUpsideDown:
        orientation = AVCaptureVideoOrientation.portraitUpsideDown
    default:
        orientation = AVCaptureVideoOrientation.landscapeRight
    }

    return orientation
}

func startCapture() {

    startRecording()

}

//EDIT 1: I FORGOT THIS AT FIRST

func tempURL() -> URL? {
    let directory = NSTemporaryDirectory() as NSString

    if directory != "" {
        let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
        return URL(fileURLWithPath: path)
    }

    return nil
}


func startRecording() {

    if movieOutput.isRecording == false {

        let connection = movieOutput.connection(withMediaType: AVMediaTypeVideo)
        if (connection?.isVideoOrientationSupported)! {
            connection?.videoOrientation = currentVideoOrientation()
        }

        if (connection?.isVideoStabilizationSupported)! {
            connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
        }

        let device = activeInput.device
        if (device?.isSmoothAutoFocusSupported)! {
            do {
                try device?.lockForConfiguration()
                device?.isSmoothAutoFocusEnabled = false
                device?.unlockForConfiguration()
            } catch {
                print("Error setting configuration: \(error)")
            }

        }

        //EDIT2: And I forgot this
        outputURL = tempURL()
        movieOutput.startRecording(toOutputFileURL: outputURL, recordingDelegate: self)

    }
    else {
        stopRecording()
    }

}

func stopRecording() {

    if movieOutput.isRecording == true {
        movieOutput.stopRecording()
    }
}

func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {

}

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    if (error != nil) {
        print("Error recording movie: \(error!.localizedDescription)")
    } else {

        _ = outputURL as URL

    }
    outputURL = nil
}



}

これがView Controllerのセットアップ方法です

Setup your View Controller with campPreview

Info.plistの権限

plist permissions

録音代理人の設定

AVCaptureFileOutputRecordingDelegateに準拠する必要があります。 Apple docsによれば、AVCaptureFileOutputのデリゲートが単一ファイルの記録プロセスで発生するイベントに応答するためのインターフェイスを定義します。実装する必要がある2つのメソッドがあります。コードの最後にある最後の2つのメソッド。

func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {
}

ビデオの記録を開始するときに、これに任意のロジックを追加できます。私が指定したコード例では、左隅の赤い四角ボタンをタップするとビデオの録画が開始されます。二つ目は、

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    if (error != nil) {
        print("Error recording movie: \(error!.localizedDescription)")
    } else {

        _ = outputURL as URL

    }
    outputURL = nil
}

これは、ビデオの記録が終了したときに呼び出されます。コード例では、赤い四角ボタンをもう一度タップした後にビデオが録画を停止するように指定しています。ビデオの記録が停止すると、出力ファイルのURLが取得されます。これはビデオを表します。これを使用して別のView Controllerに接続し、AVPlayerでビデオを再生することができます。または、保存することもできます。ただし、この例では、出力URLをあまり処理していません。

ビデオの録画を開始するには、プログラムで作成されたボタンを使用しました。このボタンは、左隅に赤い正方形として表示され、UITapGestureに応答します。アプリでより良いボタンを作成できます。

セッションのセットアップ

ビデオレコーダーには、setupSession()で設定したキャプチャセッションが必要です。ここで、カメラとマイクを含むAVCapture入力デバイスを追加します。 Appleによると、AVCaptureDeviceInputはAVCaptureDeviceオブジェクトからデータをキャプチャするために使用するAVCaptureInputの具象サブクラスです。ただし、ユーザーはこれらを使用するためのアクセスを許可する必要があるため、info.plistでプライバシー-マイクの使用法の説明とプライバシー-カメラの使用法の説明を追加し、ビデオレコーダーとマイクを使用する理由を指定する必要があります。これを行わないと、黒い画面しか表示されません。セッションプリセットは、出力の品質レベルまたはビットレートを示す定数値です。これを高に設定しましたが、他のオプションを探索できます。 movieOutputのタイプはAVCaptureMovieFileOutputで、Appleによると、データをQuickTimeムービーにキャプチャするために使用するAVCaptureFileOutputの具体的なサブクラスです。これにより、実際にビデオを録画および保存できます。

プレビューの設定

ここで、setupPreview()で行われるカメラプレビューレイヤーをセットアップします。次のAVCaptureVideoPreviewLayer(session:captureSession)で作成したキャプチャセッションでプレビューレイヤーをセットアップします。

セッションの開始

最後のステップは、startSession()で行われるセッションを開始することです。セッションがすでに実行されているかどうかを確認し、実行されていない場合は開始します。

if !captureSession.isRunning {
    videoQueue().async {
        self.captureSession.startRunning()
    }
}

記録の開始

赤いボタンをタップすると、startRecording()メソッドが呼び出されます。ここで、ビデオの向きとビデオの安定化を処理するメソッドを追加しました。最後に、セッションで以前にセットアップしたmovieOutput変数が再び表示されます。呼び出してムービーをoutputURLに記録し、記録の開始と終了を処理するデリゲートメソッドが同じView Controllerにあることを伝えます(最後の2つのメソッド)。

記録の停止

赤いボタンをもう一度タップすると、startRecodingが再度呼び出されますが、何かが記録されていることに気付き、stopRecordingを呼び出します。

録画したビデオの再生

今日は気前がいいので、これも入れます。

新しいView Controllerを作成し、VideoPlaybackと呼びます。 Storyboardのセグエを使用して、最初のViewControllerに接続します。セグエに「showVideo」の識別子を付けます。 UIViewを作成してVideoPlaybackの画面をいっぱいにし、videoViewと呼ばれるビューコントローラーへのアウトレットを作成します。次のコードを新しいVideoPlayback View Controllerに追加します。

Swift 4

import UIKit
import AVFoundation

class VideoPlayback: UIViewController {

    let avPlayer = AVPlayer()
    var avPlayerLayer: AVPlayerLayer!

    var videoURL: URL!
    //connect this to your uiview in storyboard
    @IBOutlet weak var videoView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        avPlayerLayer = AVPlayerLayer(player: avPlayer)
        avPlayerLayer.frame = view.bounds
        avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        videoView.layer.insertSublayer(avPlayerLayer, at: 0)

        view.layoutIfNeeded()

        let playerItem = AVPlayerItem(url: videoURL as URL)
        avPlayer.replaceCurrentItem(with: playerItem)

        avPlayer.play()
    }
}

Swift 3

import UIKit
import AVFoundation

class VideoPlayback: UIViewController {

    let avPlayer = AVPlayer()
    var avPlayerLayer: AVPlayerLayer!

    var videoURL: URL!
    //connect this to your uiview in storyboard
    @IBOutlet weak var videoView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        avPlayerLayer = AVPlayerLayer(player: avPlayer)
        avPlayerLayer.frame = view.bounds
        avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        videoView.layer.insertSublayer(avPlayerLayer, at: 0)

        view.layoutIfNeeded()

        let playerItem = AVPlayerItem(url: videoURL as URL)
        avPlayer.replaceCurrentItem(with: playerItem)

        avPlayer.play()
    }
}

最後のデリゲートメソッドに戻り、次のように変更します。

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {

    if (error != nil) {
        print("Error recording movie: \(error!.localizedDescription)")
    } else {

        let videoRecorded = outputURL! as URL

        performSegue(withIdentifier: "showVideo", sender: videoRecorded)
    }
}

最後に、AVPlayerで再生するvideoURLを初期化するセグエメソッドの準備を作成します。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    let vc = segue.destination as! VideoPlayback
    vc.videoURL = sender as! URL
}

テストするには、戻ってビデオの録画を開始します。赤い四角の2回目のタップでセグエが実行され、録画されたビデオが自動的に再生されます。

81
gwinyai

@gwinyaiの驚くべき答えに基づいて、私は同様のカメラフレームワークを作成しました。 https://github.com/eonist/HybridCamera これは写真の撮影もサポートしており、この行によって引き起こされた@Maksim Kniazevによって説明されたグリッチの問題はありません。

if (connection?.isVideoStabilizationSupported)! {
    connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
}
4
eonist

@gwinyaiの回答から(Swift 4)の最新バージョンに更新

import UIKit
import AVFoundation


class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

@IBOutlet weak var camPreview: UIView!
let captureSession = AVCaptureSession()
let movieOutput = AVCaptureMovieFileOutput()

var previewLayer: AVCaptureVideoPreviewLayer!
var activeInput: AVCaptureDeviceInput!
var outputURL: URL!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    if setupSession() {
        setupPreview()
        startSession()
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
func setupPreview() {
    // Configure previewLayer
    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = camPreview.bounds
    previewLayer.videoGravity = .resizeAspectFill
    camPreview.layer.addSublayer(previewLayer)
}

//MARK:- Setup Camera

func setupSession() -> Bool {
    captureSession.sessionPreset = AVCaptureSession.Preset.high

    // Setup Camera
    let camera = AVCaptureDevice.default(for: .video)

    do {
        let input = try AVCaptureDeviceInput(device: camera!)
        if captureSession.canAddInput(input) {
            captureSession.addInput(input)
            activeInput = input
        }
    } catch {
        print("Error setting device video input: \(error)")
        return false
    }

    // Setup Microphone
    let microphone = AVCaptureDevice.default(for: .audio)

    do {
        let micInput = try AVCaptureDeviceInput(device: microphone!)
        if captureSession.canAddInput(micInput) {
            captureSession.addInput(micInput)
        }
    } catch {
        print("Error setting device audio input: \(error)")
        return false
    }


    // Movie output
    if captureSession.canAddOutput(movieOutput) {
        captureSession.addOutput(movieOutput)
    }

    return true
}

func setupCaptureMode(_ mode: Int) {
    // Video Mode

}

//MARK:- Camera Session
func startSession() {


    if !captureSession.isRunning {
        videoQueue().async {
            self.captureSession.startRunning()
        }
    }
}

func stopSession() {
    if captureSession.isRunning {
        videoQueue().async {
            self.captureSession.stopRunning()
        }
    }
}

func videoQueue() -> DispatchQueue {
    return DispatchQueue.main
}



func currentVideoOrientation() -> AVCaptureVideoOrientation {
    var orientation: AVCaptureVideoOrientation

    switch UIDevice.current.orientation {
    case .portrait:
        orientation = AVCaptureVideoOrientation.portrait
    case .landscapeRight:
        orientation = AVCaptureVideoOrientation.landscapeLeft
    case .portraitUpsideDown:
        orientation = AVCaptureVideoOrientation.portraitUpsideDown
    default:
        orientation = AVCaptureVideoOrientation.landscapeRight
    }

    return orientation
}

func startCapture() {

    startRecording()

}

//EDIT 1: I FORGOT THIS AT FIRST

func tempURL() -> URL? {
    let directory = NSTemporaryDirectory() as NSString

    if directory != "" {
        let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
        return URL(fileURLWithPath: path)
    }

    return nil
}


func startRecording() {

    if movieOutput.isRecording == false {

        let connection = movieOutput.connection(with: .video)
        if (connection?.isVideoOrientationSupported)! {
            connection?.videoOrientation = currentVideoOrientation()
        }

        if (connection?.isVideoStabilizationSupported)! {
            connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
        }

        let device = activeInput.device
        if (device.isSmoothAutoFocusSupported) {
            do {
                try device.lockForConfiguration()
                device.isSmoothAutoFocusEnabled = false
                device.unlockForConfiguration()
            } catch {
                print("Error setting configuration: \(error)")
            }

        }

        //EDIT2: And I forgot this
        outputURL = tempURL()
        movieOutput.startRecording(to: outputURL, recordingDelegate: self)

    }
    else {
        stopRecording()
    }

}

func stopRecording() {

    if movieOutput.isRecording == true {
        movieOutput.stopRecording()
    }
}

func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {

}

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
    if (error != nil) {
        print("Error recording movie: \(error!.localizedDescription)")
    } else {
        _ = outputURL as URL
    }
    outputURL = nil
}

}
2
mert