2013-03-26 15 views
10

我的目標是組合一組從相機記錄並以特定首選大小導出的剪輯。當然,視頻方向需要在導出之前進行旋轉。在導出時轉換不在AVMutableVideoComposition中工作

我正在通過從AVAssets下面存儲的視頻剪輯數組中組成AVMutableComposition來完成此操作。我能夠將它們組合起來並導出。但是,我在AVMutableVideoComposition上設置的旋轉變形未被遵守。如果我使用相同的轉換並將其設置在視頻軌道的preferredTransform屬性上,則它可以工作。在這兩種情況下,視頻渲染大小都不受尊重。這就好像出口商完全忽略了視頻組合。任何想法可能發生什麼?

我確實有一個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

好理解了它,並張貼在這裏,以幫助其他人不能浪費,我沒有時間。

問題是如果您在AVExportSession上使用AVAssetExportPresetPassthrough,那麼導出器將忽略視頻組合指令。我期待它至少能夠在通過格式等的同時尊重視頻作品說明,但顯然這不是它的工作原理。在填寫完文檔錯誤後,您可以在Technical Q&A中找到它。

+4

那麼解決方案是什麼? – jpswain 2013-08-18 08:06:38

+1

你是如何解決它的? – MAMN84 2013-11-28 01:19:15

+0

要解決這個問題,只需使用AVAssetExportPresetPassthrough以外的其他設置,這對您的應用程序來說很合理。 – BooTooMany 2013-12-19 22:19:07

相關問題