之前各種事情在身,發現好久沒更新文章了,臨近年末,就把最近做的視頻處理相關的內容整理一下吧~

最近在做視頻編輯處理相關的開發,其中之一就是音視頻合成,需求是用戶可以選擇將相冊中的視頻,然后將一段音樂片段加入其中,并可以實時調整視頻原聲以及添加的音樂音量,最后合成為一個視頻。

1、分析

首先對于視頻處理,萬能的肯定可以實現,但依賴并用一段magic一樣的語句維護擴展都十分有限,對結構不熟悉的話大量c的api也會無從下手,適合熟悉并且對陌生者使用。

其次的最優方案就是了,作為蘋果音視頻編輯的利器可謂十分強大,官方有一 demo利用來實現音頻的混音,甚至可以對pcm數據進行編輯,但是缺點也很明顯:1 和視頻沒什么關系,還得啟一個來播放(那還不如單獨用得了) 2 并沒有對音頻如“美聲,變音”之類的需求。所以不作為考慮范圍,不過可以實現一些特殊音效還是很厲害的,感興趣可以下來官方demo-Using for , and () 看看。

我最后選用的方案就是ios視頻編輯ios視頻編輯,熟悉以及的話可能會注意到 是作為屬性存在于的分類中。

/*! @property audioMix @abstract Indicates the audio mix parameters to be applied during playback @discussion ? The inputParameters of the AVAudioMix must have trackIDs that correspond to a track of the receiver's asset. Otherwise they will be ignored. (See AVAudioMix.h for the declaration of AVAudioMixInputParameters and AVPlayerItem's asset property.) */@property (nonatomic, copy, nullable) AVAudioMix *audioMix;

" the audio mix to be " 表明是可以在播放的時設置,需要注意的就是需要對應。

補充:可能有人覺得最簡單的是同時創建一個負責播放視頻,一個播放音樂;當然這種方法是可以實現基本需求,但完美出同步這倆個播放器的狀態會是一個問題,而且最終還是要經歷混音寫文件過程,從邏輯上看十分糟糕。

2、播放實現

為了表述清晰下面省略等沒太大關系的代碼,同樣也可以下載我的 demo 來查看所有內容。

流程如下:

1.創建視頻以及音頻的

 ?AVURLAsset *videoAsset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"demo" ofType:@"mp4"]]]; ?AVURLAsset *musicAsset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"music" ofType:@"mp3"]]];

2.聲明并實例化音視頻處理的核心類

@property (nonatomic, readwrite, strong) AVMutableComposition *composition;@property (nonatomic, readwrite, strong) AVMutableVideoComposition *videoComposition;@property (nonatomic, readwrite, strong) AVMutableAudioMix *audioMix; AVMutableComposition *composition = [AVMutableComposition composition]; AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition]; AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];

3.創建1條視頻處理軌道以及2條音頻處理軌道(視頻原聲+添加的音樂這倆條音軌)

 ?AVMutableCompositionTrack *compositionVideoTracks = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; ?AVMutableCompositionTrack *compositionAudioTracks[2]; ?compositionAudioTracks[0] = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; ?compositionAudioTracks[1] = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

【學習地址】://RTMP/NDK/音視頻流媒體高級開發

【文章福利】:免費領取更多音視頻學習資料包、大廠面試題、技術視頻和學習路線圖,資料包括(C/C++,Linux, rtmp hls rtsp srs 等等)有需要的可以點擊加群領取哦~

4.根據之前創建好的視頻以及音頻資源()實例化一條視頻軌道以及2條音頻軌道

 ?AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; ?  [compositionVideoTracks insertTimeRange:self.videoTimeRange ofTrack:videoTrack atTime:kCMTimeZero error:&error]; ? ? ? ? ?AVAssetTrack *audioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; ?  [_comTrack1 insertTimeRange:self.videoTimeRange ofTrack:audioTrack atTime:kCMTimeZero error:&error]; ? ? ? ? ?AVAssetTrack *musicTrack = [[self.musicAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; ? ? [_comTrack2 insertTimeRange:self.videoTimeRange ofTrack:musicTrack atTime:kCMTimeZero error:&error];

5.配置參數,注意這里的一定得是上面創建的Track對應的,而不是中的,之前使用出過很奇怪的問題,而后在上找到了這個解決方案

 NSMutableArray *trackMixArray = [NSMutableArray array]; ?  { ? ? ? ?AVMutableAudioMixInputParameters *trackMix1 = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:_comTrack1]; ? ? ? ?trackMix1.trackID = _comTrack1.trackID; ? ? ?  [trackMix1 setVolume:_videoVolume atTime:kCMTimeZero]; ? ? ?  [trackMixArray addObject:trackMix1]; ? ? ? ? ? ? ? ?AVMutableAudioMixInputParameters *trackMix2 = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:_comTrack2]; ? ? ? ?trackMix2.trackID = _comTrack2.trackID; ? ? ?  [trackMix2 setVolume:_musicVolume atTime:kCMTimeZero]; ? ? ?  [trackMixArray addObject:trackMix2]; ?  } ? ? ?audioMix.inputParameters = trackMixArray;

6.構建, 設置asset以及最重要的,然后交給就可以同時播放視頻與音樂了!

- (AVPlayerItem *)playerItem { ? ?if (!_currentItem) { ? ? ? ?AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:self.composition]; ? ? ? ?playerItem.videoComposition = self.videoComposition; ? ? ? ?playerItem.audioMix = self.audioMix; ? ? ? ?_currentItem = playerItem; ?  } ? ?return _currentItem;}

7.播放時調整音量,這里其實和第5步一樣,重新配置參數后賦值給,設置音樂音量同理

- (void)setVideoVolume:(CGFloat)volume { ? ?NSMutableArray *allAudioParams = [NSMutableArray array]; ? ? ? ?AVMutableAudioMixInputParameters *audioInputParams = ?  [AVMutableAudioMixInputParameters audioMixInputParameters]; ?  [audioInputParams setTrackID:_comTrack1.trackID]; ? ?_videoVolume = volume; ?  [audioInputParams setVolume:_videoVolume atTime:kCMTimeZero]; ?  [allAudioParams addObject:audioInputParams]; ? ? ? ?AVMutableAudioMixInputParameters *audioInputParams2 = ?  [AVMutableAudioMixInputParameters audioMixInputParameters]; ?  [audioInputParams2 setTrackID:_comTrack2.trackID]; ?  [audioInputParams2 setVolume:_musicVolume atTime:kCMTimeZero]; ?  [allAudioParams addObject:audioInputParams2]; ? ? ? ?AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix]; ?  [audioMix setInputParameters:allAudioParams]; ? ? ?  [_currentItem setAudioMix:audioMix];}

3、導出實現

這里直接使用來導出視頻,與設置的屬性相同,將設置給實例即可導出混合的視頻了

 ? ?NSURL *outputFileUrl = [NSURL fileURLWithPath:outputPath]; ? ? ? ?AVAssetExportSession *_assetExport =[[AVAssetExportSession alloc]initWithAsset:self.composition presetName:AVAssetExportPreset1280x720]; ? ?_assetExport.outputFileType = AVFileTypeMPEG4; ? ?_assetExport.audioMix = _currentItem.audioMix; ? ?_assetExport.outputURL = outputFileUrl; ? ?_assetExport.shouldOptimizeForNetworkUse = YES; ? ? ?  [_assetExport exportAsynchronouslyWithCompletionHandler:^{ ? ? ? ?// ?  }];

最后貼上Demo地址 有什么問題歡迎留言,如果還能提供不同實現方案或思路也可以和我討論~

原文鏈接:iOS視頻編輯之添加音軌 - 簡書