前言
从本文开始逐渐学习iOS自带的多媒体处理框架,例如AVFoundation,VideoToolbox,CoreMedia,CoreVideo实现多媒体的处理,并且将实现方式以及效果和ffmpeg的方式做对比
本文的目的为实现将本地的多媒体文件(MP4,MP3,MOV等等)解封装
对应的ffmpeg实现方式参考:MP4/MP3解封装ffmpeg(十三)
解封装相关流程
image.png
解封装相关对象及函数介绍
-
1、AVURLAsset对象
AVAsset对象是一个抽象子类,是AVFoundation中对封装格式资源的封装,比如MP4容器,MKV容器,MP3容器等等。AVURLAsset对象则是它的一个具体子类
通常通过该子类来初始化一个AVAsset对象。容器的属性(如音视频时长,视频帧率,编解码格式等等)通过键值对的方式存储于AVAsset对象中; -
2、loadValuesAsynchronouslyForKeys:
初始化AVURLAsset对象的资源可以是本地的MP4资源,也可以是远程的基于HTTP协议的MP4资源;访问AVURLAsset对象(这里假设为inputAsset)的属性有两种方式,同步和异步
a、直接调用属性名如下,inputAsset.tracks,inputAsset.duration等等是同步的方式,它的机制为:如果属性值未初始化,那么将阻塞当前线程去解封装容器的资源去
b、异步方式,通过loadValuesAsynchronouslyForKeys方法将对应的属性名传递进去异步获取,比如@[@"tracks",@"duration"]将异步获取这两个属性;该函数的作用和ffmpeg的avformat_open_input()函数功能一样;备注:inputAsset不能被释放,否则初始化会失败,回调函数不在主线程中 -
3、AVAssetReader对象
它作为从容器对象AVAsset对象读取音视频数据的管理器,需要音视频输出对象才能向外部输出数据 -
4、AVAssetTrack 对象
1、音视频流对象,它代表了容器中的某一路音视频流,跟ffmpeg中AVStream对象功能一样。
2、一个容器中可以包括一路视频流或者多路音频流或者多路字幕流
3、当AVAsset对象被初始化之后,音视频流对象就被初始化了 -
5、AVAssetReaderTrackOutput 对象
1、音视频输出对象,它是AVAssetReaderOutput对象的具体实现子类,外部通过该对象读取音视频数据
2、该对象负责配置输出音视频数据的格式等等参数
3、音视频输出对象要加入到音视频读取管理对象中才能从其中读取数据 -
6、assetReaderTrackOutputWithTrack:outputSettings:
此方法要说明下,当outputSettings:对应的参数为nil时当代表输出压缩的数据,
如果配置了outputSettings 则内部会自动调用gpu硬解码输出解压后的数据,解压后的数据格式为前面outputSettings中配置的;
实现代码
头文件 AVDemuxer.h
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface AVDemuxer : NSObject
@property(nonatomic,strong)AVAsset *asset;
@property(nonatomic,strong)AVAssetReader *assetReader;
@property(nonatomic,assign)BOOL autoDecode;
- (id)initWithURL:(NSURL*)localURL;
/** 实现解封装MP4文件,并且将其中的未压缩音视频数据读取出来
*/
- (void)startProcess;
- (void)stopProcess;
@end