Mein Ziel ist es, eine Reihe von Clips, die von der Kamera aufgenommen wurden, zu erstellen und sie in einer bestimmten bevorzugten Größe zu exportieren. Natürlich muss die Videoausrichtung vor dem Export gedreht werden.Umwandlung funktioniert nicht in AVMutableVideoComposition während des Exports
Ich mache das, indem ich eine AVMutableComposition aus einem Array von Videoclips zusammensetze, die unten in AvAssets gespeichert sind. Ich kann sie gut komponieren und exportieren. Die Rotationsumwandlung, die ich auf AVMutableVideoComposition einstelle, wird jedoch nicht berücksichtigt. Wenn ich dieselbe Transformation verwende und sie auf die Eigenschaft preferredTransform der Videospur einstelle, funktioniert sie. In beiden Fällen wird das Video renderSize nicht berücksichtigt. Es ist, als ob der Exporteur die videoComposition vollständig ignoriert. Irgendwelche Ideen, was passieren könnte?
Ich habe eine AVCaptureSession ausgeführt, aber ich habe es vor dem Export ausgeschaltet und das machte keinen Unterschied. Ich bin ziemlich neu in der iOS-Programmierung, also könnte es sein, dass mir etwas Grundlegendes fehlt. :)
Mein Code:
-(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");
}
}];
}
Was war die Lösung? – jpswain
Wie hast du es gelöst? – MAMN84
Um es zu lösen, verwenden Sie einfach eine andere Einstellung als AVAssetExportPresetPassthrough, die für Ihre App sinnvoll ist. – BooTooMany