编译好了ffmpeg和x264之后, 在来看看怎么使用他们.
首先在项目文件中加入ffmpeglib和x264lib, 然后在Build Setting->Header Search Paths 加入他们的include目录, 如
$(PROJECT_DIR)/ffmpeg/libs/ffmpeglib/include
$(PROJECT_DIR)/ffmpeg/libs/x264lib/include
然后在Build Phases->Link Binary With Libraries中加入
libz.tbd, libiconv.tbd, libbz2.tbd
等库的引用
如果在.m文件中, include头文件即可使用
首先对ffmpeg几个结构体先介绍一下
AVFormatContext,这个结构体主要与文件有关, 打开文件, 关闭文件, 对文件的操作主要都是由它完成的.
AVStream, 跟流相关的, 视频流, 音频流, 还有字幕流.
AVCodecContext, 跟解码器相关的
AVCodec, 解码器
AVPacket, 原始的数据, 对H264格式的视频来说, 就是一帧一帧的未解码的数据, I帧, P帧, B帧这些
AVFrame, 未压缩的数据, 就视频来说, 就是解码完后, 一个完整的图片, 对音频来说就是音频数据
几个主要函数
avformat_open_input 打开文件
avformat_close_input 关闭文件
avformat_find_stream_info 获取流信息
avcodec_open2 打开解码器
avcodec_close 关闭解码器
av_read_frame 读取完整一帧数据
avcodec_decode_video2 解码视频帧
avcodec_decode_audio4 解码音频帧
基本的流程是这样
打开文件->获取流信息并初始化解码器->读取视频/音频帧->解码视频/音频帧->显示
视频解码完后一般是YUV格式, YUV格式的显示可以用OpenGL显示
音频解码完后就是裸数据PCM, 我们播放的时候, 正常的数据都是要非plane的格式, 如果你的数据是plane的, 还需要转换, PCM数据可以用OpenAL来播放
如果你的文件是网络文件, 那么接受最好独立开一条线程, 解码视频和音频, 一般也需要开启另外一条线程, 因为这些操作都是挺耗时的
显示的话, 可以用一个定时器, 根据你视频的帧数设定定时器的间隔
还有一个问题, 音频和视频的同步, 因为我们音频和视频是分开播放, 所以才会有同步在这个问题, 正常可以用时间戳来同步.这边的时间戳可以用AVFrame的pkt_dts, pkt_pts之类的统计, 也可以自己计算视频和音频各自的时间
打开文件
int ret = 0;
_formatContext = avformat_alloc_context();
ret = avformat_open_input(&_formatContext, [file UTF8String], NULL, NULL);
获取流信息并初始化解码器