【iOS】AVFoundationを使用して動画撮影機能を実装する
AVFoundationのCapture APIを使用して、動画撮影機能を実装する方法について書きます。以下の記事を先にお読みいただくと、本記事の内容をスムーズに理解することができます。
本記事をお読みいただくことで、以下の内容を学ぶことができます。
- 動画データを出力するキャプチャセッションの設定方法
- 動画データ撮影を開始・終了・停止・再開する方法
- デリゲートメソッドを介した動画データの取得方法
- 動画データを写真アルバムに追加する方法
本記事の内容は、「詳解 AVFoundation Capture」から一部の説明を抜粋した内容になっています。
アプリがカメラやマイク、写真アルバムへアクセスするために必要なアクセス権を取得する方法については、本記事では割愛しています。「詳解 AVFoundation Capture」の「第2章 アクセス権」または、以下のドキュメントをご参照ください。キャプチャセッションの設定
入力設定
音声付きの動画データを取得するためには、カメラからの入力を表すAVCaptureDeviceInput
オブジェクトに加え、マイクからの入力を表すAVCaptureDeviceInput
オブジェクトをAVCaptureSession
オブジェクトに追加します。以下のソースコードでは、マイクからの入力を表すAVCaptureDeviceInput
オブジェクトを、AVCaptureSession
オブジェクトに追加しています。
出力設定
AVCaptureMovieFileOutput
は、動画データを出力するためのワークフローを提供するクラスです。
AVCaptureOutput
を継承しており、AVCaptureSession
オブジェクトに追加することで、AVCaptureFileOutputRecordingDelegate
プロトコルで定義されているデリゲートメソッドを介して、撮影した動画データを取得することができます。
AVCaptureSession
オブジェクトは、撮影フォーマットを変更することができるAVCaptureSession.Preset
型のsessionPreset
プロパティを持っています。
撮影フォーマットを表すAVCaptureSession.Preset
オブジェクトは、スタティックプロパティとしていくつかのプリセットが用意されています。今回は、動画データ撮影向けに、高品質な動画データを出力することができるAVCaptureSession.Preset.high
オブジェクトを、sessionPreset
プロパティに代入します。以下のソースコードでは、iPhone 背面の広角レンズカメラと、マイクが記録した動画データを出力するキャプチャセッションの設定を行っています。
動画データ撮影の開始・終了
AVCaptureMovieFileOutput
オブジェクトのstartRecording(to:recordingDelegate:)
メソッドで、動画データ撮影を開始することができます。
to
引数には、出力する動画データの書き出し先のドキュメントフォルダパスを表すURL
オブジェクトを指定します。recordingDelegate
引数には、AVCaptureFileOutputRecordingDelegate
プロトコルに準拠するオブジェクトを指定します。AVCaptureFileOutputRecordingDelegate
プロトコルで定義されているデリゲートメソッドについては後述しますが、上記のソースコードでは、self
を指定しています。AVCaptureFileOutputRecordingDelegate
プロトコルに準拠したオブジェクトに、動画データ撮影の開始から完了するまでに呼び出されるデリゲートメソッドを定義します。
startRecording(to:recordingDelegate:)
メソッドを実行する前に、AVCaptureMovieFileOutput
オブジェクトのisRecording
プロパティを確認します。
isRecording
は、動画データ撮影中かどうかを表すBool
値が代入されているプロパティです。isRecording
プロパティがfalse
であることを確認した後に、startRecording(to:recordingDelegate:)
メソッドを実行します。
また、AVCaptureMovieFileOutput
オブジェクトのstopRecording()
メソッドで、動画データ撮影を終了することができます。
isRecording
プロパティがtrue
であることを確認した後に、stopRecording()
メソッドを実行します。
プロトコルへの準拠
startRecording(to:recordingDelegate:)
メソッドのrecordingDelegate
引数に、動画データ撮影の開始から完了するまでに呼び出されるデリゲートメソッドの委譲先を指定しました。今回は、移譲先にself
を指定したので、startRecording(to:recordingDelegate:)
メソッドを実行するクラス自身にデリゲートメソッドを定義します。デリゲートメソッドを定義するために、self
をAVCaptureFileOutputRecordingDelegate
プロトコルに準拠させます。
動画データの取得
fileOutput(_:didFinishRecordingTo:from:error:)
は、AVCaptureFileOutputRecordingDelegate
プロトコルで定義されているデリゲートメソッドです。
動画データが出力される時に呼び出されます。outputFileURL
引数には、動画データが書き込まれているドキュメントフォルダパスを表すURL
オブジェクトが代入されています。
動画データを写真アルバムへ追加
動画データを写真アルバムへ追加する処理は、fileOutput(_:didFinishRecordingTo:from:error:)
メソッド内で行います。静止画データや動画データ (以降、アセットデータ)を写真アルバムに追加する処理は、PhotoKitフレームワークのAPIを使用します。PhotoKitは、写真アルバムを操作するためのAPIが定義されているフレームワークです。写真アルバムに変更を加える時は、PHPhotoLibrary
のperformChanges(_:)
メソッドを実行します。
performChanges(_:)
は、第一引数に指定した写真アルバムに変更を加える処理を、PhotoKitにリクエストするメソッドです。
第一引数には、写真アルバムを操作する処理をクロージャで記述します。写真アルバムに対する変更は、PHAssetCreationRequest
オブジェクトのメソッドで行います。PHAssetCreationRequest
は、写真アルバムに対する変更をPhotoKitにリクエストすることができるメソッドを持つクラスです。
PHAssetCreationRequest
オブジェクトは、forAsset()
メソッドで取得することができます。
特定のドキュメントフォルダパスに書き込まれているアセットデータを写真アルバムに追加する時は、PHAssetCreationRequest
オブジェクトのaddResource(with:fileURL:options:)
メソッドを実行します。
addResource(with:fileURL:options:)
は、特定のドキュメントフォルダパスに書き込まれているアセットデータを、写真アルバムに追加することをPhotoKit にリクエストするメソッドです。
with
引数には、写真アルバムに追加するアセットのタイプを、PHAssetResourceType
オブジェクトで指定します。今回は、動画データを写真アルバムに追加するので、上記のソースコードでは、with
引数に.video
を指定しています。fileURL
引数には、動画データが書き込まれているドキュメントフォルダパスを表すURL
オブジェクトを指定します。上記のソースコードでは、fileOutput(_:didFinishRecordingTo:from:error:)
メソッドのoutputFileURL
引数を指定しています。options
引数には、PHAssetResourceCreationOptions
オブジェクトを指定します。PHAssetResourceCreationOptions
は、アセットデータを写真アルバムに追加する時の追加処理オプションを設定することができるクラスです。
ドキュメントフォルダパスに配置されている動画データを写真アルバムに追加した後に、元の動画データが不要な時は、PHAssetResourceCreationOptions
オブジェクトのshouldMoveFile
プロパティにtrue
を代入します。shouldMoveFile
プロパティにtrue
を代入したPHAssetResourceCreationOptions
オブジェクトをoptions
引数に指定することで、元の動画データが写真アルバムに移動してから、動画データを写真アルバムに追加する処理が行われます。つまり、元の動画データが配置されていたドキュメントフォルダパスには動画データが存在しなくなり、端末のストレージを節約することができます。
以下のソースコードでは、撮影した動画データを写真アルバムに追加しています。
次回は、Live Photos撮影機能を実装する方法について解説します。
参考資料
・詳解 AVFoundation Capture
・Setting Up a Capture Session, Apple Developer Documentation
Discussion
アプリ制作の参考になりました。ありがとうございます。
「前回の記事」と書かれているリンクが403エラーになるので、間違っているかと思います。
ご指摘ありがとうございます!リンクミス部分を修正致しました。