1、打开音视频文件
使用avformat_open_input函数打开音视频文件,获取该文件构成和基本信息的结构体。
* 打开一个输入流并读取头部。未打开编解码器。
* 必须使用 avformat_close_input() 关闭流。
* @param ps 指向用户提供的 AVFormatContext 的指针(由 avformat_alloc_context 分配)。
* 可能是一个指向 NULL 的指针,在这种情况下,一个 AVFormatContext 由 this 分配函数并写入 ps。
* 请注意,用户提供的 AVFormatContext 将在失败时被释放。
* @param url 要打开的流的 URL或者文件名,如果是打开网络流,调用该函数前需要调用avformat_network_init()。
* @param fmt 如果非空,此参数强制特定的输入格式。否则格式是自动检测的。
* @param options 一个充满 AVFormatContext 和 demuxer-private 选项的字典。返回时,此参数将被销毁并替换为包含未找到的选项。可能为 NULL。
* @return 成功时返回 0,失败时返回负的 AVERROR。
* @note 如果要使用自定义 IO,请预先分配格式上下文并设置其 pb 字段。
int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options);
//调用例子
const char *in_filename = "believe.mp4";
AVFormatContext *ifmt_ctx = NULL; // 输入文件的demux
int ret = avformat_open_input(&ifmt_ctx, in_filename, NULL, NULL);
AVFormatContext是描述一个媒体文件或媒体流的构成和基本信息的结构体。
2、读取媒体文件的音视频包去获取流信息
/**
* 读取媒体文件的数据包以获取流信息。 这个
* 对于没有标题的文件格式(如 MPEG)很有用。 这个
* 在 MPEG-2 重复的情况下,函数还计算实际帧率
* 帧模式。
* 逻辑文件位置不会被这个函数改变;
* 检查的数据包可能会被缓冲以供以后处理。
* @param ic 媒体文件句柄
* @param options 如果非 NULL,一个 ic.nb_streams 长指针数组
* 字典,其中第 i 个成员包含以下选项
* 对应于第 i 个流的编解码器。
* 返回时,每本词典将填充未找到的选项。
* @return >=0 如果正常,AVERROR_xxx 出错
* @note 这个函数不能保证打开所有的编解码器,所以
* 返回时非空的选项是完全正常的行为。
* @todo 让用户以某种方式决定需要什么信息,以便
* 我们不会浪费时间获取用户不需要的东西。
*/
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
//调用例子
ret = avformat_find_stream_info(ifmt_ctx, NULL);
音频流、视频流、字幕流的信息存储在AVFormatContext 结构体的streams数组中,可以通过判断流的codecpar成员的codec_type类型区分它们。
3、打印输入或输出格式的详细信息
/**
* 打印关于输入或输出格式的详细信息,例如持续时间,比特率,流,容器,程序,元数据,边数据,编解码器和时基。
* @param ic AVFormatContext 结构体指针
* @param index index 参数用于指定要打印的音视频流的索引。如果传入的值为负数,表示打印所有音视频流的信息;如果传入的值为非负数,则表示打印指定索引的音视频流信息。
* @param url 音视频文件的 URL 或者文件名
* @param is_output is_output 参数用于指示传入的音视频文件是否为输出文件。如果该参数为非零值,表示传入的音视频文件是输出文件;如果为零值,则表示传入的音视频文件是输入文件。
*/
void av_dump_format(AVFormatContext *ic,
int index,
const char *url,
int is_output);
//使用例子
av_dump_format(ifmt_ctx, 0, in_filename, 0);
4、分配音视频帧结构体的函数
//av_packet_alloc 是 FFmpeg 中用于分配 AVPacket 结构体的函数,AVPacket 结构体用于表示音视频数据包。
av_packet_alloc();
5、获取音视频帧
//该函数是 FFmpeg 中用于从媒体文件中读取音视频帧的函数。它的作用是从输入媒体文件(如视频文件)中读取下一帧的音频或视频数据。
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
//调用例子
AVPacket *pkt = av_packet_alloc();
ret = av_read_frame(ifmt_ctx, pkt);
av_packet_unref(pkt);
6、关闭音视频文件
avformat_close_input(&ifmt_ctx);