2

我試圖將2個音頻文件和1個視頻文件合併爲1個.mov文件。我知道它與下一個代碼:AVAssetExportSession與指令使黑色屏幕

-(void)combineData{ 
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init]; 

AVAsset *audioAsset = [AVAsset assetWithURL:_songURL]; 
AVAsset* audioAsset2 = [AVAsset assetWithURL:[NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[@"speechRecord" stringByAppendingPathExtension:@"caf"]]]]; 
AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[@"movie" stringByAppendingPathExtension:@"mov"]]] options:nil]; 

AVMutableCompositionTrack *firstTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
[firstTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil]; 

AVMutableCompositionTrack *secondTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
[secondTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[audioAsset2 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil]; 

AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil]; 

AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 
/*CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90)); 
CGAffineTransform rotateTranslate = CGAffineTransformTranslate(rotationTransform,320,0);*/ 
[layerInstruction setTransform:videoTrack.preferredTransform atTime:kCMTimeZero]; 

AVMutableVideoCompositionInstruction * mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration); 
[mainInstruction setLayerInstructions:[NSArray arrayWithObject:layerInstruction]]; 

mixComposition.naturalSize = videoTrack.naturalSize; 

AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition]; 
mainCompositionInst.renderScale = 1.0; 
mainCompositionInst.renderSize = videoTrack.naturalSize; 
mainCompositionInst.frameDuration = CMTimeMake(1, 30); 
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction]; 
//mainCompositionInst. 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:@"mergeVideo.mov"]; 

if ([[NSFileManager defaultManager] fileExistsAtPath:myPathDocs]) { 
    [[NSFileManager defaultManager] removeItemAtPath:myPathDocs error:nil]; 
    NSLog(@"Removing old mergeVideo"); 
} 

NSURL *url = [NSURL fileURLWithPath:myPathDocs]; 

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality]; 
exporter.outputURL=url; 
exporter.outputFileType = AVFileTypeQuickTimeMovie; 
exporter.videoComposition = mainCompositionInst; 
exporter.shouldOptimizeForNetworkUse = YES; 

[exporter exportAsynchronouslyWithCompletionHandler:^ 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self exportDidFinish:exporter]; 
    }); 
}]; 

我的第一個任務是處理我的新視頻90旋轉。當我將mainCompositionInst添加到我的代碼中時,我的新視頻擁有所有聲音,但它有黑屏,仍然未旋轉。如果我不使用任何指示,它工作正常。也許我的代碼有錯誤,或者不是。你會建議我什麼?

回答

1

我會嘗試在preferredTransform上應用旋轉,因爲preferredTransform可能會翻​​譯您的視頻,以便它在屏幕上正確顯示。

我會嘗試以下方法:

CGAffineTransform transform = videoTrack.preferredTransform; 
transform = CGAffineTransformRotate(transform, DEGREES_TO_RADIANS(90)); 
//transform = CGAffineTransformTranslate(transform, 320, 0); 
[layerInstruction setTransform:transform atTime:kCMTimeZero]; 
0

正常工作的樣品可以在這裏找到: https://github.com/robovm/apple-ios-samples/blob/master/AVSimpleEditoriOS/AVSimpleEditor/AVSERotateCommand.m#L98

的事情是,你需要翻譯組成,以補償因旋轉運動(自旋轉會導致它移出框架),正如Apple示例源代碼中的註釋所述。

應用正確的翻譯是:

t1 = CGAffineTransformMakeTranslation(assetVideoTrack.naturalSize.height, 0.0); 
// Rotate transformation 
t2 = CGAffineTransformRotate(t1, degreesToRadians(90.0));