美文网首页视频iOS视频的编辑AVPlayer和GPUImagede学习
AVFoundation 教你如何处理混音,拼接,消音,快进倒放

AVFoundation 教你如何处理混音,拼接,消音,快进倒放

作者: Y_Swordsman | 来源:发表于2017-06-19 15:19 被阅读569次

    第一 对于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];
    

    到这里你就能感受到混音的功能了。下一个文章我将给大家讲解如何去实现吧处理后的音视频如何压缩写出来成一个文件。

    原创文章转载需获授权并注明出处
    请在后台留言联系转载

    相关文章

      网友评论

        本文标题:AVFoundation 教你如何处理混音,拼接,消音,快进倒放

        本文链接:https://www.haomeiwen.com/subject/zelsxxtx.html