今天和大家一起分享關(guān)于音軌合成的坑(套路!全TM是套路!走一步套一路)
理論部分:
我們需要用到AVURLAsset
來初始化文件,然后用AVMutableComposition
和AVMutableCompositionTrack
來插入音軌,最后用AVAssetExportSession
來輸出文件
先說音頻和音頻的合成
首先創(chuàng)建一個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];
這樣我們就把兩條音軌都混合到一起了,接下來就是把它輸出成文件,這時候我們需要創(chuàng)建一個Session
AVAssetExportSession *session = [[AVAssetExportSession alloc]initWithAsset:compostion presetName:AVAssetExportPresetAppleM4A];
其中presetName
這個參數(shù)非??尤?必須文件的后綴和這里設(shè)定的格式相互呼應(yīng)才行,否則文件無法創(chuàng)建,格式也是五花板門,有興趣的小伙伴可以自己試試~
有一些設(shè)置需要給出,否者輸出時程序會crash掉
1.首先是輸出路徑,切記切記這里的后綴一定要和上面選擇的呼應(yīng),比如我寫的格式為
AVAssetExportPresetAppleM4A
那么我的文件后綴就需要為.m4a,如果用.MP3這種的話是無法正確生成出文件的,有可能會出現(xiàn)空文件的存在.一定要注意!!!2.則是輸出文件類型,這個更是個坑,一不留神就崩了,也是和上面的設(shè)置有關(guān),需要給出一個輸出類型,根據(jù)所選的不同,支持的類型也不同,可以通過
[session supportedFileTypes]
查詢,然后根據(jù)需要填寫對應(yīng)的類型.(這里一定要先查詢,否則很容易因為不支持而crash掉)3.是否優(yōu)化,屬于可選,但是一般都選擇YES
session.outputURL = [NSURL fileURLWithPath:outPutFilePath];
session.outputFileType = @"com.apple.m4a-audio";
session.shouldOptimizeForNetworkUse = YES;
設(shè)置完以上之后,我們只需要執(zhí)行
"[session exportAsynchronouslyWithCompletionHandler:^{
if ([[NSFileManager defaultManager] fileExistsAtPath:outPutFilePath])
{
// 調(diào)用播放方法
[self playAudio:[NSURL fileURLWithPath:outPutFilePath]];
}
else
{
NSLog(@"輸出錯誤");
}
}];"
就可以輸出了.個人推薦在里面做個判斷,因為無論合成失敗或者成功,都會調(diào)用block內(nèi)的方法,但是如果失敗則不會生成文件.可以通過這個來判是否合成成功.
插入多個
蘋果還提供了一個inserts
的函數(shù),我們來試試是否可以批量插入
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];
運行!結(jié)果是依然還是一條音軌,原來這是個批量添加到尾部音軌的函數(shù),即當(dāng)A音軌播放完后,B音軌接著A后面無縫添加,而不是同時添加音軌.
音頻和視頻
大體上和上面一樣,我們只需要注意改幾個參數(shù)就好了
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
會產(chǎn)生不同的outputFileType
一定要填寫相對應(yīng)的支持類型,否則會直接crash!
文章參考資料
http://blog.csdn.net/linzhiji/article/details/6736704
http://www.lxweimin.com/p/9f83af9dbbef
寫在最后
如果有什么遺漏或者錯誤歡迎指正,共同進步!
附上Demo地址:https://github.com/WeiTChen/multitrackerDemo
原創(chuàng)作品,轉(zhuǎn)載請注明出處