Edited at

AV Foundationで240fpsスローモーション動画撮影を実装する

More than 3 years have passed since last update.

iPhone5s以降で登場した機能として、秒間120コマ(2013年当時。最近は240コマ)までの高速撮影 があり、標準カメラアプリではこれを利用した スローモーション動画撮影機能 が可能となっています。

これに類する機能をAVFoundationで実装できないかやってみたところ、うまくいったので、その方法を紹介します。


できたもの

サンプルアプリをGitHubにアップしております。

スクショ下部にあるように、 デフォルト / 60fps / 240fps を切り替えられるようになっています。

このアプリを使って撮ったものがこちら(寒かったので外に出てすぐ目の前にあったこれを撮影しました)。

120fps Slow-Motion video recorded using AVFoundation.

(中盤をスローモーションにしています。)


実装方法

わりと複雑な処理になったので、 AVFoundation関連の処理を全部ラップしたクラス をつくりました。

そのラッパークラス TTMCaptureManager を使うと、下記のように 3行 で実装できます。


1. 初期化

self.captureManager = [[TTMCaptureManager alloc] initWithPreviewView:self.view];


2. 録画開始

[self.captureManager startRecording];


3. 録画停止

[self.captureManager stopRecording];

停止したときに撮影した動画を保存する、とかはデリゲートメソッドを使用します。そのあたりはサンプルをご参照ください。

また今はこのサンプルの用途しか考慮されてないAPIになっているのですが、これから動画処理とかは積極的にやっていくので、随時拡張していく所存です。


ラッパーを使わない実装

大部分はAVCapture~で動画撮影する場合の一般的な処理で、240fps実装ならではのポイントは AVCaptureManager の次の部分に集約されています。

AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

AVCaptureDeviceFormat *selectedFormat = nil;
int32_t maxWidth = 0;
AVFrameRateRange *frameRateRange = nil;

for (AVCaptureDeviceFormat *format in [videoDevice formats]) {

for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) {

CMFormatDescriptionRef desc = format.formatDescription;
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(desc);
int32_t width = dimensions.width;

if (range.minFrameRate <= desiredFPS && desiredFPS <= range.maxFrameRate && width >= maxWidth) {

selectedFormat = format;
frameRateRange = range;
maxWidth = width;
}
}
}

if (selectedFormat) {

if ([videoDevice lockForConfiguration:nil]) {

NSLog(@"selected format:%@", selectedFormat);
videoDevice.activeFormat = selectedFormat;
videoDevice.activeVideoMinFrameDuration = CMTimeMake(1, (int32_t)desiredFPS);
videoDevice.activeVideoMaxFrameDuration = CMTimeMake(1, (int32_t)desiredFPS);
[videoDevice unlockForConfiguration];
}
}

処理の内容としては、


  • AVCaptureDevice の formats プロパティから使用可能なフォーマットのリストを取得

  • その中から所望のfpsを満たすものを探索


    • 同じfpsなら幅がより大きい方をとる



  • 見つかれば AVCaptureDevice の activeFormat プロパティにセットする

ということを行っています。


Special Thanks!!

@hkato193 さんにTwitterで諸々教えていただきました。ありがとうございました!


上を目指すプログラマーのためのiPhoneアプリ開発テクニック iOS 7編



加藤 寛人 西方 夏子 藤川 宏之 鈴木 晃 高丘 知央
インプレスジャパン
売り上げランキング: 2,641






関連

AVFoundationを使うレシピは、下記書籍にもいくつか書いたのでもしよろしければ。

『iOSアプリ開発 達人のレシピ100』という本を書きました