如何为 Windows 编译最佳版本的 FFmpeg

Has*_*ziz 8 cygwin ffmpeg compile audio-conversion video-encoding

人们普遍认为,由于许可原因,FFmpeg 的预编译 Windows 可执行文件开箱即用,带有较低质量的编码器 - 特别是当涉及到默认的 AAC 编码器默认的 resampler 时

根据这些消息来源,解决方案是从源代码编译程序:

FFmpeg 支持两种 AAC-LC 编码器(aac 和 libfdk_aac)和一种 HE-AAC (v1/2) 编码器 (libfdk_aac)。libfdk_aac 的许可证与 GPL 不兼容,因此当还包含 GPL 许可的代码时,GPL 不允许分发包含不兼容代码的二进制文件。因此,此编码器已被指定为“非免费”,您无法下载支持它的预构建 ffmpeg。这可以通过自己编译ffmpeg来解决...

Fraunhofer FDK AAC 编解码器库。这是目前 ffmpeg 可用的最高质量的 AAC 编码器。需要使用 --enable-libfdk-aac 配置 ffmpeg(如果您还使用 --enable-gpl,还需要配置--enable-nonfree)。

...

如果你想要FDK-AAC,你必须自己编译handbrake。我做到了,现在音频听起来很棒。

我的机器上已经有了 Cygwin,我宁愿用它来编译程序,而不是设置另一个软件生态系统或烧毁整个 Linux 发行版。

如何使用 Cygwin 用更好的外部库编译 FFmpeg?

Has*_*ziz 9

这说起来容易做起来难,我花了一个多月才弄清楚如何做到没有任何问题,但我已经花了足够的时间在上面,所以我决定将过程记录得足够好,以便几乎无缝地完成任何跟随我的人。

不幸的是,Cygwin 的默认工具链(即gcc-coreCygwin 安装程序中包含的包)在交叉编译时被固有地破坏了,而且 Cygwin 维护者似乎没有任何意图来解决这个问题,所以目前,编译的唯一方法带有 Cygwin 的 Windows 软件是在其下设置一个 MinGW-w64 工具链。值得庆幸的是,这就像安装几个软件包一样简单。在此之后,我们将编译剩余的包,然后使用两者的组合来编译 FFmpeg 本身。

使用本指南

在全部按照这份指南将建立一个静态的FFmpeg的安装与外部库,比如fdk-aaclibopusx265和SOX重采样。如果我收到足够多的请求来为特定库执行此操作,我可能会考虑将编译特定外部库的说明添加到指南中。

本指南使用的依赖项 - 由 MinGW-w64 交叉编译工具链本身组成,所有安装的apt-cyg包和所有从源编译的包 - 将消耗高达 2.8GB 的​​磁盘空间,尽管该指南还包括清理命令完成后,除了 FFmpeg 安装之外的所有内容。安装本身由二进制文件和文档组成,仅占用超过 200MB 的磁盘空间。

本指南将在您的主目录中创建一个名为 的文件夹ffmpeg_sources,它将在其中下载和编译从源代码构建的所有包。FFmpeg 将安装到/usr/local,FHS 标准建议将用户编译的软件安装到。此位置还有一个次要优势,即PATH在 Cygwin 中默认位于系统上,因此不需要$PATH更新环境变量。

安装包管理器依赖项

首先,下载最新版本的Cygwin的安装程序来安装wgettargawkgit包。好消息是这些包是一个工具的依赖项,可以阻止您再次使用 Cygwin 安装程序。

安装apt-cyg包管理器

接下来,安装kou1okada 的 apt-cyg 包管理器的分支。如果您目前没有使用 Cygwin 的包管理器,这一步不仅会使指南的其余部分变得轻而易举,而且会使您的 Cygwin 体验与任何 Linux 发行版的体验相媲美。

即使您已经为 Cygwin 使用了包管理器,例如原始版本的不同分支apt-cyg,我强烈建议您将其替换为这个,与原始版本相比,这是一个更加成熟的软件,以及目前正在积极开发的 Cygwin 的唯一包管理器。

要安装 kou1okada 的apt-cyg

mkdir -p /usr/local/src &&
cd /usr/local/src &&
git clone https://github.com/kou1okada/apt-cyg.git &&
ln -s "$(realpath apt-cyg/apt-cyg)" /usr/local/bin/
Run Code Online (Sandbox Code Playgroud)

安装构建工具并设置 MinGW-w64 交叉编译器

apt-cyg install \
autoconf \
automake \
binutils \
cmake \
doxygen \
git \
libtool \
make \
mercurial \
mingw64-x86_64-SDL2 \
mingw64-x86_64-binutils \
mingw64-x86_64-fribidi \
mingw64-x86_64-gcc-core \
mingw64-x86_64-gcc-g++ \
mingw64-x86_64-headers \
mingw64-x86_64-libtheora \
mingw64-x86_64-libvpx \
mingw64-x86_64-runtime \
mingw64-x86_64-win-iconv \
mingw64-x86_64-windows-default-manifest \
mingw64-x86_64-zlib \
nasm \
pkg-config \
subversion \
texinfo \
yasm
Run Code Online (Sandbox Code Playgroud)

编译依赖

下面的每个部分都编译了一个外部库,允许您在启用对该库的支持的情况下编译 FFmpeg。将每个命令的全部复制并粘贴到您的 shell 中。

如果您决定不需要构建 FFmpeg 来支持给定的库,请跳过其部分并在本指南的最后阶段编译 FFmpeg 时删除相应的行。--enable-package

使用以下内容在 Cygwin 安装的根目录下创建一个目录:

rm -rf /ffmpeg_sources &&
mkdir -p /ffmpeg_sources
Run Code Online (Sandbox Code Playgroud)

这是我们将源代码下载到并编译的目录。

libmp3lame

为 MP3 编译 LAME 音频编解码器:

cd /ffmpeg_sources && rm -rf lame-svn &&
svn checkout https://svn.code.sf.net/p/lame/svn/trunk/lame lame-svn &&
cd lame-svn &&
./configure --host=x86_64-w64-mingw32 --prefix="/usr/x86_64-w64-mingw32/sys-root/mingw" \
--enable-static --disable-shared &&
make -j$(nproc) &&
make install 
Run Code Online (Sandbox Code Playgroud)

libx264

编译 x264 视频编解码器:

cd /ffmpeg_sources && rm -rf x264 && 
git clone --depth 1 https://code.videolan.org/videolan/x264.git && 
cd x264 &&
./configure --cross-prefix=x86_64-w64-mingw32- --host=x86_64-w64-mingw32 \
--prefix="/usr/x86_64-w64-mingw32/sys-root/mingw" --enable-static &&
make -j$(nproc) &&
make install 
Run Code Online (Sandbox Code Playgroud)

libx265

编译 x265 视频编解码器:

cd /ffmpeg_sources && rm -rf x265 && 
hg clone https://bitbucket.org/multicoreware/x265 &&
cd x265/build/linux &&
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="/usr/x86_64-w64-mingw32/sys-root/mingw" \
-DENABLE_SHARED=OFF -DCMAKE_EXE_LINKER_FLAGS="-static" ../../source \
-DCMAKE_TOOLCHAIN_FILE="/ffmpeg_sources/x265/build/msys/toolchain-x86_64-w64-mingw32.cmake" &&
make -j$(nproc) &&
make install
Run Code Online (Sandbox Code Playgroud)

libogg/libvorbis

Ogg 格式是 Vorbis 音频编解码器的依赖项,因此需要在它之前编译:

cd /ffmpeg_sources && rm -rf ogg &&
git clone --depth 1 https://gitlab.xiph.org/xiph/ogg.git &&
cd ogg && ./autogen.sh &&
./configure --host=x86_64-w64-mingw32 --prefix="/usr/x86_64-w64-mingw32/sys-root/mingw" \
--enable-static --disable-shared &&
make -j$(nproc) &&
make install
Run Code Online (Sandbox Code Playgroud)

然后正常编译 Vorbis:

cd /ffmpeg_sources && rm -rf vorbis && 
git clone --depth 1 https://gitlab.xiph.org/xiph/vorbis.git &&
cd vorbis && ./autogen.sh &&
./configure --host=x86_64-w64-mingw32 --prefix="/usr/x86_64-w64-mingw32/sys-root/mingw" \
--enable-static --disable-shared &&
make -j$(nproc) &&
make install
Run Code Online (Sandbox Code Playgroud)

阿里巴巴

编译 AV1 视频编码器:

cd /ffmpeg_sources && rm -rf aom && 
git clone --depth 1 https://aomedia.googlesource.com/aom && 
mkdir -p /ffmpeg_sources/aom/build && cd /ffmpeg_sources/aom/build && 
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="/usr/x86_64-w64-mingw32/sys-root/mingw" \
-DCMAKE_EXE_LINKER_FLAGS="-static" .. \
-DCMAKE_TOOLCHAIN_FILE="/ffmpeg_sources/aom/build/cmake/toolchains/x86_64-mingw-gcc.cmake" && 
make -j$(nproc) && 
make install
Run Code Online (Sandbox Code Playgroud)

Libopus

编译 Opus 音频编码器:

cd /ffmpeg_sources && rm -rf opus && 
git clone --depth 1 https://github.com/xiph/opus.git &&
cd opus && ./autogen.sh &&
./configure CFLAGS="-I/usr/local/llsp" --host=x86_64-w64-mingw32 --prefix="/usr/x86_64-w64-mingw32/sys-root/mingw" \
--enable-static --disable-shared &&
make -j$(nproc) &&
make install
Run Code Online (Sandbox Code Playgroud)

libfdk-aac

为 AAC 编译 Fraunhofer FDK 编码器:

cd /ffmpeg_sources && rm -rf fdk-aac && 
git clone --depth 1 https://github.com/mstorsjo/fdk-aac &&
cd fdk-aac && autoreconf -fiv &&
./configure --host=x86_64-w64-mingw32 --prefix="/usr/x86_64-w64-mingw32/sys-root/mingw" \
--enable-static --disable-shared &&
make -j$(nproc) &&
make install 
Run Code Online (Sandbox Code Playgroud)

libsoxr

要编译 SOX 重采样器库,您首先需要为 MinGW-w64 工具链创建一个 CMAKE 工具链文件,因为该项目默认不包含一个。

在 Cygwin 根目录中创建一个新文件,并调用它toolchain-x86_64-mingw32.cmake(确保 Windows 显示扩展名,并且扩展名是.cmake)。

将以下内容复制并粘贴到文件中:

SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc)
SET(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++)
SET(CMAKE_RC_COMPILER /usr/bin/x86_64-w64-mingw32-windres)
SET(CMAKE_Fortran_COMPILER /usr/bin/x86_64-w64-mingw32-gfortran)
SET(CMAKE_AR:FILEPATH /usr/bin/x86_64-w64-mingw32-ar)
SET(CMAKE_RANLIB:FILEPATH /usr/bin/x86_64-w64-mingw32-ranlib)
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(QT_BINARY_DIR /usr/x86_64-w64-mingw32/bin /usr/bin)
SET(Boost_COMPILER -gcc47)
Run Code Online (Sandbox Code Playgroud)

现在您可以正常编译 SOX 重采样器:

cd /ffmpeg_sources && rm -rf soxr &&  
git clone --depth 1 https://git.code.sf.net/p/soxr/code soxr &&
mkdir -p soxr/build && cd soxr/build &&
cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="/usr/x86_64-w64-mingw32/sys-root/mingw" \
-DBUILD_SHARED_LIBS=OFF .. -DCMAKE_TOOLCHAIN_FILE="/toolchain-x86_64-mingw32.cmake" &&
make -j$(nproc) &&
make install
Run Code Online (Sandbox Code Playgroud)

编译 FFmpeg 二进制文件

唯一剩下的就是编译 FFmpeg 本身,使用上面下载或编译的库:

cd /ffmpeg_sources && rm -rf ffmpeg &&
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 &&
tar xvf ffmpeg-snapshot.tar.bz2 && rm -f ffmpeg-snapshot.tar.bz2 && cd ffmpeg &&
CFLAGS=-I/usr/x86_64-w64-mingw32/sys-root/mingw/include &&
LDFLAGS=-L/usr/x86_64-w64-mingw32/sys-root/mingw/lib &&
export PKG_CONFIG_PATH= &&
export PKG_CONFIG_LIBDIR=/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig &&
./configure \
--arch=x86_64 \
--target-os=mingw32 \
--cross-prefix=x86_64-w64-mingw32- \
--prefix=/usr/local \
--pkg-config=pkg-config \
--pkg-config-flags=--static \
--extra-cflags=-static \
--extra-ldflags=-static \
--extra-libs="-lm -lz -fopenmp" \
--enable-static \
--disable-shared \
--enable-nonfree \
--enable-gpl \
--enable-avisynth \
--enable-libaom \
--enable-libfdk-aac \
--enable-libfribidi \
--enable-libmp3lame \
--enable-libopus \
--enable-libsoxr \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libx265 &&
make -j$(nproc) &&
make install
Run Code Online (Sandbox Code Playgroud)

请记住为--enable-\*package\*上面列表中的每个包删除您没有下载或编译库的行。

编译 FFmpeg 比编译外部库需要更长的时间,但是一旦完成,您应该拥有一个完全可用的二进制文件,其中包含您编译它的所有库。要运行它,只需ffmpeg在 Cygwin 终端中运行即可。

清理/卸载

到本指南的这一点,下载、安装和编译将占用大约 2.8 GB 的磁盘空间。其中大部分现在是多余的,应该清理。可以安全清除超过 2.6 GB 的空间,这使我们的 FFmpeg 安装的总占用空间减少到 200MB。

安装后清理

运行以下命令将释放超过 2.3GB 的磁盘空间:

apt-cyg remove \
cmake \
doxygen \
git \
mercurial \
subversion \
texinfo \
yasm &&
rm -rf /ffmpeg_sources &&
rm -rf /usr/local/lib/{libav*,libpost*,libsw*} &&
rm -rf /usr/local/lib/pkgconfig/{libav*,libpost*,libsw*} &&
rm -rf /usr/local/include/{libav*,libpost*,libsw*} &&
rm -rf /toolchain-x86_64-mingw32.cmake
Run Code Online (Sandbox Code Playgroud)

除了删除ffmpeg_sources目录和不需要的静态库外,这还将删除之前安装的所有不再需要的包,除了那些在 Cygwin/Linux 上构建工具通常需要的包。

删除交叉编译器

如果您不再打算使用本指南前面构建的 MinGW-w64 交叉编译工具链编译任何其他程序,您可以安全地卸载它,以及之前安装的所有剩余软件包:

apt-cyg remove \
autotools \
autoconf \
automake \
gcc-core \
gcc-g++ \
pkg-config \
libtool \
make \
nasm \
mingw64-x86_64-SDL2 \
mingw64-x86_64-binutils \
mingw64-x86_64-fribidi \
mingw64-x86_64-gcc-core \
mingw64-x86_64-gcc-g++ \
mingw64-x86_64-headers \
mingw64-x86_64-libtheora \
mingw64-x86_64-libvpx \
mingw64-x86_64-runtime \
mingw64-x86_64-win-iconv \
mingw64-x86_64-windows-default-manifest \
mingw64-x86_64-zlib &&
rm -rf /usr/x86_64-w64-mingw32
Run Code Online (Sandbox Code Playgroud)

这将额外释放约 450 MB 的空间。

卸载 FFmpeg

如果您需要反转本指南中的所有步骤并从系统中清除 FFmpeg 二进制文件,只需运行以下命令:

apt-cyg remove \
autotools \ 
autoconf \
automake \
binutils \
cmake \
doxygen \
gcc-core \
gcc-g++ \
git \
libtool \
make \
mercurial \
mingw64-x86_64-SDL2 \
mingw64-x86_64-binutils \
mingw64-x86_64-fribidi \
mingw64-x86_64-gcc-core \
mingw64-x86_64-gcc-g++ \
mingw64-x86_64-headers \
mingw64-x86_64-libtheora \
mingw64-x86_64-libvpx \
mingw64-x86_64-runtime \
mingw64-x86_64-win-iconv \
mingw64-x86_64-windows-default-manifest \
mingw64-x86_64-zlib \
nasm \
pkg-config \
subversion \
texinfo \
yasm &&
rm -rf /ffmpeg_sources &&
rm -rf /usr/local/bin{ffmpeg,ffprobe,ffplay} &&
rm -rf /usr/local/lib/{libav*,libpost*,libsw*} &&
rm -rf /usr/local/lib/pkgconfig/{libav*,libpost*,libsw*} &&
rm -rf /usr/local/include/{libav*,libpost*,libsw*} &&
rm -rf /usr/local/share/doc/ffmpeg &&
rm -rf /usr/local/share/ffmpeg &&
rm -rf /usr/local/share/man/man1/ff* &&
rm -rf /usr/local/share/man/man3/{libav*,libpost*,libsw*} &&
rm -rf /usr/x86_64-w64-mingw32/ &&
rm -rf /toolchain-x86_64-mingw32.cmake 
Run Code Online (Sandbox Code Playgroud)

这将删除本指南过程中安装的所有内容,并将您的系统恢复到启动前的状态。