导出时转换不在AVMutableVideoComposition中工作

我的目标是组合从相机记录的一组剪辑,并以特定的首选尺寸导出它们。 当然,video方向需要在导出之前旋转。

我是通过从存储在下面的avAssets中的video剪辑数组合成AVMutableComposition来做到这一点的。 我可以把它们组合好,并将其导出。 但是,我在AVMutableVideoComposition上设置的旋转变换不受尊重。 如果我使用相同的转换并将其设置在video轨道的preferredTransform属性上,那么它可以工作。 在这两种情况下,videorenderSize都没有被尊重。 这就好像导出器完全忽略了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"); } }]; } 

好的想出来并发布在这里帮助其他人不浪费我的时间。

问题是如果您在AVAssetExportPresetPassthrough上使用AVExportSession ,则导出器将忽略video组合指令。 我希望它在通过格式等时至少尊重video合成指令,但显然这不是它的工作原理。 填写完文档错误后,您可以在技术问答中找到它。