[iOS] AVFoundation(AVCaptureMovieFileOutput)を使用したビデオ録画を作ってみた

2017.01.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

本記事は、AVFoundationを使用したビデオの録画を紹介するものです。

AVFoundationを使用する場合の共通的な処理については下記に纏めましたので、是非、ご参照下さい。
[iOS] AVFundationを使用して、「ビデオ録画」や「連写カメラ」や「QRコードリーダー」や「バーコードリーダー」を作ってみた

2 入出力

ビデオの録画機能を実装する場合、入力として、カメラ(今回は背面)とマイクを使用し、出力として、動画ファイルを生成できるAVCaptureMovieFileOutputを設定します。

007

下記のコードは、セッションを生成して、上記のとおり入出力をセットしている例です。

// セッションのインスタンス生成
let captureSession = AVCaptureSession()

// 入力(背面カメラ)
let videoDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
let videoInput = try! AVCaptureDeviceInput.init(device: videoDevice)
captureSession.addInput(videoInput)

// 入力(マイク)
let audioDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)
let audioInput = try! AVCaptureDeviceInput.init(device: audioDevice)
captureSession.addInput(audioInput);

// 出力(動画ファイル)
let fileOutput = AVCaptureMovieFileOutput()
captureSession.addOutput(fileOutput)

3 AVCaptureMovieFileOutput

出力として指定した、AVCaptureMovieFileOutputは、QuickTimeムービーにデータをキャプチャするために使用するAVCaptureFileOutputのサブクラスです。

(1) 録画開始

AVCaptureFileOutputでは、startRecording(toOutputFileURL:recordingDelegate:)で録画を開始します。 そして、この時パラメータに、出力ファイルと、AVCaptureFileOutputRecordingDelegateを実装したクラスを指定します。

let fileURL : NSURL = ...
fileOutput?.startRecording(toOutputFileURL: fileURL as URL!, recordingDelegate: self)

(2) 録画終了

stopRecording()で録画を終了します。

 fileOutput?.stopRecording()

(3) AVCaptureFileOutputRecordingDelegate

AVCaptureFileOutputRecordingDelegateでは、capture(_:didFinishRecordingToOutputFileAt:fromConnections:error:)の実装が、必須となっており、録画終了時にこれがコールされます。

下記のコードは、録画終了時に動画ファイルを保存している例です。

public func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    // ライブラリへの保存
    PHPhotoLibrary.shared().performChanges({
        PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputFileURL)
    }) { completed, error in
        if completed {
            print("Video is saved!")
        }
    }
}

なお、ライブラリへの保存は、従来の「ALAssetsLibrary」が、iOS9以降非推奨となってるため、PHPhotoLibraryを使用しています。

3 info.plist

カメラやマイクを入力に使用する場合、iOS10以降では、info.plistに記述がないと、アプリが落ちてしまいます。 また、録画した動画ファイルをライブラリに保存する場合、その記述も必要になります。

今回、info.plistに記述した内容は、次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSCameraUsageDescription</key>
    <string>ビデオ撮影のためにカメラを使用します。</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>ビデオ撮影のためにマイクを使用します。</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>撮影したビデオを保存するために写真ライブラリにアクセスします。</string>

・・・省略・・・

008

実行時に、表示されるダイアログは、次のとおりです。

001 002 005

4 動作確認

サンプルを実行すると次のような画面となり、画面下部のボタンで、撮影が開始(終了)されます。

003 004

撮影を終了すると、動画ファイルは、逐次ライブラリに追加されます。

006

5 最後に

本記事では、AVFoundationを使用したビデオの録画を紹介しました。AVCaptureSessionの使い方をしっかり押さえておけば、そんなに難しいところは無いように感じました。

コードは下記に置いています。気になるところが有りましたら、ぜひ教えてやってください。
github [GitHub] https://github.com/furuya02/AVCaputureMovieFileOutputSample

6 参考資料


API Reference AVCaptureMovieFileOutput
[iOS 10] iOS 10以降のAVFoundationでの撮影方法
[iOS] AVFundationを使用して、「ビデオ録画」や「連写カメラ」や「QRコードリーダー」や「バーコードリーダー」を作ってみた