Nakajijapan

生きるのに必死です。

メディアキャプチャの出力先の実装について

AV Foundationを利用して写真の撮影やはたまた動画の撮影を行う場合は、カメラデバイスに接続して映像をリアルタイムに表示させたい場合があるかと思います。

AV Foundation

そんなときはAVCaptureSessionを利用してメディアキャプチャの実装の準備をを行い、入力先・出力先はどうするかという設定を行うのですが、今回はその出力部分について何パターンか方法があったので調べてみました。

Video Output

  • AVCaptureMovieFileOutput
    • ムービーファイルを出力するときに利用する
  • AVCaptureVideoDataOutput
    • キャプチャ中のビデオフレームを処理するときに利用する
  • AVCaptureStillImageOutput
    • 付随するメタデータを使用して静止画像をキャプチャするときに利用する

Audio Output

  • AVCaptureAudioDataOutput
    • キャプチャ中のオーディオフレームを処理するときに利用する

使い方

AVCaptureMovieFileOutput

ムービーファイルを保存するのに必要な処理を提供してくれるクラス。

録画するときは

1
2
//録画開始
[captureMovieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];

のように始めることができます。

必要に応じてAVCaptureFileOutputRecordingDelegateオプションを利用して、各タイミングに応じた処理を行います。

  • AVCaptureFileOutputRecordingDelegate
1
2
3
4
Delegate Methods

 captureOutput:didStartRecordingToOutputFileAtURL:fromConnections:
 captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:

前者は録画を開始したときに、後者は終了したときに呼び出されるメソッドです。例えば、captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:の時に録画したムービーファイルをデバイスに保存する等の処理が行えることができます。

AVCaptureStillImageOutput

画像をキャプチャするときに利用して、出力は以下のように実装します。

1
2
3
4
5
6
7
8
9
10
11
12
AVCaptureConnection *connection = [[captureStillImageOutput connections] lastObject];
[captureStillImageOutput captureStillImageAsynchronouslyFromConnection:connection
                                                     completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
                                                         NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                                                         UIImage *image = [UIImage imageWithData:data];
                                                         ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
                                                         [library writeImageToSavedPhotosAlbum:image.CGImage
                                                                                   orientation:image.imageOrientation
                                                                               completionBlock:^(NSURL *assetURL, NSError *error) {
                                                                                   NSLog(@"saved");
                                                                               }];
                                                     }];

AVCaptureVideoDataOutput, AVCaptureAudioDataOutput

デリゲートメソッドを利用して非圧縮状態のビデオフレーム情報を提供します。 そのフレーム情報はCMSampleBufferRefという形式で送信されてきてそれを利用して動画の保存やら編集やらを行うことができます。 このときにビデオとオーディオは別で処理しないといけません。(デリゲートメソッドが分かれているように) 主にビデオもオーディオも両方扱うときは– captureOutput:didOutputSampleBuffer:fromConnection:でどちらのメディアなのか区別して処理を行うような実装になります。 さらに細かい処理を行っていく場合はこちらのクラスを実装しないといけないですね。例えば、リアルタイムに動画を編集したりだとか、Vineみたいにタッチしているときは動画の保存し続けるような処理でしょうか。

  • AVCaptureVideoDataOutputSampleBufferDelegate
1
2
3
Managing Sample Buffer Behavior
 captureOutput:didOutputSampleBuffer:fromConnection:
 captureOutput:didDropSampleBuffer:fromConnection:
  • AVCaptureAudioDataOutputSampleBufferDelegat
1
2
Delegate Methods
 captureOutput:didOutputSampleBuffer:fromConnection:

まとめ

メディアキャプチャの出力先の実装について調べてみました。目的に応じてどれを使うかは選択していけばいいのですが、よりユーザにインタラクティブなインタフェースや体験をさせるにはそれ相応に細かい実装していかなければいけないこともわかりました。何度も言っているかもしれないけどメディア系の実装は大変です。。。

ref