2013-03-26 7 views
10

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"); 
    } 
}]; 

} 

Antwort

9

Ok es heraus und veröffentlichen hier andere Leute verschwenden die Zeit nicht zu helfen, die ich getan habe.

Das Problem ist, dass wenn Sie AVAssetExportPresetPassthrough auf einem AVExportSession verwenden, wird der Exporteur die Anweisungen zur Videozusammenstellung ignorieren. Ich habe erwartet, dass es zumindest die Anweisungen zur Videozusammenstellung beim Durchlaufen des Formats usw. berücksichtigt, aber anscheinend funktioniert das nicht so. Nachdem ich einen Dokumentationsfehler gefunden habe, können Sie ihn in Technical Q&A finden.

+4

Was war die Lösung? – jpswain

+1

Wie hast du es gelöst? – MAMN84

+0

Um es zu lösen, verwenden Sie einfach eine andere Einstellung als AVAssetExportPresetPassthrough, die für Ihre App sinnvoll ist. – BooTooMany

Verwandte Themen