最近项目需要,使用了 ffmpeg 做摄像头视频采集和串流。这几天有点时间,打算把相关的一些知识记录分享一下。
在撰写本文时,我又在另外一台电脑上把 ffmpeg 重新安装了一遍,所以绝对真实靠谱!如果你觉得文章写得还不错,敬请点个赞支持一下,十分感谢~
ffmpeg 简介
ffmpeg是一套跨平台的,用于音视频录制、转换、流化等操作的完善的解决方案,它是业界最负盛名的开源音视频框架之一。许多软件都是基于ffmpeg开发的,如格式工厂、各种xx影音等。
ffmpeg 是一套开源库以及命令行工具的集合,用户既可以使用命令行直接对音视频进行操作(CLI),也可以调用其开源库进行个性化的功能开发(SDK)。
如果要在自己的程序中使用 ffmpeg ,那么使用它的 SDK 是最好的选择。当前 ffmpeg 包含以下几个库:
- libavcodec : 编/解码
- libavfilter : 帧级操作(如添加滤镜)
- libavformat : 文件 I/O 和 封装/解封装
- libavdevice : 设备视频文件的封装/解封装
- libavutil : 通用工具集合
- libswresample : 音频重采样、格式处理、混音等
- libpostproc : 预处理
- libswscale : 色彩处理和缩放
ffmpeg 库在 Windows 下的安装
这个项目大部分是在 Linux 开发板上做的,Windows 上占一小部分。虽然如此,在 Windows 上安装 ffmpeg 的步骤一点都没法省。
ffmpeg 目前不提供预编译的库文件,而是需要自己下载源码并编译。看网上说 Windows 下编译 ffmpeg 非常麻烦,我想应该是“找到好用的教程”比较麻烦。本文使用 MSYS2 来编译 ffmpeg ,许多问题可以迎刃而解!
环境准备
在 Windows 下,编译需要做的准备如下:
- 安装并配置 MYSY2
- 安装 git (可选)
- ffmpeg 源码
- x264 源码(可选)
本节只讲述 MSYS2 的安装和配置和源码的下载。git 可根据需要自行选择安装。
安装 MSYS2 及编译工具链
MSYS2 是 Windows 下的一组编译套件,它可以在 Windows 系统中模拟 Linux 下的编译环境,如使用 shell 运行命令、使用 pacman 安装软件包、使用 gcc (MinGW) 编译代码等。简单来说,使用 MSYS2 ,你可以通过在 Linux 下非常熟悉的各种命令,来编译 Windows 下的软件。
官网描述:It provides a native build environment, based on open source software, and makes you feel right at home when you are already comfortable with Linux.
扫描二维码关注公众号,回复: 14609046 查看本文章
MSYS2 的安装也非常省心,只需要到 MSYS2 官网 下载.exe
安装包,管理员身份运行安装即可。
注意安装盘必须是NTFS,路径要全使用 ACSII 字符,不能有空格。建议就安装在默认位置,如果不想装在 C 盘,就直接改下盘符,装在其他盘的根目录。
安装完毕后,开始菜单里就会有下面的程序:
点击它们就会启动一个 shell 窗口,Just like on Linux ! 这个 shell 程序默认是 Mintty,类似 Linux 系统中的 bash shell。MSYS2 支持多个编译器工具链,它们的环境是独立的(可以去安装文件夹查看),这里选择启动 MINGW64 (如果你也是64位系统的话)。
首先为了提高下载速度,将下载源换成中科大的:
sed -i "s#mirror.msys2.org/#mirrors.ustc.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*
pacman -Sy
然后安装mingw64编译链和基本的依赖:
pacman -S mingw-w64-x86_64-toolchain # mingw64编译工具链,win下的gcc
pacman -S base-devel # 一些基本的编译工具
pacman -S yasm nasm # 汇编器
安装完毕后,可以输入gcc -v
查看 gcc 版本:
最后需要添加环境变量。右击此电脑 -> 属性 -> 高级系统设置 -> 环境变量 -> 选择 Path
(用户变量和系统变量都要)-> 编辑 -> 新建,添加编译工具链的路径:
注意如果 MSYS2 没有安装在 C 盘,或者使用的不是 MINGW64 的shell,那么这里需要改成对应的路径。
添加环境变量这一步,是为了以后使用其他编辑器或者IDE时,能够找到 MINGW64 的编译工具链。在 MSYS2 中编译 ffmpeg 本身是不需要添加 Windows 的环境变量的。
ffmpeg 源码下载
在 ffmpeg 官网 下载源码,目前最新的版本是 5.1.2 。注意不要下载成 executable files 了,那个是可以直接运行的 CLI 程序。
你也可以直接下载 snapshot 版本,不过我个人更愿意下载带版本数字的。试想两年之后,谁能知道你电脑里的 snapshot 是何年何月的 snapshot 呢?
三个 download 都可以,只是压缩包格式不一样:
下载后解压到一个好找的文件夹即可。
x264 源码下载
ffmpeg 提供了相当多的外部库支持,但是如果要使用的话需要自己编译外部库。因为项目需要用到视频编码,所以此处加入 x264 库。
libx264 由 VideoLAN 组织所发布,它是 H.264 的一套性能较好的软编码器实现(不包括解码器)。H.264 (AVC) 是当前较常用的视频编码,目前 H.264 的继任者 H.265 (HEVC) 也渐趋成熟, VideoLAN 也有一套实现 libx265 。不过 libx265 的编译方式与 libx264 有所区别,目前我还没仔细研究。
官方建议使用 git 下载源码(下载压缩包再解压应该也是一样的):
git clone https://code.videolan.org/videolan/x264.git
编译和安装
将所有源码放到同一文件夹下便于管理,我把它们都统一放在一个叫 ffmpeg 的文件夹下。然后再建立各自的 install 文件夹存储编译好的库(当然你也可以选择其他任何地方的文件夹)。
为了方便,将编译的命令写成脚本 build-x264.sh
和 build-ffmpeg.sh
。当前文件夹的结构如下(源码文件夹名称被我修改过了):
编译 x264 库
build-x264.sh
脚本内容如下:
#!/bin/sh
basepath=$(cd `dirname $0`;pwd)
echo ${basepath}
cd ${basepath}/x264-src # 根据路径名称自行修改
pwd
./configure --prefix=${basepath}/x264_install --enable-shared
make -j8
make install
注意第一行必须是 #!/bin/sh
,才能被 MSYS2 的 shell 识别为可执行脚本。(亲测在 MSYS2 中chmod
命令没有效果)
这几条命令中最重要的就是./configure
命令,它的参数会指导编译器应该如何编译代码。这里 --prefix
参数指定了编译好的库文件的安装路径,可以自己任意指定。 --enable-shared
代表编译动态库。如果你需要静态库,那么需要加入 -enable-static
参数。
此外,make 命令的-j
参数是指并行编译的线程数,可以根据你的 CPU 核数自行确定。
可以在源码文件夹下,通过
./configure --help
命令查看所有可选参数。
在 MSYS2 的 shell 中,打开源码所在文件夹,并执行脚本:
cd /d/repos/ffmpeg
./build-x264.sh
注意 MSYS2 中文件路径的写法,是以/d
代表 D 盘,类似 Linux 的风格。
不出意外的话,等待片刻后就会在 x264_install
路径下看到编译好的库。其中 bin/libx264-164.dll
文件就是x264的动态库文件。
如果出现错误,可以先单独执行 .\configure
命令,然后再执行 make
,逐步查找错误原因。
编译 ffmpeg 库
build-ffmpeg.sh
脚本内容如下:
#!/bin/sh
basepath=$(cd `dirname $0`;pwd)
echo ${basepath}
cd ${basepath}/ffmpeg-5.1.2-src
pwd
export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/d/repos/ffmpeg/x264_install/lib/pkgconfig
echo ${PKG_CONFIG_PATH}
./configure --prefix=${basepath}/ffmpeg_5.2.1_install \
--enable-gpl --enable-libx264 --disable-static --enable-shared \
--extra-cflags=-l${basepath}/x264_install/include --extra-ldflags=-L${basepath}/x264_install/lib
make -j8
make install
使用的命令与libx264
类似,也是先 configure
再 make
。如果需要添加 x264 支持的话,需要注意以下几点:
- 加入
--enable-libx264
参数 - 指定 PKG_CONFIG_PATH 变量,告知编译器 x264 库的路径
- 指定 x264 库的头文件包含路径及动态库链接的路径
ffmpeg 可自定义的编译参数非常多,有需要可自行研究。
然后同样也是执行脚本即可:
cd /d/repos/ffmpeg
./build-ffmpeg.sh
ffmpeg 代码量较大,可能会编译比较久,多线程 make 可加快编译速度。我使用make -j8
大约花了七八分钟。
编译完成后,就可以在 ffmpeg_5.2.1_install 路径下看到库文件了。其中 bin 下的一堆 dll 就是动态库文件。
现在 ffmpeg 的 SDK 就任你调用了!下一节我们来试试调用 ffmpeg 编写程序。
ffmpeg 的 Hello World 程序
在 ffmpeg 安装路径下,打开 share\ffmpeg\examples ,可以看到 ffmpeg 的示例程序,它们也可以在 ffmpeg 的在线 API 文档 中查看到。
其中的 avio_reading.c
相当于 ffmpeg 的 Hello World,它会读取一个媒体文件的元数据信息并打印显示。
另外建一个文件夹,将avio_reading.c
复制过去,然后用在 MYSY2 中打开这个目录,使用 gcc 命令编译。
gcc命令如下:
gcc avio_reading.c -o test \
-I"D:/repos/ffmpeg/ffmpeg_5.2.1_install/include/" \
-L"D:/repos/ffmpeg/ffmpeg_5.2.1_install/bin/" \
-lavcodec -lavformat -lavutil
编译完毕后,将在当前文件夹下生成可执行文件test.exe
。
注意在 shell 中运行程序之前,需要将两个库的安装目录添加到环境变量 PATH (这是MSYS2 的环境变量,不是 Windows 系统的)。
export PATH=$PATH:/d/repos/ffmpeg/x264_install/bin:/d/repos/ffmpeg/ffmpeg_5.2.1_install/bin
如果不执行export命令的话,那么运行test.exe
时就无法链接到动态库,更令人困扰的是不会弹出任何提示,所以一定记得添加。当然如果你觉得每次打开都要运行太麻烦,也可以将这条命令添加到 你的安装位置/msys64/etc/profile
文件的末尾,这个文件和 Linux 下的/etc/profile
文件作用是类似的。
运行测试效果如下:
至此,我们迈出了使用 ffmpeg 库的第一步——也是一大步!
由于 gcc 的编译命令很长,重复手打很不方便,所以我一般会使用 vscode+cmake 的方式来做开发。不过这个配置又是较为麻烦的一件事,限于篇幅本文不再详述,感兴趣的读者可自行查阅资料。基本上只要注意把 gcc 的命令参数转换到 CmakeLists.txt 文件里,并注意终端的环境变量配置即可。
入门资料
ffmpeg 我也是最近才开始用,官方对 SDK 没有详细的入门教程,仅提供了 Doxygen 风格的 API 文档供查询。所以这里贴两个我觉得很好的入门帖,供与我一样刚刚入门的朋友参考。
首先是 Github 上的一篇tutorial:ffmpeg-libav-tutorial ,篇幅不长,读完可以对音视频有一个基本的认知。
然后是已故的音视频领域先驱雷霄骅(雷神)的博客 。需要注意的是现在的 ffmpeg 相比雷神当年使用的版本已经有了许多变化,使用雷神的源代码有时还需要修改。(斯人已逝,生者如斯!)
其他较为系统的参考资料我还没有找到,基本就是根据需要去百度or谷歌。有时 ffmpeg 官网也能派上一些用场,可以多翻翻。
后记
MSYS2 真是个好东西!
下一篇将讨论 ffmpeg 在 Linux 上的安装以及交叉编译的问题。