概述:这些API可用到QT的实战中。
1.主要API函数
av_register_all();
解析:将ffmpeg所定义的格式库和各种协议注册到程序中。有了这个我们就可以查询到各种库和协议。所有的ffmpeg程序开始之前必须要调用的函数。
avformat_open_input()
//参数1:AVFormatContext的指针的指针
//参数2:视频文件地址(有带文件名的那种)
//参数3:输入文件的格式,一般我们这写NULL让他自己识别视频文件
//参数4:要传入函数的参数,但是这意义不大,一般写NULL
avformat_close_input()
//参数1:AVFormatContext的指针的指针,注意是二级指针
解析:这两个API是成对出现的;
主要作用是打开一个多媒体文件,它会根据文件的后缀名来识别格式是什么。结束后会输出一个重要的结构体。就是在FFmpeg学习笔记(4) 中最重要的结构体AVFormatContext——格式上下文。有了这个格式上下文我们就可以获取到音视频流的信息了。
注意:结束不用 的时候就要把AVFormatContext传到avformat_close_input()中把他释放掉。不然会内存泄漏!
av_dump_format();
//参数1:AVFormatContext的指针,注意不是二重指针!
//参数2:直接输入0
//参数3:视频文件地址(有带文件名的那种)
//参数4:指定是输入流还是输出流,输入流是0,输出流是1
//在这一笔记中我们用到的都是输入流的函数(API函数后面部分是input)所以这里是0,
解析:他是在这则笔记中比较重要的API函数,它主要就是打印出多媒体文件的信息
2.linux下demo
#include <libavutil/log.h>
#include <libavformat/format.h>
int main(int argc,char* argv[]){
int ret = 0;
//格式上下文
AVFormatContext *fmt_ctx = NULL;
//设置日志级别
av_log_set_level(AV_LOG_INFO);
//注册
av_register_all();
//这里我的根目录里面要有test.mp4这个音视频文件才行。
ret = avformat_open_input(&fmt_ctx,"./test.mp4",NULL,NULL);
if(ret<0){
av_log(NULL,AV_LOG_ERROR,"打开失败:%s\n",av_err2str(ret));
return -1;
}
//输出音视频的信息
av_dump_format(fmt_ctx,0,"./test.mp4",0);
avformat_close_input(&fmt_ctx);
return 0;
}
注意,这个在Linux下是可以的,但是在QT里面av_dump_format需要fflush(stderr)函数帮助才能输出,标准输出和标准错误输出均有缓存,缓存达到一定程度后,方才输出。
这里解释一下fflush(stderr)口号里面的 stderr,和stdout重要的一点区别,stderr是没有缓冲的,它立即输出,而stdout默认是行缓冲,也就是它遇到‘\n’,才向外输出内容,如果你想stdout也实时输出内容,那就在输出语句后加上fflush(stdout),这样就能达到实时输出的效果。
QT中的使用
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//先获取名字,并且保存
char* cinputFilePath = "text.mov"; //本地视频文件放入程序运行目录
AVFormatContext* fmt_ctx = avformat_alloc_context();
//参数一:封装格式上下文->AVFormatContext->包含了视频信息(视频格式、大小等等...)
//参数二:打开文件(入口文件)->url
int avformat_open_result = avformat_open_input(&fmt_ctx,cinputFilePath,NULL,NULL);
if (avformat_open_result != 0)
{
//获取异常信息,注意这里是
char* error_info = new char[32];
av_strerror(avformat_open_result, error_info, 1024);
qDebug()<<QString("异常信息 %1").arg(avformat_open_result);
};
//此函数自动打印输入或输出的详细信息
av_dump_format(fmt_ctx, 0, cinputFilePath, 0);
//需要使用fflush(stderr)把缓冲区的数据打印出来
fflush(stderr);
//有打开就要有关闭
avformat_close_input(&fmt_ctx);
}