您的位置:首页 > 移动开发 > IOS开发

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

2016-07-22 16:44 197 查看

今天和大家一起分享关于音轨合成的坑(套路!全TM是套路!走一步套一路)

理论部分:

我们需要用到
AVURLAsset
来初始化文件,然后用
AVMutableComposition
AVMutableCompositionTrack
来插入音轨,最后用
AVAssetExportSession
来输出文件

先说音频和音频的合成

首先创建一个AVMutableComposition对象
AVMutableComposition *compostion = [AVMutableComposition composition];


然后通过下面的方法,得到一个AVMutableCompositionTrack对象
AVMutableCompositionTrack *video = [compostion addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];


这里的mediaType传入的是文件类型,因为我们即将插入的文件类型是音频,这里要选择AVMediaTypeAudio,支持的类型见下图



可选类型

接下里就是插入了,有insert和inserts两种插入方式,我们先选择第一种
[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
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内的方法,但是如果失败则不会生成文件.可以通过这个来判是否合成成功.

插入多个

苹果还提供了一个
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后面无缝添加,而不是同时添加音轨.

音频和视频

大体上和上面一样,我们只需要注意改几个参数就好了
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];

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



必须是其中的类型

文章参考资料

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

写在最后

如果有什么遗漏或者错误欢迎指正,共同进步!

附上Demo地址:https://github.com/WeiTChen/multitrackerDemo

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

文/魏天晨(简书作者)

原文链接:http://www.jianshu.com/p/76e0c4e684db

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息