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));