Windows下如何编译FFmpeg

  ffmpeg一般在linux环境中使用,但是我们目前很多的开发工具是windows,为了方便在windows下调试和使用ffmpeg,我们需要再windows下面编译和使用ffpeg,本文只讲述windows下如何编译ffmpeg的内容。
  windows下编译ffmpeg有很多的方法,本文主要用MSYS2的方式来编译。其本质就是模拟一个linux的命令环境,用来编译ffmpeg

一、需要的软件下载

  在windows下编译ffmpeg,需要下载几个软件,我们将其下载在一个不带有中文名称的文件夹中。

1、下载MSYS2

官网下载地址:MSYS2
在这里插入图片描述

2、下载FFmpeg源码

ffmpeg官网上下载的源码好像不是最新的,后面编译的时候会报错,所以我们直接从github上下载5.1.2版本

在这里插入图片描述

3、下载x264源码

官网下载地址:x264, the best H.264/AVC encoder - VideoLAN
在这里插入图片描述

4、下载SDL源码(可选,在编译FFplay.exe时需要)

官网下载地址:Simple DirectMedia Layer - Homepage
在这里插入图片描述
这里下载了2.26.3版本
在这里插入图片描述

将下载的软件解压放在一个没有中文名称和空格的文件夹中,以下是我的地址路径

在这里插入图片描述

二、安装MSYS2及编译工具链

1、点击msys2-x86_64-20230718.exe并完成安装,完成后的工具如下:

在这里插入图片描述

2、修改C:\msys64\msys2_shell.cmd文件,将 rem set MSYS2_PATH_TYPE=inherit 修改成 set MSYS2_PATH_TYPE=inherit

在这里插入图片描述

3、启动MSYS2 MINGW64,依次输入以下命令行开始安装mingw64编译链和基本依赖

  • 更新环境
<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell">pacman <span style="color:#ee9900">-Sy</span>
</code></span></span>
  • 1

如果出现 clang32: signature from “Christoph Reiter (MSYS2 development key) reiter.christoph@gmail.com” is invalid
解决方法是输入以下命令,

<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell"> <span style="color:#61aeee">rm</span> <span style="color:#ee9900">-r</span> /etc/pacman.d/gnupg/
 pacman-key <span style="color:#ee9900">--init</span>
 pacman-key <span style="color:#ee9900">--populate</span> msys2
 <span style="color:#61aeee">curl</span> <span style="color:#ee9900">-O</span> http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz
 <span style="color:#61aeee">curl</span> <span style="color:#ee9900">-O</span> http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig
 pacman <span style="color:#ee9900">-U</span> <span style="color:#ee9900">--config</span> <span style="color:#669900"><</span><span style="color:#999999">(</span><span style="color:#669900">echo</span><span style="color:#999999">)</span> msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz
 pacman <span style="color:#ee9900">-Syu</span>
</code></span></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

最终结果:
在这里插入图片描述

  • 安装基本依赖库
<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell">pacman <span style="color:#ee9900">-S</span> mingw-w64-x86_64-toolchain  <span style="color:#5c6370"># mingw64编译工具链,win下的gcc,用于编译64位的库</span>
pacman <span style="color:#ee9900">-S</span> mingw-w64-i686-toolchain <span style="color:#5c6370"># 用于编译32位的库</span>
pacman <span style="color:#ee9900">-S</span> base-devel    <span style="color:#5c6370"># 一些基本的编译工具</span>
pacman <span style="color:#ee9900">-S</span> yasm nasm  gcc   <span style="color:#5c6370"># 汇编器</span>
pacman <span style="color:#ee9900">-S</span> mingw64/mingw-w64-x86_64-SDL2  <span style="color:#5c6370">#SDL2 是ffmpeg依赖的,因为没有它ffpaly不能用</span>
</code></span></span>
  • 1
  • 2
  • 3
  • 4
  • 5

安装完毕后,可以输入gcc -v查看 gcc 版本:
在这里插入图片描述

3、添加环境变量

最后需要添加环境变量。右击此电脑 -> 属性 -> 高级系统设置 -> 环境变量 -> 选择 Path (用户变量和系统变量都要)-> 编辑 -> 新建,添加编译工具链的路径:
在这里插入图片描述
注意如果 MSYS2 没有安装在 C 盘,或者使用的不是 MINGW64 的shell,那么这里需要改成对应的路径。添加环境变量这一步,是为了以后使用其他编辑器或者IDE时,能够找到 MINGW64 的编译工具链。在 MSYS2 中编译 ffmpeg 本身是不需要添加 Windows 的环境变量的。

三、编译和安装

1、新建FFmpeg-n5.1.2-install和x264-install两个文件夹,用来存放编译后安装的文件

2、打开SDL源码中的sdl2-config文件

在这里插入图片描述
修改其中的prefix路径,具体路径根据你文件所在位置确定,不能直接复制文件资源管理器中的路径,需要修改为以下格式

<span style="color:#000000"><span style="background-color:#282c34"><code>prefix=/d/worksoft/audioAndVideo/SDL2-2.26.3/x86_64-w64-mingw32
</code></span></span>
  • 1

在这里插入图片描述

3、打开FFmpeg源码目录中的configure文件

在这里插入图片描述

修改SDL2_CONFIG路径,规则同上

<span style="color:#000000"><span style="background-color:#282c34"><code>SDL2_CONFIG="/d/worksoft/audioAndVideo/SDL2-2.26.3/x86_64-w64-mingw32/bin/sdl2-config"
</code></span></span>
  • 1

在这里插入图片描述

4、编译x264

在放置文件的目录下新建build_x264.sh文件,内容如下:

<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell"><span style="color:#ee9900">#!/bin/sh</span>
<span style="color:#5c6370">#进入执行脚本所在目录</span>
<span style="color:#ee9900">basepath</span><span style="color:#669900">=</span><span style="color:#ee9900"><span style="color:#ee9900">$(</span><span style="color:#669900">cd</span> `dirname $0`<span style="color:#999999">;</span><span style="color:#669900">pwd</span><span style="color:#ee9900">)</span></span>
<span style="color:#669900">echo</span> <span style="color:#ee9900">${basepath}</span>
 
<span style="color:#5c6370">#进入h264源码目录</span>
<span style="color:#669900">cd</span> <span style="color:#ee9900">${basepath}</span>/x264-master   <span style="color:#5c6370"># 根据路径名称自行修改</span>
<span style="color:#669900">pwd</span>
<span style="color:#5c6370">#配置编译参数</span>
./configure <span style="color:#ee9900">--prefix</span><span style="color:#669900">=</span><span style="color:#ee9900">${basepath}</span>/x264-install --enable-shared
<span style="color:#5c6370">#开始8线程编译</span>
<span style="color:#61aeee">make</span> <span style="color:#ee9900">-j8</span>
<span style="color:#5c6370">#将编译后的文件拷贝到--prefix参数配置目录</span>
<span style="color:#61aeee">make</span> <span style="color:#61aeee">install</span>
</code></span></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在MSYS2 MINGW64中执行如下命令,等待x264编译完成

<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell"><span style="color:#669900">cd</span> /d/worksoft/audioAndVideo
./build_x264.sh
</code></span></span>
  • 1
  • 2

编译完成后,在x264-install目录下就可以看到编译后的文件
在这里插入图片描述

5、编译ffmpeg

在在放置文件的目录下新建build_ffmpeg.sh文件,内容如下:

<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell"><span style="color:#ee9900">#!/bin/sh</span>
<span style="color:#5c6370">#进入执行脚本所在目录</span>
<span style="color:#ee9900">basepath</span><span style="color:#669900">=</span><span style="color:#ee9900"><span style="color:#ee9900">$(</span><span style="color:#669900">cd</span> `dirname $0`<span style="color:#999999">;</span><span style="color:#669900">pwd</span><span style="color:#ee9900">)</span></span>
<span style="color:#669900">echo</span> <span style="color:#ee9900">${basepath}</span>

<span style="color:#5c6370">#进入ffmpeg源码目录</span>
<span style="color:#669900">cd</span> <span style="color:#ee9900">${basepath}</span>/FFmpeg-n5.1.2  <span style="color:#5c6370"># 根据路径名称自行修改</span>
<span style="color:#669900">pwd</span>
<span style="color:#5c6370">#指定PKG_CONFIG_PATH变量,告知编译器x264库的路径</span>
<span style="color:#669900">export</span> <span style="color:#ee9900">PKG_CONFIG_PATH</span><span style="color:#669900">=</span><span style="color:#ee9900">${PKG_CONFIG_PATH}</span><span style="color:#669900">:</span><span style="color:#ee9900">${basepath}</span>/x264-install/lib/pkgconfig
<span style="color:#669900">echo</span> <span style="color:#ee9900">${PKG_CONFIG_PATH}</span>
<span style="color:#5c6370">#配置编译参数</span>
./configure <span style="color:#ee9900">--prefix</span><span style="color:#669900">=</span><span style="color:#ee9900">${basepath}</span>/FFmpeg-n5.1.2-install <span style="color:#999999">\</span>
--enable-gpl <span style="color:#999999">\</span>
--enable-debug <span style="color:#999999">\</span>
--enable-libx264 <span style="color:#999999">\</span>
--disable-static <span style="color:#999999">\</span>
--enable-shared <span style="color:#999999">\</span>
--enable-sdl2 <span style="color:#999999">\</span>
--enable-ffplay <span style="color:#999999">\</span>
--enable-ffprobe <span style="color:#999999">\</span>
--enable-ffmpeg <span style="color:#999999">\</span>
--disable-vulkan <span style="color:#999999">\</span>
--disable-doc  <span style="color:#999999">\</span>
--disable-htmlpages  <span style="color:#999999">\</span>
--disable-manpages  <span style="color:#999999">\</span>
--disable-podpages  <span style="color:#999999">\</span>
--disable-txtpages <span style="color:#999999">\</span>
--extra-cflags<span style="color:#669900">=</span>-l<span style="color:#ee9900">${basepath}</span>/x264-install/include <span style="color:#999999">\</span>
--extra-ldflags<span style="color:#669900">=</span>-L<span style="color:#ee9900">${basepath}</span>/x264-install/lib
 
 
<span style="color:#5c6370">#开始8线程编译</span>
<span style="color:#61aeee">make</span> <span style="color:#ee9900">-j8</span>
<span style="color:#5c6370">#将编译后的文件拷贝到--prefix参数配置目录</span>
<span style="color:#61aeee">make</span> <span style="color:#61aeee">install</span>
</code></span></span>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

在MSYS2 MINGW64中执行如下命令,等待编译完成

<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell">./build_ffmpeg.sh
</code></span></span>
  • 1
  • 如果出现如下错误:
    在这里插入图片描述
    解决方案:
    修改FFmpeg-n5.1.2\libavcodec\x86\mathops.h文件的三个函数,修改对应的函数的内容如下:
<span style="color:#000000"><span style="background-color:#282c34"><code class="language-c"><span style="color:#98c379">#<span style="color:#c678dd">define</span> MULL MULL</span>
<span style="color:#c678dd">static</span> av_always_inline av_const <span style="color:#c678dd">int</span> <span style="color:#61aeee">MULL</span><span style="color:#999999">(</span><span style="color:#c678dd">int</span> a<span style="color:#999999">,</span> <span style="color:#c678dd">int</span> b<span style="color:#999999">,</span> <span style="color:#c678dd">unsigned</span> shift<span style="color:#999999">)</span>
<span style="color:#999999">{</span>
    <span style="color:#c678dd">int</span> rt<span style="color:#999999">,</span> dummy<span style="color:#999999">;</span>
    <span style="color:#c678dd">if</span> <span style="color:#999999">(</span><span style="color:#61aeee">__builtin_constant_p</span><span style="color:#999999">(</span>shift<span style="color:#999999">)</span><span style="color:#999999">)</span>
    <span style="color:#61aeee">__asm__</span> <span style="color:#999999">(</span>
        <span style="color:#669900">"imull %3               \n\t"</span>
        <span style="color:#669900">"shrdl %4, %%edx, %%eax \n\t"</span>
        <span style="color:#669900">:</span><span style="color:#669900">"=a"</span><span style="color:#999999">(</span>rt<span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#669900">"=d"</span><span style="color:#999999">(</span>dummy<span style="color:#999999">)</span>
        <span style="color:#669900">:</span><span style="color:#669900">"a"</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#669900">"rm"</span><span style="color:#999999">(</span>b<span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#669900">"i"</span><span style="color:#999999">(</span>shift <span style="color:#669900">&</span> <span style="color:#98c379">0x1F</span><span style="color:#999999">)</span>
    <span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#c678dd">else</span>
        <span style="color:#61aeee">__asm__</span> <span style="color:#999999">(</span>
            <span style="color:#669900">"imull %3               \n\t"</span>
            <span style="color:#669900">"shrdl %4, %%edx, %%eax \n\t"</span>
            <span style="color:#669900">:</span><span style="color:#669900">"=a"</span><span style="color:#999999">(</span>rt<span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#669900">"=d"</span><span style="color:#999999">(</span>dummy<span style="color:#999999">)</span>
            <span style="color:#669900">:</span><span style="color:#669900">"a"</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#669900">"rm"</span><span style="color:#999999">(</span>b<span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#669900">"c"</span><span style="color:#999999">(</span><span style="color:#999999">(</span>uint8_t<span style="color:#999999">)</span>shift<span style="color:#999999">)</span>
        <span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#c678dd">return</span> rt<span style="color:#999999">;</span>
<span style="color:#999999">}</span>

<span style="color:#98c379">#<span style="color:#c678dd">define</span> NEG_SSR32 NEG_SSR32</span>
<span style="color:#c678dd">static</span> <span style="color:#c678dd">inline</span>  int32_t <span style="color:#61aeee">NEG_SSR32</span><span style="color:#999999">(</span> int32_t a<span style="color:#999999">,</span> int8_t s<span style="color:#999999">)</span><span style="color:#999999">{</span>
    <span style="color:#c678dd">if</span> <span style="color:#999999">(</span><span style="color:#61aeee">__builtin_constant_p</span><span style="color:#999999">(</span>s<span style="color:#999999">)</span><span style="color:#999999">)</span>
    <span style="color:#61aeee">__asm__</span> <span style="color:#999999">(</span><span style="color:#669900">"sarl %1, %0\n\t"</span>
         <span style="color:#669900">:</span> <span style="color:#669900">"+r"</span> <span style="color:#999999">(</span>a<span style="color:#999999">)</span>
         <span style="color:#669900">:</span> <span style="color:#669900">"i"</span> <span style="color:#999999">(</span><span style="color:#669900">-</span>s <span style="color:#669900">&</span> <span style="color:#98c379">0x1F</span><span style="color:#999999">)</span>
    <span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#c678dd">else</span>
        <span style="color:#61aeee">__asm__</span> <span style="color:#999999">(</span><span style="color:#669900">"sarl %1, %0\n\t"</span>
               <span style="color:#669900">:</span> <span style="color:#669900">"+r"</span> <span style="color:#999999">(</span>a<span style="color:#999999">)</span>
               <span style="color:#669900">:</span> <span style="color:#669900">"c"</span> <span style="color:#999999">(</span><span style="color:#999999">(</span>uint8_t<span style="color:#999999">)</span><span style="color:#999999">(</span><span style="color:#669900">-</span>s<span style="color:#999999">)</span><span style="color:#999999">)</span>
        <span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#c678dd">return</span> a<span style="color:#999999">;</span>
<span style="color:#999999">}</span>

<span style="color:#98c379">#<span style="color:#c678dd">define</span> NEG_USR32 NEG_USR32</span>
<span style="color:#c678dd">static</span> <span style="color:#c678dd">inline</span> uint32_t <span style="color:#61aeee">NEG_USR32</span><span style="color:#999999">(</span>uint32_t a<span style="color:#999999">,</span> int8_t s<span style="color:#999999">)</span><span style="color:#999999">{</span>
    <span style="color:#c678dd">if</span> <span style="color:#999999">(</span><span style="color:#61aeee">__builtin_constant_p</span><span style="color:#999999">(</span>s<span style="color:#999999">)</span><span style="color:#999999">)</span>
    <span style="color:#61aeee">__asm__</span> <span style="color:#999999">(</span><span style="color:#669900">"shrl %1, %0\n\t"</span>
         <span style="color:#669900">:</span> <span style="color:#669900">"+r"</span> <span style="color:#999999">(</span>a<span style="color:#999999">)</span>
         <span style="color:#669900">:</span> <span style="color:#669900">"i"</span> <span style="color:#999999">(</span><span style="color:#669900">-</span>s <span style="color:#669900">&</span> <span style="color:#98c379">0x1F</span><span style="color:#999999">)</span>
    <span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#c678dd">else</span>
        <span style="color:#61aeee">__asm__</span> <span style="color:#999999">(</span><span style="color:#669900">"shrl %1, %0\n\t"</span>
               <span style="color:#669900">:</span> <span style="color:#669900">"+r"</span> <span style="color:#999999">(</span>a<span style="color:#999999">)</span>
               <span style="color:#669900">:</span> <span style="color:#669900">"c"</span> <span style="color:#999999">(</span><span style="color:#999999">(</span>uint8_t<span style="color:#999999">)</span><span style="color:#999999">(</span><span style="color:#669900">-</span>s<span style="color:#999999">)</span><span style="color:#999999">)</span>
        <span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#c678dd">return</span> a<span style="color:#999999">;</span>
<span style="color:#999999">}</span>
</code></span></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

然后重新编译
编译完成后的结果如下:
在这里插入图片描述

6、复制一份x264-install\bin下面的libx264-164.dll到FFmpeg-n5.1.2-install\bin下面,否则打开的时候会报找不到

四、ffmpeg的Hello World程序

在 ffmpeg 安装路径下,打开 share\ffmpeg\examples ,可以看到 ffmpeg 的示例程序,它们也可以在 ffmpeg 的在线 API 文档 中查看到。

其中的 avio_reading.c 相当于 ffmpeg 的 Hello World,它会读取一个媒体文件的元数据信息并打印显示。
另外建一个文件夹test_hello_world,将avio_reading.c复制过去,然后用在 MYSY2 中打开这个目录,使用 gcc 命令编译。
命令如下:

<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell"><span style="color:#669900">cd</span> /d/worksoft/audioAndVideo/FFmpeg-n5.1.2-install/share/ffmpeg/examples
<span style="color:#61aeee">mkdir</span> test_hello_world
<span style="color:#61aeee">cp</span> avio_reading.c test_hello_world/

<span style="color:#669900">cd</span> test_hello_world
gcc avio_reading.c <span style="color:#ee9900">-o</span> <span style="color:#669900">test</span> <span style="color:#999999">\</span>
-I<span style="color:#669900">"D:/worksoft/audioAndVideo/FFmpeg-n5.1.2-install/include/"</span> <span style="color:#999999">\</span>
-L<span style="color:#669900">"D:/worksoft/audioAndVideo/FFmpeg-n5.1.2-install/bin/"</span> <span style="color:#999999">\</span>
<span style="color:#ee9900">-lavcodec</span> <span style="color:#ee9900">-lavformat</span> <span style="color:#ee9900">-lavutil</span>

</code></span></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

编译完毕后,将在当前文件夹下生成可执行文件test.exe。
在这里插入图片描述

在 shell 中运行程序之前,需要将两个库的安装目录添加到环境变量 PATH (这是MSYS2 的环境变量,不是 Windows 系统的)。

<span style="color:#000000"><span style="background-color:#282c34"><code class="language-shell"><span style="color:#669900">export</span> <span style="color:#ee9900"><span style="color:#98c379">PATH</span></span><span style="color:#669900">=</span><span style="color:#98c379">$PATH</span>:/d/worksoft/audioAndVideo/x264_install/bin:/d/worksoft/audioAndVideo/FFmpeg-n5.1.2-install/bin

</code></span></span>
  • 1
  • 2

如果不执行export命令的话,那么运行test.exe时就无法链接到动态库,更令人困扰的是不会弹出任何提示,所以一定记得添加。当然如果你觉得每次打开都要运行太麻烦,也可以将这条命令添加到 你的安装位置/msys64/etc/profile 文件的末尾,这个文件和 Linux 下的/etc/profile文件作用是类似的。

找一个视频文件,运行测试效果如下:
在这里插入图片描述

五、踩过的坑

1、安装MSYS2的时候,如果执行了sed -i “s#mirror.msys2.org/#mirrors.ustc.edu.cn/msys2/#g” /etc/pacman.d/mirrorlist*,在执行pacman -Sy时会报错,还了各个ffmpeg版本无法解决

2、从ffmpeg官网下载的文件源码内容和github上的不一样

3、在编译ffmpeg的时候,如果不加

–disable-doc
–disable-htmlpages
–disable-manpages
–disable-podpages
–disable-txtpages
这几个,会在make install的时候报错,导致无法安装完成

后记
  个人总结,欢迎转载、评论、批评指正


参考资料:
Windows下FFmpeg库编译安装指南
ffmpeg库编译安装及入门指南(Windows篇)- 2022年底钜献




Windows下如何编译FFmpeg_windows编译ffmpeg-CSDN博客

Download FFmpeg 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值