iOS 干货整理GPUImageiOS 实用技术

GPUImage详细解析(八)视频合并混音

2016-06-25  本文已影响4230人  落影loyinglin

回顾

GPUImage源码解析、图片模糊、视频滤镜、视频水印、文字水印和动态图片水印GPUImage的大多数功能已经介绍完毕,这次的demo是源于简书的一位简友问我如何用GPUImage进行混音,他需要对视频添加水印背景音乐
经过一番研究,找到了一个解决方案,下面我们按照这个方案进行实践,并学习如何进行混音

知识储备

1、AVFoundation

2、GCD

用处:在dispatch_queue中开始一个group任务,当group里面所有任务完成调用再执行最后的任务。
在demo主要用于等待异步加载Reader等待视频合并完成

核心思路

具体细节

1、音频流解析

2、视频流解析

视频流的解析在解析六解析七已经详细介绍过。

3、THImageMovieWriter对象解析

THImageMovieWriter对象和GPUImageMovieWriter非常类似,核心的逻辑也是分为音频信息写入和视频信息写入。


代码解析

右边是代码地址

THImageMovie

添加了renderNextFrame方法。如果还有下一帧视频信息,那么返回Yes,如果没有则返回No。

- (BOOL)renderNextFrame {
    __unsafe_unretained THImageMovie *weakSelf = self;
    if (reader.status == AVAssetReaderStatusReading && (!_shouldRepeat || keepLooping))
    {

        return [weakSelf readNextVideoFrameFromOutput:readerVideoTrackOutput];
    }

    if (reader.status == AVAssetWriterStatusCompleted) {
        NSLog(@"movie: %@ reading is done", self.url.lastPathComponent);
        [reader cancelReading];

        [weakSelf endProcessing];
    }
    return NO;
}

THImageMovieWriter

下面是核心的逻辑,设置多个音轨的合并信息,并通过AVMutableComposition设置为AVAssetReader的输入。

/**
 *  设置读取音频信息的Reader
 */
- (void)setupAudioAssetReader {
    
    NSMutableArray *audioTracks = [NSMutableArray array];
    
    for(THImageMovie *movie in self.movies){
        AVAsset *asset = movie.asset;
        if(asset){
            NSArray *_audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
            if(_audioTracks.count > 0){
                [audioTracks addObject:_audioTracks.firstObject];
            }
        }
    }
    AVMutableComposition* mixComposition = [AVMutableComposition composition];
    
    for(AVAssetTrack *track in audioTracks){
        if(![track isKindOfClass:[NSNull class]]){
            NSLog(@"track url: %@ duration: %.2f", track.asset, CMTimeGetSeconds(track.asset.duration));
            AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                     
                                                                                                preferredTrackID:kCMPersistentTrackID_Invalid];
            [compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, track.asset.duration)
                                                ofTrack:track
                                                 atTime:kCMTimeZero error:nil];
        }
    }
    
    self.assetAudioReader = [AVAssetReader assetReaderWithAsset:mixComposition error:nil];
    self.assetAudioReaderTrackOutput =
    [[AVAssetReaderAudioMixOutput alloc] initWithAudioTracks:[mixComposition tracksWithMediaType:AVMediaTypeAudio]
                                               audioSettings:nil];
    
    [self.assetAudioReader addOutput:self.assetAudioReaderTrackOutput];
}

总结

为什么GPUImage没有支持音轨合并?
GPUImage的核心是响应链,通过GPU对图像进行加工,并且download下来。
而音频信息没有这么流畅的操作,作者没有进行支持。

苹果的官方有纯AVFoundation实现的视频合并和音频合并,但是学习的成本非常高,研究了几天还是没有吃透。而且和GPUImage没有关系,就不写入本次教程,留待以后单开一篇。

AVFoundation的内容还不够熟悉,这次很多时间是花在理解和消化音轨相关的知识。

留下一个思考题:

GPUImage做出来的视频有时候会遇到视频特别长,或者是没有声音的情况,可能是什么原因导致的?

上一篇下一篇

猜你喜欢

热点阅读