BAD_ACCESS

おもにiOS、ときどき変な電子工作、ガジェット話。

AVAssetExportSessionで動画の圧縮

カメラロールに保存された動画をアップロードする際にある程度データを圧縮する必要があると思いAVAssetExportSessionを使った方法を試してみるメモ。

AVAssetExportSessionについて

公式のドキュメントによると、

エクスポートセッションは、アセットの非同期エクスポートを管理するコントローラオブジェクトです。


※ちなみに圧縮するときに音声の場合はACC、動画の場合はh264で圧縮されるようになっている。

出力するときに必要となるのは大きく3つ。「Export preset」と「outputURL」、「outputFileType」

Export preset

アセットはエクスポートセッションを通して出力するファイルタイプを指定することができる。
指定するときはExport presetを変える。
AVAssetExportPresetLowQuality
AVAssetExportPresetMediumQuality
AVAssetExportPresetHighestQuality
AVAssetExportPreset640x480
AVAssetExportPreset960x540
AVAssetExportPreset1280x720
AVAssetExportPreset1920x1080(iOS5.0のみ)
※今回は比較のため色々とこの値を変えて試してみた。
エクスポートセッションを初期化するときに指定する。

AVAssetExportSession *exportSession
exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetLowQuality];
outputURL

エクスポートセッションは一時的にファイルをどこかに書きだす必要がある。そのための保管場所をoutputURLを指定する。

NSString *filePath = NSTemporaryDirectory();
filePath = [filePath stringByAppendingPathComponent:@"temp.mov"];
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
exportSession.outputURL = [NSURL fileURLWithPath:filePath];
outputFileType

出力するファイルタイプを指定する。
ここで指定できるのは
AVFileTypeAIFC;
AVFileTypeAIFF;
AVFileTypeAMR;
AVFileTypeCoreAudioFormat;
AVFileTypeAppleM4V;
AVFileTypeMPEG4;
AVFileTypeAppleM4A;
AVFileTypeQuickTimeMovie;
AVFileTypeWAVE;
となっている。今回はAVFileTypeQuickTimeMovieを指定してエクスポートセッションを開始させる。

エクスポートセッションは非同期で実行される。(圧縮とか結構時間を食うのでメインのUI動作を阻害しないため)

exportSession.outputURL = [NSURL fileURLWithPath:filePath];
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        switch ([exportSession status]) {
            case AVAssetExportSessionStatusCompleted:
                  LOG(@"Export completed");
                  NSData *compressedData = [NSData dataWithContentsOfURL:exportSession.outputURL];
                  //exportSessionのoutputURLを利用して圧縮後のデータをぶっこ抜く!

                  break;        
           case AVAssetExportSessionStatusFailed:
                 LOG(@"Export failed: %@", [[exportSession error]localizedDescription]);
                 break;
           case AVAssetExportSessionStatusCancelled:
                 LOG(@"Export canceled");
                 break;
           default:
                 break;
           }
           [exportSession release];
    }]; 

ここで取得したNSDataをアップロードしてあげれば随分と軽くなるはず!
次はAVAssetReaderとAVAssetWriterを使った圧縮処理についても記事にしてみたい。