在之前的博客中 , 安装了 VS2015 , Qt 5.14.0 , CDB 调试器 , 并在 Qt 中配置了 MSVC 编译器 和 CDB 调试器 ;
本篇博客开始在 Windows 10 平台的 Qt 开发环境中导入 编译好的 FFmpeg 库 , 并调用 FFmpeg 库 ;
在 Windows 中调用的 FFmpeg 库需要
在本篇博客中使用的 Qt 5.14.0 开发环境 + MSVC 2015 编译器 + CDB 调试器 , 进行 FFmpeg 开发 , 导入 FFmpeg 编译好的 函数库 和 头文件 , 在 Qt 中的 C/C++ 代码中调用 FFmpeg 的功能 ;
博客的绑定资源中 , 附带了完整的 FFmpeg 函数库 , 动态库 , Qt 项目的头文件 / 函数库 配置 , 完整源码 , 可自行下载 ;
下载地址 : https://download.csdn.net/download/han1202012/89350567
FFmpeg 官方只给提供 源码 和 可执行程序 , 如果想要使用 函数库 , 必须自己使用源码编译 ;
FFmpeg 源码下载地址 : https://ffmpeg.org//download.html
这里提供一个编译好的 函数库 + 头文件 开发库 , ffmpeg-4.2.1-win32-dev.zip ,
该 开发库 只能在 Windows 系统中 , 使用 32 位 的编译器 进行编译 生成 32 位的 应用程序 ,
不能使用 64 位的编译器进行编译 , 无法编译生成 64 位的应用程序 ;
下载开发库后解压 , 内容如下 :
其中 examples 目录下是 FFmpeg 使用示例 ;
include 目录下是 一系列的 头文件 ,
打开 libavcodec 目录 , 与音视频编解码相关的头文件就在里面 ;
lib 目录下是 FFmpeg 的函数库 ,
想要正常调用 FFmpeg 库 , 需要提前将 FFmpeg 相关的 dll 动态库 拷贝到 C:\Windows\SysWOW64 目录 中 ;
拷贝过程如下 ;
如果没有拷贝上述动态库 , 则需要将 这些 dll 动态库 , 拷贝到 Qt 构建程序 的根目录中 , 否则 FFmpeg 的函数无法调用 , 进入命令行中 , 发现都是黑屏 ;
打开 Qt , 选择 " 菜单栏 / 文件 / 新建文件或项目 " 选项 ;
在 项目类型中 , 选择 " Non-Qt Project " 下的 " Plain C Application " 类型的项目 , 然后点击右下角的 " Choose " 按钮 ;
设置项目名称 " FFmpegC " , 然后将其创建到 Qt 工程的常用目录中 ;
构建系统 设置默认的 qmake 即可 ;
构建套件 选择 MSVC2015 和 MinGW , 只有这两个是 完整的 , 且是 32 位的 , 因为 FFmpeg 的函数库是 32 位的 , 只能使用 32 位编译器编译 FFmpeg 函数库 ;
项目版本控制系统 选择默认的 None 即可 ;
创建完成后 , 进入 工程页面 , 点击左下角的 电脑 按钮 , 查看配置的 " 构建套件 Kit " , 默认的 构建套件是 MSVC ;
点击左下角的 运行按钮
可以使用 MSVC 编译器编译源码 , 并运行 , 运行效果如下 :
打个断点 , 点击左下角的 调试按钮
, 可以使用 CDB 调试 上述源码 ;
将 ffmpeg-4.2.1-win32-dev 开发库 , 拷贝到 Qt 工程目录下 ,
其中包含了 头文件 和 函数库 ;
打开 .pro 配置文件 , 配置 头文件 和 函数库 , 在配置文件末尾添加 :
win32 {
INCLUDEPATH += $$PWD/ffmpeg-4.2.1-win32-dev/include
LIBS += $$PWD/ffmpeg-4.2.1-win32-dev/lib/avformat.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avcodec.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avdevice.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avfilter.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avutil.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/postproc.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/swresample.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/swscale.lib
}
完整配置文件如下 :
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.c
win32 {
INCLUDEPATH += $$PWD/ffmpeg-4.2.1-win32-dev/include
LIBS += $$PWD/ffmpeg-4.2.1-win32-dev/lib/avformat.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avcodec.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avdevice.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avfilter.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avutil.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/postproc.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/swresample.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/swscale.lib
}
在 main.c 代码中 , 引入头文件 “libavutil/avutil.h” , 然后调用头文件中的 av_version_info() 函数 获取 FFmpeg 版本号 , 得到一个 char* 字符串结果 , 将该字符串打印出来 ;
#include <stdio.h>
#include "libavutil/avutil.h"
int main()
{
printf("Hello World\n");
printf("FFmpeg version is %s\n", av_version_info());
return 0;
}
拷贝 FFmpeg 动态库 :
如果不拷贝 dll 动态库 , 上述代码 执行 是黑屏效果 ;
点击左下角的 运行按钮 , 执行结果如下 :
这里仅把 与 C 语言不同的内容说明一下 , 详细过程可参考 C 语言程序的创建和配置过程 ;
新建工程时 , 选择 " Non-Qt Project " 下的 " Plain C++ Application " 项目 ;
设置名称为 FFmpegCPP ,
构建套件 Kit 选择与 C 语言程序一样 ;
将 ffmpeg-4.2.1-win32-dev 开发库 拷贝到 Qt 中创建的 C++ 项目中 ,
配置 FFmpeg 头文件 和 函数库 到 .pro 构建脚本中 , 完整配置如下 :
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
main.cpp
win32 {
INCLUDEPATH += $$PWD/ffmpeg-4.2.1-win32-dev/include
LIBS += $$PWD/ffmpeg-4.2.1-win32-dev/lib/avformat.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avcodec.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avdevice.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avfilter.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/avutil.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/postproc.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/swresample.lib \
$$PWD/ffmpeg-4.2.1-win32-dev/lib/swscale.lib
}
在 C++ 代码中 , 包含 FFmpeg 头文件 “libavutil/avutil.h” , 并调用 av_version_info() 函数获取 FFmpeg 版本号 ;
#include <iostream>
using namespace std;
// 在 C++ 代码中导入 C 语言的头文件 都要使用这种方式导入
extern "C"{
#include "libavutil/avutil.h"
}
int main()
{
printf("Hello World\n");
// C 语言方式 控制台打印
printf("FFmpeg version is %s\n", av_version_info());
// C++ 语言方式 控制台打印
cout << "FFmpeg version is " << av_version_info() << endl;
return 0;
}
执行结果如下 :