第一 對于AVFoundation的理解
我們現在原生上對于視頻的處理都是在于avfoundation的框架下完成的.那我們對視頻的剪接、混音、倒放、快進等大部分功能。
一、混音
AVMutableComposition
混音主要我們會使用大avfoundation的一個API,AVMutableComposition(音視頻組合軌道)相當于一個容器.
//創建一個音視頻組合軌道
AVMutableComposition *mainComposition = [[AVMutableComposition alloc]init];
AVMutableCompositionTrack
創建對應的音視頻軌道 ==> AVMutableCompositionTrack
//可變音視頻軌道添加一個 視頻通道
AVMutableCompositionTrack *compositionVideoTrack = [mainComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
//可變音視頻軌道添加一個 音頻通道
AVMutableCompositionTrack *compositionAudioTrack = [mainComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
這個相當于一個容器里又兩個對應不同屬性的杯子.
AVAssetTrack
AVAssetTrack是一個軌道.一個AVAsset對象里有兩個數組.該數組分別裝著兩個不同屬性的軌道.既是音視軌軌道.
//視頻通道數組
NSArray<AVAssetTrack *> *videoTrackers = [asset tracksWithMediaType:AVMediaTypeVideo];
if (0 >= videoTrackers.count) {
NSLog(@"數據獲取失敗");
return ;
}
//獲取第一個視頻通道
AVAssetTrack *video_track = [videoTrackers objectAtIndex:0];
********************************************************
//獲取音頻軌道數組
NSArray<AVAssetTrack *> *audioTrackers = [asset tracksWithMediaType:AVMediaTypeAudio];
if (0 >= audioTrackers.count) {
NSLog(@"獲取音頻數據失敗");
return;
}
//獲取第一個音頻軌道
AVAssetTrack *audio_track = [audioTrackers objectAtIndex:0];
將獲取的視軌倒入杯子
//視頻時間
float video_times = (float)asset.duration.value / (float)asset.duration.timescale;
compositionVideoTrack.preferredTransform = video_track.preferredTransform;
NSError *error = nil;
//把采集軌道數據加入到可變軌道之中
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
ofTrack:video_track
atTime:kCMTimeZero
error:&error];
if (error) {
NSLog(@"error;%@",error);
return;
}
*****************************************************
//獲取第一個音頻軌道
AVAssetTrack *audio_track = [audioTrackers objectAtIndex:0];
int audio_time_scale = audio_track.naturalTimeScale;
//獲取音頻的時間
CMTime audio_duration = CMTimeMake(video_times * audio_time_scale, audio_time_scale);
//將音頻軌道加入到可變軌道中
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audio_duration)
ofTrack:audio_track
atTime:kCMTimeZero
error:&error];
if (error) {
NSLog(@"音軌error:%@",error);
return;
}
對于- (BOOL)insertTimeRange:(CMTimeRange)timeRange ofTrack:(AVAssetTrack *)track atTime:(CMTime)startTime error:(NSError * _Nullable * _Nullable)outError
方法.timeRange表示的該視頻的時間范圍,track表示 你插入的軌道.StartTime 表示 你要在哪個時間點去開始插入這個軌道. outError 返回的錯誤信息.
再加入一個音軌
這個音軌可以從別的視頻里獲取,也可以從MP3中獲取
//增加音軌
//采集資源
AVURLAsset *mixAsset = [[AVURLAsset alloc]initWithURL:mixAssetUrl options:nil];
NSArray<AVAssetTrack *> *audioTrackers_mix = [mixAsset tracksWithMediaType:AVMediaTypeAudio];
if (0 >= audioTrackers_mix.count) {
NSLog(@"獲取第二音軌資源失敗");
return;
}
//可變音視軌道再添加一個 音軌
AVMutableCompositionTrack *mixAudioTrack = [mainComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];//第二音軌
//將采集到數據加入到第二音軌
[mixAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audio_duration)
ofTrack:[audioTrackers_mix objectAtIndex:0]
atTime:kCMTimeZero
error:&error];
對音視軌操作
該階段是對音視軌的處理.比如混音的時候如何處理哪個音軌音量的大小,設置視頻的大小.
//視頻操作指令集合
AVMutableVideoComposition *select_videoComposition = [AVMutableVideoComposition videoCompositionWithPropertiesOfAsset:mainComposition];
AVMutableVideoComposition *first_vcn = [AVMutableVideoComposition videoCompositionWithPropertiesOfAsset:asset];
select_videoComposition.renderSize = first_vcn.renderSize;
AVMutableAudioMix *videoAudioMixTools = [AVMutableAudioMix audioMix];
//獲取第一個音頻軌道
AVMutableAudioMixInputParameters *firstAudioParam = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:compositionAudioTrack];
//設置第一個音軌音量
[firstAudioParam setVolumeRampFromStartVolume:firstStartVolume toEndVolume:firstEndVolume timeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)];
//第二個音頻軌道
AVMutableAudioMixInputParameters *secondAudioParam = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:mixAudioTrack];
[secondAudioParam setVolumeRampFromStartVolume:secondStartVolume toEndVolume:secondEndVolume timeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)];
videoAudioMixTools.inputParameters = @[firstAudioParam,secondAudioParam];
到這里你就可以獲得三個參數分別為mainComposition(既是音視頻組合軌道)
、select_videoComposition(視頻操作指令集合)
、videoAudioMixTools(音頻操作)
.
預覽
預覽主要用到三個參數 mainComposition
select_videoComposition
videoAudioMixTools
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:sourceVideo_.mainComposition];
[item setAudioMix:sourceVideo_.videoAudioMixTools];
AVPlayer *tmpPlayer = [AVPlayer playerWithPlayerItem:item];
self.player = tmpPlayer;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = self.videoContainView.bounds;
playerLayer.videoGravity = AVLayerVideoGravityResize;
[self.view.layer addSublayer:playerLayer];
到這里你就能感受到混音的功能了。下一個文章我將給大家講解如何去實現吧處理后的音視頻如何壓縮寫出來成一個文件。
原創文章轉載需獲授權并注明出處
請在后臺留言聯系轉載