【iOS】AVFoundationを使用してビデオ撮影アプリを開発する
AVFoundationを使用してビデオ撮影アプリを開発する方法について書きます。前回の記事で開発した写真撮影機能アプリに対して、ビデオ撮影機能を追加する形で説明します。iPhoneのカメラを立ち上げて画面にカメラの映像を表示するまでの処理は上記記事で説明していますので必要に応じてご参照ください。本記事のサンプルコードは以下に置いています。
アクセス権限の確認
前回の記事でアプリからカメラやマイクといったiPhoneのデバイス、フォトライブラリや連絡先といったユーザデータへアクセスする時は、Info.plistにアクセスを行う項目とその理由を記載し、コード側でアクセス権限確認アラートを表示する処理を記述すると説明しました。今回はビデオ撮影にiPhoneのマイクを使用しますので、Info.plistへの追記とアクセス権限確認アラートを表示する処理を追加します。
Info.plistへの記載
iPhoneのマイクを使用するために以下の項目を追加します。
アクセス権限項目 | Info.plistに記載する項目 |
---|---|
マイク | Privacy - Microphone Usage Description |
アクセス権限要求アラートの表示
今回はマイクへのアクセス権限要求アラートを表示する処理を記述します。
マイクへのアクセス権限
現在のマイクへのアクセス権限状態は以下のメソッドで確認することができます。
func authorizationStatus(for: AVMediaType) -> AVAuthorizationStatus
for
に確認するアクセス権限のタイプを指定します。.audio
を指定するとマイクへのアクセス権限状態を確認することができます。
マイクへのアクセス権限要求アラートは以下のメソッドで表示することができます。
func requestAccess(for mediaType: AVMediaType, completionHandler handler: @escaping (Bool) -> Void)
for
に要求するアクセス権限のタイプを指定します。.audio
を指定するとマイクへのアクセス権限要求アラートを表示することができます。handler
にはアクセス権限確認後に行う処理を記述します。アクセスを許可した時はtrue
、許可しなかった時はfalse
が引数として渡ってくるので、結果に応じて処理を分岐させることができます。
以下のコードではマイクへのアクセス権限状態をswitch
文の引数として、状態が.notDetermined
つまり権限状態が未決定の時にアクセス権限要求アラートが表示されます。
キャプチャセッションの再構築
キャプチャセッションを再構築する手順はキャプチャセッションの構築で実施したことに加えて以下の5ステップです。
- iPhoneのマイク(
AVCaptureDevice
)を取得 -
AVCaptureDevice
を使用してAVCaptureDeviceInput
(入力ソース)を生成 -
AVCaptureSession
(セッション)にAVCaptureDeviceInput
(入力ソース)をセット -
AVCaptureSession
(セッション)にAVCaptureMovieFileOutput
(出力タイプ)をセット -
AVCaptureSession
(セッション)からAVCapturephotoOutput
(出力タイプ)を削除
キャプチャセッションの構築で写真撮影を行うためにAVCaptureSession
に対して入力ソースはiPhoneの広角レンズバックカメラ、出力タイプは写真出力(AVCapturePhotoOutput
)をセットしていました。ビデオ撮影を行うために入力ソースはiPhoneの広角レンズバックカメラに加えてiPhoneのマイク、出力タイプはムービー(AVCaptureMovieFileOutput
)をセットします。また、写真出力(AVCapturePhotoOutput
)は不要になるので、removeOutput
でAVCaptureSession
から取り除きます。
ビデオ撮影の開始
AVCaptureMovieFileOutput
のstartRecording
を実行するとビデオ撮影が開始します。startRecording
の引数にビデオを一時的に保存するパスと、ビデオの保存が完了した時にコールされるデリゲートメソッドの移譲先を指定します。移譲先はself
つまり以下のコードを記述したViewController
を指定しています。
ビデオ撮影で使用するデリゲートメソッド
ビデオ撮影開始から終了までの間にいくつかのデリゲートメソッドがコールされますが、使用するデリゲートメソッドは以下の1つです。
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?)
前項でデリゲートの移譲先をself
に指定しました。上記デリゲートメソッドをViewController
内に記述する為に、移譲先のViewController
はAVCaptureFileOutputRecordingDelegate
プロトコルに準拠する必要があります。
ビデオ撮影のハンドリング処理
ビデオ撮影の終了
AVCaptureMovieFileOutput
のstopRecording
を実行するとビデオ撮影が終了します。
撮影したビデオの保存
ビデオの出力が完了したタイミングで、デリゲートメソッドfileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?)
がコールされます。引数のoutputFileURL
は撮影したビデオが保存されているパスです。PHPhotoLibrary.shared().performChanges
を使用してフォトライブラリにビデオを保存しています。
5. おまけ
キャプチャセッションをビデオ撮影向けに変更した後に、再び写真撮影を行いたい時は以下の様にキャプチャセッションを再構築することで写真撮影を行うことができます。
以上でビデオ撮影機能の実装は完了です。次回はLive Photos撮影機能について説明します。
Discussion
アプリ制作の参考になりました。ありがとうございます。
「前回の記事」と書かれているリンクが403エラーになるので、間違っているかと思います。
ご指摘ありがとうございます!リンクミス部分を修正致しました。