Windows10使用MSYS2和VS2019编译FFmpeg详解

1 环境准备

1.1 安装Visual Studio 2019

这个步骤相对比较简单,不再详细说明。

1.2 安装msys2

首先需要安装msys2环境以及相关的编译依赖项, 官方网址为:

https://www.msys2.org/

在官网下载好 安装程序后,直接按照提示安装即可。

安装好后需要将下载库的地址更换为国内源,否则下载速度可能会极慢,甚至失败。配置文件位于:C:\msys64\etc\pacman.d,分别将mirrorlist.mingw32、mirrorlist.mingw64、mirrorlist.msys三个配置文件的首选Server的地址,更换为清华大学及中科大镜像

运行C:\msys64\msys2.exe,在命令行通过 pacman -Syu 一键安装和升级所有的库。

在编译过程中可能会遇到还缺少某些其他库的问题, 直接根据提示安装就可以。比如可能还需要安装的库如下:

1.3 配置VC环境

首先,为了使msys2访问windows PATH环境变量,需要在msys2安装目录中找到脚本文件msys2_shell.cmd,使用任何编辑器将其打开,将rem set MSYS2_PATH_TYPE=inherit修改为set MSYS2_PATH_TYPE=inherit,即删除rem注释继承系统环境变量。

其次,在windows开始菜单中找到Visual Studio 2019,右击“x64_x86 Cross Tools Command Prompt For VS 2019”,选择以管理员身份运行(最好以管理员权限运行,否则后续在执行make install 指令时可能会发生权限不足的问题,切记)。

关于几个选项的选择

如果是32位Windows, 想编译32位的FFmpeg, 建议选择:

x86 Native Tools Command Prompt

;

如果是64位Windows, 想编译64位的FFmpeg, 建议选择:

x64 Native Tools Command Prompt

如果是32位Windows, 想编译64位的FFmpeg, 建议选择:

x86_x64 Cross Tools Command Prompt

如果是64位Windows, 想编译32位的FFmpeg, 建议选择:

x64_x86 Cross Tools Command Prompt

具体请参见微软官网:
Use the Microsoft C++ toolset from the command line

我的操作系统是Win10 64位,需要编译的是32位的FFmpeg,所以选择的是:

x64_x86 Cross Tools Command Prompt For VS 2019

然后,cd到C:\msys64,32位方式运行msys2_shell.cmd(msys2_shell.cmd -mingw64会以64位方式运行msys2),启用MinGW运行环境,此时在弹出的msys2命令窗口中输入cl,输出MSVC信息,则说明编译器配置成功。

在msys窗口中分别输入which cl和which link查看当前编译器和链接器的位置:

可以看到cl编译器的位置是正确的,link链接器的位置是不正确的,这是因为目前找到的链接器默认为MSYS的链接器,MSYS默认也携带了一个名为link.exe的链接器(在:msys安装目录/usr/bin/link.exe),它与Visual Studio 自带的link.exe发生了冲突,这会影响之后构建系统的构建(在我的编译过程中就是因为忽略了这个问题,导致编译过程异常缓慢,而且生成的dll文件无法使用),我们这里一定要确定使用的是Visual Studio自带的link.exe。找到MSYS自带的link.exe, 将它改成别的名字,比如我将其重命名为link.exe_back。再次输入which link:

可以看到link.exe已经为Visual Studio目录下link.exe。

2 FFMPEG编译

2.1 源码下载

源码可以由
https://github.com/FFmpeg/FFmpeg/tags

FFmpeg官网
下载,如本人下载的是最新版的4.3版本。

2.2 编译依赖库

2.2.1  编译SDL

首先从github上获取SDL源码,命令如下:

需要注意的是,SDL现在已经发布了3.0版本,而ffmpeg目前只能用SDL2版本,所以在拉取代码后,需要切换到2.30.0这个版本。

下载好 SDL2 源码后,我们需要使用 CMake 为其生成VS工程,所以我们首先到这里
下载CMake
,并将其安装到Windows系统上。之后打开 CMake-GUI,在 CMake-GUI 中指定SDL2源码所在路径以及编译后的输出路径,随后执行Configure,随后配置如下

随后保持默认配置,Generate VS2019工程。

有了VS工程,可以通过VS2019来编译SDL了。编译好的SDL会保存到指定输出目录的Release或Debug目录下,而我们希望输出的路径则是/usr/local/sdl2/lib,需要在指定输出目录下创建 lib 目录,并将SDL2.lib和SDL2.dll文件拷贝到lib目录下。同时在lib目录下创建 pkgconfig目录,将sdl2.pc文件拷贝到该目录中。此外,我们还要修改 sdl2.pc 中的内容,将其中的库路径修改为指定的输出路径,最终完整的目录结构如下所示:

2.2.2 编译x264

与SDL一样我们也要先获取其源码,可以通过下面的命令获取x264源码:

源码获取到后,可以直接在MSYS2环境下编译出Windows下可用的动态库,具体步骤如下:

通过上面的命令就可以将x264编译出来了。x264编译好后,其输出的目录结构与SDL2是一样的,在/usr/local/x264中包括了include、lib、bin等目录。要特别强调的一点是,我们需要将lib目录下的libx264.dll.lib文件名修改为libx264.lib,否则ffmpeg编译时会报 “无法找到该库” 的错误。

2.2.3 编译fdk-aac

fdk-aac的编译与SDL类似,它同样要使用CMake生成VS工程文件,之后再通过VS编译该库。首先,通下面的的命令获取fdk-aac源码:

之后,通过CMake生成VS工程文件,具体执行步骤请参考 SDL 生成 VS 工程的步骤,这里就不再重复了。

接下来,使用VS2019编译fdk-aac,编译好的库同要会被放到Release或Debug目录下,因此我们必须像处理SDL库一样,需要手工组织fdk-aac的输出目录树。至此fdk-aac就算编译好了。

在编译fdk-aac时有个特殊情况,就是使用CMake的方式无法产生include头文件(这也有可能是我哪块执行的不对)。为了解决这个问题,又用MSYS2+mingw的方式重新编译了一遍fdk-aac,这种方式是可以生成include头文件的,然后将生成的头文件手动拷贝到了/usr/local/fdk-aac目录下即可。

2.2.4 编译x265

首先下载x265源码

查询VS2019 cmake路径查询VS2019 cmake路径,执行whereis cmake

编辑文件/c/work/Opensource/ffmpegbuild/x265/build/msys-cl/make-Makefiles.sh,修改其中cmake.exe为VC版绝对路径,否则会使用默认msys2中的cmake,即将:

修改为:

进入源码目录,执行以下3个命令完成编译

执行nmake install之后可见x265被编译至C:/Program Files (x86)/x265/目录,我们需要将其复制至msys2的/usr/local/目录,并修改相应的x256.pc文件中的路径

2.2.5 ffmpeg使用编译好的库

首先,我们要设置环境变量PKG_CONFIG_PATH,通过它告诉FFmpeg上述几个库从哪儿可以找到,具体的设置方法如下:

在msys2窗口运行命令pacman -S vim,安装vim,vim ~/.bashrc编辑该文件,在~/.bashrc中设置环境变量

然后执行命令source ~/.bashrc让环境变量生效。四个库pkgconfig配置文件内容如下:

2.3 编译ffmpeg

进入到ffmpeg源码解压目录,执行./configure –help即可查看所有支持的编译参数:

可以看到,原生支持的编译参数有很多,我们这里只关注下列部分,通过对下列参数的配置即可完成裁剪功能。

简单介绍一下上面的几个选项:


  • encoder:

    对应的就是编码器,比如需要将mp3格式转换成aac格式,在转换后就必然会用到aac格式的编码器;

  • decoder:

    对应的就是解码器,同上,如果要转换成aac格式,就必须先要将mp3格式进行解码,这就会用到mp3格式的解码器。

  • muxer:

    对应的就是封装器,主要用于生成最终的封装格式,不同的音视频格式都有其固定的文件内容格式,方便播放器对其进行识别和解析。

  • demuxer:

    对应的就是解封装器,比如一个MP4封装格式可以同时容纳H264编码格式的视频和AAC编码格式的音频,如果要取出其中的音频,就需要根据一定的规则去查找音频所在的流。

  • protocol:

    文件协议,FFmpeg 不仅可以支持本地音视频文件的读取和写入,也可以支持网络流媒体的读取和写入,比如你想在本地观看一个网络电视,那么你可以在FFmpeg中传入这个网络电视的http/rtsp/rtmp地址,这样就可以实现本地播放了。

  • parser:

    解析并填充内部数据结构,如:AVCodecParser, 这个和decoder 一般是搭配使用的。

这里列出的是一些常用的编译选项,完整的编译选项请参考:附录一:《FFmpeg 编译参数总结》。

本人在编译时使用如下编译选项:

其中增加最后一个配置选项–disable-debug,是因为在没有这个选项的情况下,编译会卡死在生成avcodec.dll库时,提示“正在创建库 libavcodec/avcodec.lib 和对象 libavcodec/avcodec.exp”,该
文章
也遇到这个问题,但是微软官方也没有给出解决方案,不清楚是不是只有在特定版本的VS2019(本人为community版本)中才能复现该问题,所以暂时增加–disable-debug取消调试信息生成。

之后执行make命令进行编译。在编译过程中,假如出现如下错误[error C2065: “slib”: 未声明的标识符]:


那么需要修改fftools/cmdutils.c源码文件, 将第1153行注释掉,原因是CC_IDENT标识未定义引起的, 如下所示:

后续编译过程中遇见类似的编译错误,请按相同办法处理。编译完成后执行make install,将会将可执行程序、库文件、头文件等安装到指定目录。

至此编译完成,后续会介绍通过vcpkg直接安装ffmpeg的方法以及一个基于ffmpeg的简单播放器实例。

附录一:FFmpeg 编译参数汇总

1.1 Help options 帮助选项

1.2 Standard options 标准选项

1.3 Licensing options 证书选项

1.4 Configuration options 配置选项

1.5 Program options 程序选项

1.6 Documentation options 文档选项

1.7 Component options 组件选项

1.8 Individual component options 独立组件选项

1.9 External library support 扩展库支持

使用以下任何选项将允许 FFmpeg 链接到相应的外部库。 如果满足所有其他依赖项并且未明确禁用它们,则依赖于该库的所有组件都将启用。 例如。 –enable-libopus 将启用与 libopus 的链接并允许构建 libopus 编码器,除非使用 –disable-encoder=libopus 明确禁用它。

请注意,只有系统库会被自动检测。 所有其他外部库必须显式启用。

另请注意,以下帮助文本描述了库本身的用途,并非它们的所有功能都必须由 FFmpeg 使用。

以下库提供各种硬件加速功能:

1.10 Toolchain options 工具链选项

1.11 Advanced options 高级选项

1.12 Optimization options 优化选项

1.13 开发人员选项

本博文部分内容参考如下文章,特此感谢:

https://www.cnblogs.com/yongdaimi/p/16619804.html

https://juejin.cn/post/7076719206573539336

未经允许不得转载:大白鲨游戏网 » Windows10使用MSYS2和VS2019编译FFmpeg详解