LoginSignup
41
41

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-02-04

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』という本を書きました

41
41
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
41