2013-03-26 9 views
10

私の目標は、カメラから録画したクリップのセットを作成し、一定の優先サイズでエクスポートすることです。もちろん、エクスポートする前にビデオの向きを回転させる必要があります。エクスポート中にAVMutableVideoCompositionでトランスフォームが機能しない

私は、以下のavAssetsに格納されたビデオクリップの配列からAVMutableCompositionを作成することでこれを行います。私はそれらを細かく構成し、エクスポートすることができます。しかし、私がAVMutableVideoCompositionに設定している回転変換は適用されません。同じトランスフォームを使用してビデオトラックのpreferredTransformプロパティに設定すると、そのトランスフォームが機能します。どちらの場合も、ビデオrenderSizeは受け入れられません。輸出業者がvideoCompositionを完全に無視しているかのようです。何が起きているのでしょうか?

私はAVCaptureSessionを実行していますが、エクスポートする前にオフにしていて、違いはありませんでした。私はiOSプログラミングにかなり新しいので、何か基本的なものが欠けている可能性があります。 :)

マイコード:

-(void) finalRecord{ 
NSError *error = nil; 

AVMutableComposition *composition = [AVMutableComposition composition]; 

AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
NSLog(@"Video track id is %d", [compositionVideoTrack trackID]); 

AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

// avAssets hold the video clips to be composited 
int pieces = [avAssets count]; 

CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_2); 
// [compositionVideoTrack setPreferredTransform:transform]; 

for (int i = 0; i<pieces; i++) { 

    AVURLAsset *sourceAsset = [avAssets objectAtIndex:i]; 

    AVAssetTrack *sourceVideoTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    AVAssetTrack *sourceAudioTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 

    [timeRanges addObject:[NSValue valueWithCMTimeRange:CMTimeRangeMake(kCMTimeZero, sourceAsset.duration)]]; 
    [videoTracks addObject:sourceVideoTrack]; 
    [audioTracks addObject:sourceAudioTrack]; 
} 

[compositionVideoTrack insertTimeRanges:timeRanges ofTracks:videoTracks atTime:kCMTimeZero error:&error]; 
[compositionAudioTrack insertTimeRanges:timeRanges ofTracks:audioTracks atTime:kCMTimeZero error:&error]; 

AVMutableVideoCompositionInstruction *vtemp = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
vtemp.timeRange = CMTimeRangeMake(kCMTimeZero, [composition duration]); 
NSLog(@"\nInstruction vtemp's time range is %f %f", CMTimeGetSeconds(vtemp.timeRange.start), 
     CMTimeGetSeconds(vtemp.timeRange.duration)); 

// Also tried videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack  
AVMutableVideoCompositionLayerInstruction *vLayerInstruction = [AVMutableVideoCompositionLayerInstruction 
                   videoCompositionLayerInstructionWithAssetTrack:composition.tracks[0]]; 
[vLayerInstruction setTransform:transform atTime:kCMTimeZero]; 
vtemp.layerInstructions = @[vLayerInstruction]; 

AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition]; 
videoComposition.renderSize = CGSizeMake(320.0, 240.0); 
videoComposition.frameDuration = CMTimeMake(1,30); 

videoComposition.instructions = @[vtemp]; 

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:composition presetName:gVideoExportQuality]; 

NSParameterAssert(exporter != nil); 
exporter.videoComposition = videoComposition; 
exporter.outputFileType = AVFileTypeQuickTimeMovie; 

NSString *rootName = [[self captureManager] tempFileRoot]; 

NSString *temp = [NSString stringWithFormat:@"%@%@.mov", NSTemporaryDirectory(), rootName]; 
exporter.outputURL = [NSURL fileURLWithPath:temp ]; 

[exporter exportAsynchronouslyWithCompletionHandler:^{ 
    switch ([exporter status]) { 
     case AVAssetExportSessionStatusFailed: 
      NSLog(@"Export failed: %@", [exporter error]); 
      break; 
     case AVAssetExportSessionStatusCancelled: 
      NSLog(@"Export canceled"); 
      break; 
     case AVAssetExportSessionStatusCompleted: 
      NSLog(@"Export successfully"); 
      [self exportFile:exporter.outputURL]; 
      [self.delegate recordingEndedWithFile:exporter.outputURL]; 
      isExporting = FALSE; 
      [[[self captureManager] session] startRunning]; 
      break; 
     default: 
      break; 
    } 
    if (exporter.status != AVAssetExportSessionStatusCompleted){ 
     NSLog(@"Retry export"); 
    } 
}]; 

} 

答えて

9

OK]をクリックして、それを考え出したと他の人が私がした時間を無駄にしない助けるためにここに掲示します。

AVExportSessionAVAssetExportPresetPassthroughを使用すると、エクスポータはビデオの合成指示を無視します。私はそれがフォーマットなどを通過している間に少なくともビデオ合成指示を尊重することを期待していたが、明らかにそれはどのように動作していない。ドキュメントのバグを埋めると、Technical Q&Aにあります。

+4

解決策は何ですか? – jpswain

+1

どうやって解決しましたか? – MAMN84

+0

これを解決するには、あなたのアプリケーションに合ったAVAssetExportPresetPassthrough以外の設定を使用してください。 – BooTooMany

関連する問題