📹

【iOS】AVFoundationを使用してビデオ撮影アプリを開発する

2021/07/17に公開
2


AVFoundationを使用してビデオ撮影アプリを開発する方法について書きます。前回の記事で開発した写真撮影機能アプリに対して、ビデオ撮影機能を追加する形で説明します。iPhoneのカメラを立ち上げて画面にカメラの映像を表示するまでの処理は上記記事で説明していますので必要に応じてご参照ください。本記事のサンプルコードは以下に置いています。
https://github.com/NAOYA-MAEDA-DEV/AVFoundation-Camera-App

アクセス権限の確認

前回の記事でアプリからカメラやマイクといった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ステップです。

  1. iPhoneのマイク(AVCaptureDevice )を取得
  2. AVCaptureDevice を使用してAVCaptureDeviceInput (入力ソース)を生成
  3. AVCaptureSession (セッション)にAVCaptureDeviceInput (入力ソース)をセット
  4. AVCaptureSession (セッション)にAVCaptureMovieFileOutput (出力タイプ)をセット
  5. AVCaptureSession (セッション)からAVCapturephotoOutput (出力タイプ)を削除

キャプチャセッションの構築で写真撮影を行うためにAVCaptureSession に対して入力ソースはiPhoneの広角レンズバックカメラ、出力タイプは写真出力(AVCapturePhotoOutput )をセットしていました。ビデオ撮影を行うために入力ソースはiPhoneの広角レンズバックカメラに加えてiPhoneのマイク、出力タイプはムービー(AVCaptureMovieFileOutput )をセットします。また、写真出力(AVCapturePhotoOutput )は不要になるので、removeOutputAVCaptureSession から取り除きます。

ビデオ撮影の開始

AVCaptureMovieFileOutputstartRecording を実行するとビデオ撮影が開始します。startRecording の引数にビデオを一時的に保存するパスと、ビデオの保存が完了した時にコールされるデリゲートメソッドの移譲先を指定します。移譲先はselfつまり以下のコードを記述したViewControllerを指定しています。

ビデオ撮影で使用するデリゲートメソッド

ビデオ撮影開始から終了までの間にいくつかのデリゲートメソッドがコールされますが、使用するデリゲートメソッドは以下の1つです。

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

前項でデリゲートの移譲先をselfに指定しました。上記デリゲートメソッドをViewController内に記述する為に、移譲先のViewControllerAVCaptureFileOutputRecordingDelegateプロトコルに準拠する必要があります。

ビデオ撮影のハンドリング処理

ビデオ撮影の終了

AVCaptureMovieFileOutputstopRecording を実行するとビデオ撮影が終了します。

撮影したビデオの保存

ビデオの出力が完了したタイミングで、デリゲートメソッドfileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) がコールされます。引数のoutputFileURL は撮影したビデオが保存されているパスです。PHPhotoLibrary.shared().performChanges を使用してフォトライブラリにビデオを保存しています。

5. おまけ

キャプチャセッションをビデオ撮影向けに変更した後に、再び写真撮影を行いたい時は以下の様にキャプチャセッションを再構築することで写真撮影を行うことができます。

以上でビデオ撮影機能の実装は完了です。次回はLive Photos撮影機能について説明します。

Discussion

tomotomo

アプリ制作の参考になりました。ありがとうございます。
「前回の記事」と書かれているリンクが403エラーになるので、間違っているかと思います。

Naoya MaedaNaoya Maeda

ご指摘ありがとうございます!リンクミス部分を修正致しました。