Преобразование не работает в AVMutableVideoComposition при экспорте
Моя цель - составить набор клипов, записанных с камеры, и экспортировать их с определенным предпочтительным размером. Конечно, ориентация видео должна быть повернута перед экспортом.
Я делаю это, составляя AVMutableComposition из массива видеоклипов, хранящихся в avAssets ниже. Я умею хорошо их составлять и экспортировать. Однако преобразование поворота, которое я устанавливаю в AVMutableVideoComposition, не учитывается. Если я использую то же самое преобразование и устанавливаю его в свойстве Предпочитаемое видео дорожки, то оно работает. В обоих случаях видео 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");
}
}];
}