目录
1、相关头文件
2、相关结构体
3、相关函数
4、函数详解
5、源码附上
1、相关头文件
#include <libavformat/avformat.h> 包含格式相关的函数和数据结构
#include <libavutil/avutil.h> 包含一些通用实用函数
2、相关结构体
AVFormatContext 用于存储媒体文件的信息
3、相关函数
1、void av_register_all(void);
解释:初始化所有的编解码器、解码器、分离器和复用器。在使用任何其他 libav* 函数之前,必须调用此函数一次。在 FFmpeg 4.0 之后的版本中,这个函数已经被弃用,不再需要调用。
2、int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
- 参数:
AVFormatContext **ps
:指向格式上下文指针的指针。成功打开文件后,它将指向一个已初始化的AVFormatContext
。const char *filename
:输入文件的文件名。AVInputFormat *fmt
:指定输入格式。通常传递NULL
以自动检测格式。AVDictionary **options
:包含输入选项的字典。通常传递NULL
。- 返回值:返回 0 表示成功,负值表示错误。
- 解释:打开输入文件并读取文件头,创建并初始化
AVFormatContext
。
3、int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
- 参数:
AVFormatContext *ic
:指向已打开的AVFormatContext
。AVDictionary **options
:包含选项的字典。通常传递NULL
。- 返回值:返回 0 表示成功,负值表示错误。
- 解释:读取媒体文件的数据以获取流信息。
4、void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output);
- 参数:
AVFormatContext *ic
:指向AVFormatContext
的指针。int index
:流的索引,通常传递 0。const char *url
:输入文件的 URL。int is_output
:如果是输入文件,传递 0;如果是输出文件,传递 1。- 解释:打印
AVFormatContext
的详细信息,主要用于调试。
5、void avformat_close_input(AVFormatContext **s);
- 参数:
AVFormatContext **s
:指向格式上下文指针的指针。- 解释:关闭一个打开的输入文件并释放相关资源,调用之后,
s
将被设置为 NULL。
4、函数详解
av_register_all
:
此函数在程序开始时调用,注册所有可用的文件格式、编解码器和网络协议。尽管在较新的 FFmpeg 版本中不再需要,但在旧版本中这是必要的一步,确保库中所有功能可用。
avformat_open_input
:
这个函数尝试打开一个媒体文件,并读取文件头来填充AVFormatContext
。如果文件打开成功,AVFormatContext
将包含有关文件格式的信息。它不仅处理本地文件,也支持通过 URL 访问网络上的媒体流。
avformat_find_stream_info
:
在成功打开媒体文件后,FFmpeg 还需要更多信息来正确解码数据。此函数读取更多的数据包以获取关于文件中每个流的信息(如视频和音频流),并填充AVFormatContext
中的流信息。
av_dump_format
:
这是一个非常有用的调试工具,可以打印出媒体文件的详细信息,包括每个流的格式、比特率、分辨率等。对于开发者来说,这是验证 FFmpeg 是否正确解析文件的好方法。
avformat_close_input
:
在处理完媒体文件后,需要调用此函数来关闭文件并释放与AVFormatContext
相关的所有资源。这是资源管理的一个重要部分,确保没有内存泄漏或资源占用。
5、源码附上
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
int main(int argc, char *argv[]) {
if ( argc < 2 ) {
fprintf(stderr, "Usage: %s <input_file>\n", argv[0]);
return -1;
}
AVFormatContext *fmt_ctx = NULL;
const char *input_filename = "input.mp4";
input_filename = argv[1];
// 初始化所有编解码器, 我使用的ffmpeg版本以及弃用该函数
// av_register_all();
// 打开输入文件并且读取文件头
int ret = avformat_open_input( &fmt_ctx, input_filename, NULL, NULL );
if ( ret ) {
fprintf( stderr, "avformat_open_input open %s error!!!\n", input_filename );
return -1;
}
// 读取媒体文件数据以获取流信息
ret = avformat_find_stream_info( fmt_ctx, NULL );
if ( ret ) {
fprintf( stderr, "avformat_find_stream_info error!!!\n" );
return -1;
}
// 打印AVFormatContext信息
av_dump_format( fmt_ctx, 0, input_filename, 0 );
// 关闭文件, 并设置AVFormatContext指针为NULL
avformat_close_input( &fmt_ctx );
return 0;
}