iOS|iOS 视频编辑之视频拼接
原理及步骤:
1、新建一个视频的框架
2、往框架里面添加一条音频轨道和视频轨道
3、把需要拼接的视频片段循环读取出视频和音频部分,并依次插入对应轨道
4、导出视频
代码:
- (void)finalMergeAndExportVideos:(NSArray*)videosPathArray withOutPath:(NSString*)outpath success:(void (^)(void))successBlock{if (videosPathArray.count == 0) {return;
}AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudiopreferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideopreferredTrackID:kCMPersistentTrackID_Invalid];
CMTime totalDuration = kCMTimeZero;
//用来计算视频大小(不需要可以删掉)
CGFloat length = 0;
for (int i = 0;
i < videosPathArray.count;
i++) {AVURLAsset *asset = [AVURLAsset assetWithURL:videosPathArray[i]];
NSError *erroraudio = nil;
AVAssetTrack *assetAudioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] firstObject];
[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)ofTrack:assetAudioTrackatTime:totalDurationerror:&erroraudio];
NSError *errorVideo = nil;
AVAssetTrack *assetVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo]firstObject];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)ofTrack:assetVideoTrackatTime:totalDurationerror:&errorVideo];
//合成的视频方向设置成第一个视频的方向 (不需要可以直接删掉)if (i==0 ) {[videoTrack setPreferredTransform:[MediaManager ssfixedCompositionWithAsset:asset]];
}totalDuration = CMTimeAdd(totalDuration, asset.duration);
length +=[NSData dataWithContentsOfFile:self.marr_movies[i]].length/1000000.0;
NSLog(@"lenght =============%f", length);
}NSString * name = AVAssetExportPresetPassthrough;
//视频如果大于5M就压缩(不需要可以删掉)
if (length > 5) {
name = AVAssetExportPresetMediumQuality;
}NSURL *mergeFileURL = [NSURL fileURLWithPath:outpath];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixCompositionpresetName:name];
exporter.outputURL = mergeFileURL;
exporter.outputFileType = AVFileTypeMPEG4;
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{if( exporter.status == AVAssetExportSessionStatusCompleted ){//UISaveVideoAtPathToSavedPhotosAlbum(outpath, nil, nil, nil);
successBlock();
}else if( exporter.status == AVAssetExportSessionStatusFailed )
{
}
}];
}
【iOS|iOS 视频编辑之视频拼接】PS:
1、videosPathArray为本地视频片段url的数组:[NSURL fileURLWithPath:path],注意别写成了URLWithString
2、里面有视频方向设置,以后有时间再单独写出来 (方法如下)
// 获取优化后的视频转向信息
+ (CGAffineTransform)ssfixedCompositionWithAsset:(AVAsset *)videoAsset {
// 视频转向
int degrees = [self degressFromVideoFileWithAsset:videoAsset];
CGAffineTransform translateToCenter;
CGAffineTransform mixedTransform;
NSArray *tracks = [videoAsset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
if (degrees == 90) {
// 顺时针旋转90°
translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.height, 0.0);
mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2);
} else if(degrees == 180){
// 顺时针旋转180°
translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.width, videoTrack.naturalSize.height);
mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI);
} elseif(degrees == 270){
// 顺时针旋转270°
translateToCenter = CGAffineTransformMakeTranslation(0.0, videoTrack.naturalSize.width);
mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2*3.0);
}else{
translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.height, 0.0);
mixedTransform = CGAffineTransformRotate(translateToCenter,0);
}return mixedTransform;
}// 获取视频角度
+ (int)degressFromVideoFileWithAsset:(AVAsset *)asset {
int degress = 0;
NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
if([tracks count] > 0) {
AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
CGAffineTransform t = videoTrack.preferredTransform;
if(t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0){
// Portrait
degress = 90;
} else if(t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0){
// PortraitUpsideDown
degress = 270;
} else if(t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0){
// LandscapeRight
degress = 0;
} else if(t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0){
// LandscapeLeft
degress = 180;
}
}
return degress;
}
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- iOS中的Block
- 4月23日海军节,我在青岛等你,一起看强大的中国海军。(如图如视频)
- 视频转换器哪种好用()
- 不懂法,害人终害己
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 腾讯视频(我有一段rap想给你说)
- 百度云极速下载,来体验飞的感觉,还可以看最新动漫的百度云视频哦
- 2019-08-29|2019-08-29 iOS13适配那点事
- 涵养字外功