这个真的很浪费时间,网上能查到视频合成,也能查到多个视频合成视频,可都是针对合成后的视频旋转,我遇到的是需要合成的视频,只有某一段需要旋转,一直找不到原因,最终还是参考很多大神写的文章最总捣鼓出来了
//多个视频合成一个视频
+ (void)multipleVideosMakeAVideoWitharr:(NSArray*)array completion:(outputStrBlock)completion{
//包含多个轨道的媒体信息,可以添加、删除轨道
AVMutableComposition *composition = [[AVMutableComposition alloc] init];
//程文件中的轨道,有音频轨、视频轨等,里面可以插入各种对应的素材;
AVMutableCompositionTrack *videoCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *audioCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime totalDuration = CMTimeAdd(kCMTimeZero, kCMTimeZero);
NSMutableArray *mutArr = [NSMutableArray array];
for(inti =0; i
AVAsset*videoAsset = [AVAssetassetWithURL:[NSURLURLWithString:array[i]]];
AVAssetTrack*videoTrack = [[videoAssettracksWithMediaType:AVMediaTypeVideo]firstObject];
AVAssetTrack*audioTrack = [[videoAssettracksWithMediaType:AVMediaTypeAudio]firstObject];
[videoCompositionTrackinsertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)ofTrack:videoTrackatTime:totalDurationerror:nil];
[audioCompositionTrackinsertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)ofTrack:audioTrackatTime:totalDurationerror:nil];
//视频操作指令
AVMutableVideoCompositionInstruction *instrucation = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instrucation.timeRange=CMTimeRangeMake(totalDuration, videoAsset.duration);
//视频轨道操作指令,需要添加
AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack];
if(videoAsset.naturalSize.width> videoAsset.naturalSize.height) {
CGAffineTransform t1 =CGAffineTransformMakeTranslation( videoAsset.naturalSize.width/2+ videoAsset.naturalSize.height/2,-videoAsset.naturalSize.height/2);
CGAffineTransformt2 =CGAffineTransformRotate(t1,degreesToRadians(90));
[layerInstructionsetTransform:t2atTime:kCMTimeZero];
}else{
CGAffineTransformt1 =CGAffineTransformMakeTranslation( videoAsset.naturalSize.width,0);
CGAffineTransformt2 =CGAffineTransformRotate(t1,degreesToRadians(0));
[layerInstructionsetTransform:t2atTime:kCMTimeZero];
}
instrucation.layerInstructions=@[layerInstruction];
[mutArraddObject:instrucation];
totalDuration =CMTimeAdd(totalDuration,videoAsset.duration);
}
AVMutableVideoComposition *mainComposition = [AVMutableVideoComposition videoComposition];
mainComposition.instructions= mutArr;
mainComposition.frameDuration=CMTimeMake(1,30);
// mainComposition.renderSize = CGSizeMake(renderW, renderW); // 裁剪出对应大小
CGSizerenderSize=CGSizeMake(videoCompositionTrack.naturalSize.width, videoCompositionTrack.naturalSize.height);;
mainComposition.renderSize= renderSize;// 裁剪出对应大小
mainComposition.renderScale =1;
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formattersetDateFormat:@"yyyyMMddHHmmss"];
NSString*current = [formatterstringFromDate:[NSDatedate]];
NSURL*videoPath = [selffilePathWithFileName:[NSStringstringWithFormat:@"%@.mp4",current]];
AVAssetExportSession *export = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
export.outputURL= videoPath;
export.videoComposition= mainComposition;
export.outputFileType = AVFileTypeQuickTimeMovie;
export.shouldOptimizeForNetworkUse = YES;
[exportexportAsynchronouslyWithCompletionHandler:^{
if ([export status] == AVAssetExportSessionStatusCompleted) {
NSLog(@"%@",[NSThreadcurrentThread]);
NSLog(@"%@",export.outputURL);
NSLog(@"导出成功");
if(completion) {
completion(export.outputURL.absoluteString);
}
}else{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"导出失败");
if(completion) {
completion(@"");
}
});
}
}];
}