Hatena::Groupiphone-dev

Ni chicha, ni limona - 平均から抜けられない僕

2011-02-10

[AVFoundation][AVAssetWriterInput] AVCaptureVideoDataOutputを使って縦方向のムービーを撮る方法 01:15  [AVFoundation][AVAssetWriterInput] AVCaptureVideoDataOutputを使って縦方向のムービーを撮る方法 - Ni chicha, ni limona - 平均から抜けられない僕 を含むブックマーク はてなブックマーク -  [AVFoundation][AVAssetWriterInput] AVCaptureVideoDataOutputを使って縦方向のムービーを撮る方法 - Ni chicha, ni limona - 平均から抜けられない僕  [AVFoundation][AVAssetWriterInput] AVCaptureVideoDataOutputを使って縦方向のムービーを撮る方法 - Ni chicha, ni limona - 平均から抜けられない僕 のブックマークコメント

ムービーを撮影しているときにデータをフレーム毎に処理したい場合、AVCaptureVideoDataOutputクラスを使用します。しかしこのクラス、他と違ってsupportsVideoOrientationプロパティに全てNOを返すようです(4.2で確認)。

for (AVCaptureConnection *connection in videoWriterOutput_.connections) {
    if (connection.supportsVideoOrientation) {
        // ここに入ってこない!
        connection.videoOrientation = orientation;
    }
}

ですので、そのままAVAssetWriter&AVAssetWriterInputでムービーファイルを作成すると、縦に持っていようが逆さまに持っていようが横向き(ホームボタンが右)のムービーが出来上がってしまいます。そんな見にくいムービーは要りません。


これを解決するには、AVAssetWriterInputクラスのtransformプロパティを使います。縦方向のムービーにしたい場合のコードは以下のとおりです。

assetWriter_ = [[AVAssetWriter assetWriterWithURL:saveLocationURL
                     fileType:AVFileTypeQuickTimeMovie
                     error:&error] retain];

NSDictionary *outputSettings = NULL;
outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                     AVVideoCodecH264, AVVideoCodecKey,
                     [NSNumber numberWithInt:(int)frameSize.width], AVVideoWidthKey,
                     [NSNumber numberWithInt:(int)frameSize.height], AVVideoHeightKey,
                     nil ];
videoWriterInput_ = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
                     outputSettings:outputSettings] retain];
[videoWriterInput_ setExpectsMediaDataInRealTime:YES];

// 縦方向で録画するように変換行列を指定
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, frameSize.width/2, frameSize.height/2);
transform = CGAffineTransformRotate(transform, 90/180.0f*PI); // ここでorientationを指定
//transform = CGAffineTransformScale(transform, 1.0, -1.0); // ← 間違い。左右反転してしまいます
transform = CGAffineTransformScale(transform, 1.0, 1.0);
videoWriterInput_.transform = transform;
[assetWriter_ addInput:videoWriterInput_];

AVAssetWriter&AVAssetWriterInputの初期化処理も自分メモ気味に書いてありますが、メインはtransformプロパティのところです。


これで無事に縦方向で保存されます。

良かった良かった。

ゲスト



トラックバック - http://iphone-dev.g.hatena.ne.jp/paella/20110210