利用AVFoundation中的AVAudioMix實現(xiàn)混音

正如可以用AVVideoComposition實現(xiàn)視頻的混合一樣,也可以用AVAudioMix實現(xiàn)音頻的混合,用法也跟AVVideoComposition很相似,
Demo見https://github.com/Phelthas/TEST_XMLCommon

首先創(chuàng)建一個AVMutableComposition,將需要混音的視頻或者音頻軌道添加進去

    AVAssetTrack *videoTrack = [videoAsset tracksWithMediaType:AVMediaTypeVideo].firstObject;
    AVAssetTrack *audioTrack1 = [videoAsset tracksWithMediaType:AVMediaTypeAudio].firstObject;
    AVAssetTrack *audioTrack2 = [audioAsset tracksWithMediaType:AVMediaTypeAudio].firstObject;
    AVMutableComposition *composition = [AVMutableComposition composition];
    AVMutableCompositionTrack *videoCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    [videoCompositionTrack insertTimeRange:videoTimeRange ofTrack:videoTrack atTime:kCMTimeZero error:nil];
    AVMutableCompositionTrack *audioCompositionTrack1 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    [audioCompositionTrack1 insertTimeRange:videoTimeRange ofTrack:audioTrack1 atTime:kCMTimeZero error:nil];
    AVMutableCompositionTrack *audioCompositionTrack2 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    [audioCompositionTrack2 insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:audioTrack2 atTime:kCMTimeZero error:nil];
    self.composition = composition;

然后創(chuàng)建AVMutableAudioMix,創(chuàng)建對應(yīng)音軌的AVMutableAudioMixInputParameters并設(shè)置音量,賦值給AVMutableAudioMix的inputParameters即可。

注意這里最好用添加到composition中的AVMutableCompositionTrack來初始化AVMutableAudioMixInputParameters,否則還需要手動設(shè)置trackID。(每個track的trackID必須不一樣)

    AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
    // 注意:這里必須要用audioCompositionTrack1而不能用audioTrack1,否則會因為trackId不一致而不生效
    AVMutableAudioMixInputParameters *inputParameters1 = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:audioCompositionTrack1];
    [inputParameters1 setVolume:1 atTime:kCMTimeZero];
    AVMutableAudioMixInputParameters *inputParameters2 = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:audioCompositionTrack2];
    [inputParameters2 setVolume:0.5 atTime:kCMTimeZero];
    audioMix.inputParameters = @[inputParameters1, inputParameters2];
    self.audioMix = audioMix;

最后將audioMix賦值給playerItem即可

    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:composition];
    playerItem.audioMix = audioMix;
    self.playerItem = playerItem;
    AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
    self.player = player;
    [player play];

完成~

如果需要實時修改混音的音量(比如用slider分別控制音軌的音量),需要每次都重新生成AVAudioMix才行,且里面的inputParameters也需要重新生成或者mutableCopy,直接修改原來的音量再賦值是不行的

    AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
    AVMutableAudioMixInputParameters *parameters1 = [[self.audioMix.inputParameters objectAtIndex:0] mutableCopy];
    [parameters1 setVolume:self.slider1.value atTime:kCMTimeZero];
    AVMutableAudioMixInputParameters *parameters2 = [[self.audioMix.inputParameters objectAtIndex:1] mutableCopy];
    [parameters2 setVolume:self.slider2.value atTime:kCMTimeZero];
    audioMix.inputParameters = @[parameters1, parameters2];
    self.playerItem.audioMix = audioMix;

導出時只需要將AudioMix賦值給exportSession即可,其他完全一樣
注意:導出后多個音軌會合并成一個

    NSString *userCacheDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
    NSString *outputURLString = [NSString stringWithFormat:@"%@/audioMixOutput.mp4", userCacheDirectory];
    NSLog(outputURLString);
    [kLXMFileManager removeItemAtPath:outputURLString error:nil];
    AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:self.composition presetName:AVAssetExportPresetHighestQuality];
    exportSession.outputFileType = AVFileTypeMPEG4;
    exportSession.outputURL = [NSURL fileURLWithPath:outputURLString];
    exportSession.shouldOptimizeForNetworkUse = YES;
    exportSession.audioMix = self.audioMix;
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        if (exportSession.status == AVAssetExportSessionStatusCompleted) {
            NSLog(@"export success");
        } else {
            NSLog(@"export failed: %@", exportSession.error);
        }
    }];

完整Demo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Editing(編輯) AVFoundation框架提供了一組功能豐富的類,以便于編輯視聽資料。AVFoundat...
    張芳濤閱讀 1,501評論 0 2
  • 之前各種事情在身,發(fā)現(xiàn)好久沒更新文章了,臨近年末,就把最近做的視頻處理相關(guān)的內(nèi)容整理一下吧~ 最近在做視頻編輯處理...
    Lucifron閱讀 6,448評論 1 12
  • 這個問題比較大,但是咱們長話短說。 國外的詩歌我們不管,我們只講中國詩歌。中國的詩歌總的來說分為兩大部分:古詩和新...
    梧桐樹邊羽閱讀 4,061評論 0 4
  • 尊重差異,感激多樣性、然后,培養(yǎng)自己,從報仇,到妥協(xié),到合作、最后,找到共享的目標,通過創(chuàng)造性的合作,發(fā)現(xiàn)“天啊...
    C位人生閱讀 173評論 0 0
  • 作者:星期八病號/小圣齊天 細雨淅淅 霜華為期 我有佳佳 在北一方 瘋瘋癲癲 癡癡笑笑 取經(jīng)路上 可愿隨行 小圣齊...
    小圣齊天閱讀 474評論 31 16

友情鏈接更多精彩內(nèi)容