iOS开发之音轨合成(音频与音频,音频与视频)

今天和你们一块儿分享关于音轨合成的坑(套路!全TM是套路!走一步套一路)

理论部分:

咱们须要用到AVURLAsset来初始化文件,而后用AVMutableCompositionAVMutableCompositionTrack来插入音轨,最后用AVAssetExportSession来输出文件git

先说音频和音频的合成

首先建立一个AVMutableComposition对象
AVMutableComposition *compostion = [AVMutableComposition composition];
而后经过下面的方法,获得一个AVMutableCompositionTrack对象
AVMutableCompositionTrack *video = [compostion addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];
这里的mediaType传入的是文件类型,由于咱们即将插入的文件类型是音频,这里要选择AVMediaTypeAudio,支持的类型见下图
github


可选类型

接下里就是插入了,有insert和inserts两种插入方式,咱们先选择第一种
session

[video insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[videoAsset tracksWithMediaType:AVMediaTypeAudio].firstObject atTime:kCMTimeZero error:nil];


一样的步骤,咱们再次插入另外一条音轨
AVMutableCompositionTrack *audio = [compostion addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0]; [audio insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:[audioAsset tracksWithMediaType:AVMediaTypeAudio].firstObject atTime:kCMTimeZero error:nil];


这样咱们就把两条音轨都混合到一块儿了,接下来就是把它输出成文件,这时候咱们须要建立一个Session
AVAssetExportSession *session = [[AVAssetExportSession alloc]initWithAsset:compostion presetName:AVAssetExportPresetAppleM4A];
其中 presetName这个参数很是坑人,必须文件的后缀和这里设定的格式相互呼应才行,不然文件没法建立,格式也是五花板门,有兴趣的小伙伴能够本身试试~

各类输出格式


有一些设置须要给出,否者输出时程序会crash掉
1.首先是输出路径,切记切记这里的后缀必定要和上面选择的呼应,好比我写的格式为AVAssetExportPresetAppleM4A那么个人文件后缀就须要为.m4a,若是用.MP3这种的话是没法正确生成出文件的,有可能会出现空文件的存在.必定要注意!!!
2.则是输出文件类型,这个更是个坑,一不留神就崩了,也是和上面的设置有关,须要给出一个输出类型,根据所选的不一样,支持的类型也不一样,能够经过[session supportedFileTypes]查询,而后根据须要填写对应的类型.(这里必定要先查询,不然很容易由于不支持而crash掉)
3.是否优化,属于可选,可是通常都选择YES
app

session.outputURL = [NSURL fileURLWithPath:outPutFilePath];
session.outputFileType = @"com.apple.m4a-audio";
session.shouldOptimizeForNetworkUse = YES;


设置完以上以后,咱们只须要执行

"[session exportAsynchronouslyWithCompletionHandler:^{
if ([[NSFileManager defaultManager] fileExistsAtPath:outPutFilePath])
{
// 调用播放方法
[self playAudio:[NSURL fileURLWithPath:outPutFilePath]];
}
else
{
NSLog(@"输出错误");
}
}];"


就能够输出了.我的推荐在里面作个判断,由于不管合成失败或者成功,都会调用block内的方法,可是若是失败则不会生成文件.能够经过这个来判是否合成成功.ide

插入多个

苹果还提供了一个inserts的函数,咱们来试试是否能够批量插入
CMTimeRange range = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
[video insertTimeRanges:@[[NSValue valueWithCMTimeRange:range],[NSValue valueWithCMTimeRange:range]] ofTracks:@[[videoAsset tracksWithMediaType:AVMediaTypeAudio].firstObject,[audioAsset tracksWithMediaType:AVMediaTypeAudio].firstObject] atTime:kCMTimeZero error:nil];
运行!结果是依然仍是一条音轨,原来这是个批量添加到尾部音轨的函数,即当A音轨播放完后,B音轨接着A后面无缝添加,而不是同时添加音轨.函数

音频和视频

大致上和上面同样,咱们只须要注意改几个参数就行了
post

AVMutableCompositionTrack *video = [compostion addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:0];
[video insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[videoAsset tracksWithMediaType:AVMediaTypeVideo].firstObject atTime:kCMTimeZero error:nil];
由于是视频,因此原来的Audio要所有改为Video
AVAssetExportSession *session = [[AVAssetExportSession alloc]initWithAsset:compostion presetName:AVAssetExportPresetMediumQuality];


这里的presetNameoutputFileType都要换成一个视频格式,注意不一样的presetName会产生不一样的outputFileType必定要填写相对应的支持类型,不然会直接crash!
优化


必须是其中的类型

文章参考资料

http://blog.csdn.net/linzhiji/article/details/6736704
http://www.jianshu.com/p/9f83af9dbbef.net

写在最后

若是有什么遗漏或者错误欢迎指正,共同进步!
附上Demo地址:https://github.com/WeiTChen/multitrackerDemocode

原创做品,转载请注明出处



文/魏天晨(简书做者) 原文连接:http://www.jianshu.com/p/76e0c4e684db 著做权归做者全部,转载请联系做者得到受权,并标注“简书做者”。