第一 对于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];
到这里你就能感受到混音的功能了。下一个文章我将给大家讲解如何去实现吧处理后的音视频如何压缩写出来成一个文件。
原创文章转载需获授权并注明出处
请在后台留言联系转载