AVFoundation视频播放、存储原理分析与使用

在前面的章节,我们分析了Camera拍照录制,获取音视频流的基本过程。以及AVAsset保存音频文件。这里我们还要再来了解下AVAsset以及利用AVFoundation读取音视频流处理的过程。看起来这两个部分可能有些重复,其实不然,在这个部分我们会详细的讨论如何利用AVFoundation读取音视频流数据,实时特效处理,AVAsset音视频文件保存的一些关键点。

<1> 利用音视频流播放音视频文件:

(1.1) 利用AVAsset分离音视频流的方法:

我们都知道多媒体文件读取之后,利用ffmpeg会首先检查音视频字幕轨道。所以这里也是进行这一步:

NSArray *videoTracks = [self.mAVAsset tracksWithMediaType:AVMediaTypeVideo];

    if ([videoTracks count] > 0) {

        AVAssetTrack *videoTrack = [videoTracks objectAtIndex:0];

        分离视频流数据

    }

NSArray *audioTracks = [self.mAVAsset tracksWithMediaType:AVMediaTypeAudio];

    if ([audioTracks count] > 0) {

        AVAssetTrack *audioTrack =  [audioTracks objectAtIndex:0];

分离音频流数据

    }

(1.2)音频播放

音频播放采用前面我们提到的Audio Queue,至于Audio Queue的原理以及使用,回调方法等等这里都不做描述了。可以参考前面的博客专栏。

- (CMSampleBufferRef)getNextAudio

{

    sampleBuffer = [self copyNextSampleBuffer];

在这里我们可以对拿到的音频数据进行特效处理

}

(1.3)音视频同步校验

音频我们可以直接交给IOS硬件来处理,那么视频我们怎么办?前面的Camera部分,我们讨论了使用OpenGl纹理贴图的方式显示视频文件,同样这里使用的也是这个方法,这里就不多描述了。

视频可以展示了,那么视频的时间戳我们怎么办呢?我们来看看音视频播放时都是怎么同步的?

一般情况下,可以通过音频文件同步视频文件,为什么这么说呢?因为一般情况下,我们的音频数据时交给IOS底层硬件处理,这个时候音频文件的播放时间一般都是准确的,用音频文件同步视频时间戳即可达到同步的功能。

但是,注意,这种方法是有局限性的,第一点硬件的音频播放要准确,第二点要音频数据的硬件采样周期仅可能的短,比如播放30帧视频,音频使用44100采样周期,那么硬件的采样周期不能高于1024个音频数据点.而硬件音频采样周期设置的过小,会让手机CPU使用太高,严重的会使手机发热。所以含有一种方式,也比较多。 我们自定义一个当前同步的时间戳,这个是系统标准时间,利用这个时间每次同步音频文件。同时将音频硬件采样周期放开,降低手机CPU使用率,音频每100多毫秒检查一次音视频是否同步。

- (CMSampleBufferRef)getNextVideo

{

    sampleBuffer = [self copyNextSampleBuffer];

特效处理 纹理贴图

}

<2> 音视频流保存:

- (void)appendSampleBuffer:(CMSampleBufferRef)sampleBuffer ofMediaType:(NSString *)mediaType

{


[self startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];

AVAssetWriterInput *input = ( mediaType == AVMediaTypeVideo ) ? _videoInput : _audioInput;

if ( input.readyForMoreMediaData )

{

[input appendSampleBuffer:sampleBuffer];

}

}

我们只需要将音视频流分别保存到各自的 AVAssetWriter即可。





猜你喜欢

转载自blog.csdn.net/u014011807/article/details/46964229
今日推荐