前言
当下音视频处理的技术的重要性不言而喻, FFmpeg
的强大不可撼动, 但是, 确实难啃. 由简递难, 我们来看看苹果原生的API如何做到对视频素材进行处理的.
AVFoundation
既可以对视频进行播放, 同时也可以对视频素材进行处理, 此类合成共分为两章:
1、简单视频合成
2、视频与音频的合成
正文
知识点
1.AVMutableComposition
合成工具
2.AVMutableCompositionTrack
合成工具中的轨道
3.AVAsset
视频素材的载体
4.AVAssetTrack
素材轨道
6.AVAssetExportSession
输出工具
过程简述
过程简单而言, 就是将素材中的素材轨道, 按照自定义顺序或者形式, 放到合成工具的对应的轨道, 最后, 设定好参数, 通过输出工具将合成工具中的内容一键合成并且输出.
##代码
下面是核心代码
// 这里将video的内容倒叙操作,为了后面将视频 逐个插入0的位置
videoPaths = [[videoPaths reverseObjectEnumerator] allObjects];
// 合成工具
AVMutableComposition *composition = [AVMutableComposition composition];
// 创建获取素材参数, 这个可以直接为nil, 下方的参数含义是获取素材参数的时间为非精准, 默认为精准
NSDictionary *optDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
// 合成工具的视频轨道
__block AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
// 合成工具的音频轨道
__block AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
// 遍历视频资源
[videoPaths enumerateObjectsUsingBlock:^(NSURL *videoPath, NSUInteger idx, BOOL * _Nonnull stop) {
// 素材
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoPath options:optDict];
// 获取素材中的轨道_视频
NSArray<AVAssetTrack *> *videoTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
if (videoTracks <= 0) {
*stop = YES;
completedBlock(NO, @"合成失败");
return;
}
// 获取当前视频的时间长度
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
// 素材的视频轨道
AVAssetTrack *videoCompositionTrack = videoTracks.firstObject;
// 设置合成工具的preferredTransform
[compositionVideoTrack setPreferredTransform:videoCompositionTrack.preferredTransform];
// 将素材的视频轨道添加到合成工具的视频轨道
[compositionVideoTrack insertTimeRange:timeRange
ofTrack:videoTracks.firstObject
atTime:kCMTimeZero
error:nil];
// 下面是处理原视频中的音频, 静音的话, 可以不处理
NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
if (audioTracks.count > 0) {
// 将素材的音频轨道添加到合成工具的音频轨道
[compositionAudioTrack insertTimeRange:timeRange
ofTrack:audioTracks.firstObject
atTime:kCMTimeZero
error:nil];
}
}];
// 存在旧数据, 删除旧数据
if ([[NSFileManager defaultManager] fileExistsAtPath:compoundVideoPath]) {
NSError *error;
[[NSFileManager defaultManager] removeItemAtPath:compoundVideoPath error:&error];
}
NSURL *outUrl = [NSURL fileURLWithPath:compoundVideoPath];
// 输出工具
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality];
// 输出类型
exporter.outputFileType = AVFileTypeMPEG4;
// 输出路径
exporter.outputURL = outUrl;
// 优化
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
BOOL isSuccess = NO;
NSString *msg = @"合并完成";
switch (exporter.status) {
case AVAssetExportSessionStatusFailed:
NSLog(@"MediaManager -> combinationVidesError: %@", exporter.error.localizedDescription);
NSLog(@"%@", exporter.error);
msg = @"合并失败";
break;
case AVAssetExportSessionStatusUnknown:
case AVAssetExportSessionStatusCancelled:
break;
case AVAssetExportSessionStatusWaiting:
break;
case AVAssetExportSessionStatusExporting:
break;
case AVAssetExportSessionStatusCompleted:
isSuccess = YES;
break;
}
if (completedBlock) {
completedBlock(isSuccess, msg);
}
}];
复制代码
添加背景音乐
添加背景音乐, 其实就是再添加一条音轨.
// 背景音乐 合成轨道
AVMutableCompositionTrack *compositionBGMAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
// 背景音乐
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:audioPath options:optDict];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, allTime);
NSArray *bgmTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
[compositionBGMAudioTrack insertTimeRange:timeRange
ofTrack:bgmTracks.firstObject
atTime:kCMTimeZero
error:nil];
复制代码
**作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发公众号:编程大鑫,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END