双轨道合成备注下 但是最好一个轨道
片头拼接
@param exportVideoFilePath <#exportVideoFilePath description#>
@param inputeVideoURL <#inputeVideoURL description#>
@param videoHiveURL <#videoHiveURL description#>
*/
-(void)builderVideoHiveToMp4Pth: (NSString *)exportVideoFilePath
withInputeVideoURL: (NSURL *)inputeVideoURL
withVideoHiveURL: (NSURL*)videoHiveURL{
_effectType = 1;
unlink([exportVideoFilePath UTF8String]);
if (!inputeVideoURL || ![inputeVideoURL isFileURL] || !exportVideoFilePath || [exportVideoFilePath isEqualToString:@""]){
NSLog(@"inputeVideoURL 或者 exportVideoFilePath 地址有错");
return;
}
AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:inputeVideoURL options:nil];
AVURLAsset *videoAsset2 = [[AVURLAsset alloc] initWithURL:videoHiveURL options:nil];
if (videoAsset == nil || [[videoAsset tracksWithMediaType:AVMediaTypeVideo] count]<1 || [[videoAsset2 tracksWithMediaType:AVMediaTypeVideo] count]<1){
return;
}
NSParameterAssert(videoAsset);
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *videoTrack2 = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *assetVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetTrack *assetVideoTrack2 = [[videoAsset2 tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[videoTrack2 insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset2.duration ) ofTrack:assetVideoTrack2 atTime:kCMTimeZero error:nil];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration ) ofTrack:assetVideoTrack atTime:videoAsset2.duration error:nil];
AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:assetVideoTrack];
AVMutableVideoCompositionLayerInstruction *videolayerInstruction2 = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:assetVideoTrack2];
[videolayerInstruction2 setOpacity:0.0 atTime:videoAsset2.duration];
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeAdd(videoAsset.duration, videoAsset2.duration));
mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,videolayerInstruction2, nil];
AVMutableVideoComposition *mainVideoComposition = [[AVMutableVideoComposition alloc] init];
mainVideoComposition.instructions = [NSArray arrayWithObjects:mainInstruction, nil];
mainVideoComposition.frameDuration = CMTimeMake(1, 30);
mainVideoComposition.renderSize = assetVideoTrack.naturalSize;
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.contentsScale = [UIScreen mainScreen].scale;
videoLayer.contentsScale = [UIScreen mainScreen].scale;
parentLayer.frame = CGRectMake(0, 0, assetVideoTrack.naturalSize.width, assetVideoTrack.naturalSize.height);
videoLayer.frame = parentLayer.frame;
[parentLayer addSublayer:videoLayer];
mainVideoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
if (_animationlayer){
[_animationlayer setAllFrame:parentLayer.bounds];
[parentLayer addSublayer:_animationlayer];
}
NSString *mp4Quality = AVAssetExportPresetHighestQuality;
NSString *exportPath = exportVideoFilePath;
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
_videotoTalTime = CMTimeGetSeconds(videoAsset.duration);
_exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:mp4Quality];
_exportSession.outputURL = exportUrl;
_exportSession.outputFileType = AVFileTypeQuickTimeMovie;
_exportSession.shouldOptimizeForNetworkUse = YES;
_exportSession.videoComposition = mainVideoComposition;
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
_timerEffect = [NSTimer CZ_scheduledTimerWithTimeInterval:0.1f repeats:YES callback:^{
[weakSelf retrievingProgressMP4];
}];
});
[_exportSession exportAsynchronouslyWithCompletionHandler:^{
if (!weakSelf){return;}
NSLog(@"转码状态 %ld",(long)[weakSelf.exportSession status]);
switch ([weakSelf.exportSession status]) {
case AVAssetExportSessionStatusCompleted:
{
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(AVAssetExportVideoHiveMP4SessionStatus:)]){
[weakSelf.delegate AVAssetExportVideoHiveMP4SessionStatus:[weakSelf.exportSession status]];
}
[weakSelf clearAll];
});
NSLog(@"视频转码成功");
break;
}
case AVAssetExportSessionStatusFailed:
{
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(AVAssetExportVideoHiveMP4SessionStatus:)]){
[weakSelf.delegate AVAssetExportVideoHiveMP4SessionStatus:[weakSelf.exportSession status]];
}
[weakSelf clearAll];
});
NSLog(@"视频转码失败%@",[weakSelf.exportSession error]);
break;
}
case AVAssetExportSessionStatusCancelled:
break;
case AVAssetExportSessionStatusWaiting:
break;
case AVAssetExportSessionStatusExporting:
break;
case AVAssetExportSessionStatusUnknown:
default:
break;
}
}];
}