环境准备
约定:源码全部放到sources
下,目录结构说明
/d/java/ffmpeg #工程工目录
├── build #存放编译文件的目录,子目录为具体模块的构建目录
│ ├── fdk-aac
│ ├── ffmpeg
│ └── x264
├── installed #模块的安装目录,各模块的安装文件(如:dll、so等)会存到此处
│ ├── bin
│ ├── include
│ ├── lib
│ └── share
└── sources #源码目录,存放各模块源码
├── fdk-aac
├── ffmpeg
└── x264
依赖工具安装
2.1 安装vs 2022
略过...
2.2 安装msys2
下载地址:MSYS2
安装:
选择好安装目录,默认是:C:\msys64
2.2.1 修改mysys配置
- 编辑msys2_shell.cmd脚本
找到 rem set MSYS2_PATH_TYPE=inherit
所在的行,并将rem移除,最终如下
含义:msys使用windows的环境变量。
启动msys的命令:msys2_shell.cmd -use-full-path
2.2.2 更换msys为国内源
修改C:\msys64\etc\pacman.d中mirrorlist.mingw、mirrorlist.mingw32、mirrorlist.mingw64、mirrorlist.msys四个文件中的源,在## Primary
下面添加清华大学的源
- mirrorlist.mingw上面添加
## Primary
Server = https://mirrors.tuna.tsinghua.edu.cn/mingw/$repo/
- mirrorlist.mingw32上面添加
## Primary
Server = https://mirrors.tuna.tsinghua.edu.cn/mingw/i686/
- mirrorlist.mingw64上面添加
## Primary
Server = https://mirrors.tuna.tsinghua.edu.cn/mingw/x86_64/
- mirrorlist.msys上面添加
## Primary
Server = https://mirrors.tuna.tsinghua.edu.cn/msys/$arch/
保存后启动msys。
2.2.3 安装msys中的依赖库
#pacman -Syu 一键安装和升级所有的库
pacman -Syu
#安装编译ffmpeg所需的包
pacman -S gcc
pacman -S make
pacman -S pkg-config
pacman -S diffutils
pacman -S yasm
pacman -S nasm
#//用于编码fda-aac时运行。/autogen.sh生成configure文件
pacman -S autoconf
pacman -S automake
pacman -S libtool
#避免与msvc的link冲突
mv /usr/bin/link.exe /usr/bin/link.exe.bak
2.3 编译fdk-aac编码器
在msys环境下运行
- 下载源码
cd /d/java/ffmpeg/sources
git clone --depth 1 https://gitee.com/mirrors/fdk-aac.git
- 切换到编译目录
目录结构:
/d/java/ffmpeg
├── build
│ ├── fdk-aac
│ ├── ffmpeg
│ └── x264
├── installed
│ ├── bin
│ ├── include
│ ├── lib
│ └── share
└── sources
├── fdk-aac
├── ffmpeg
└── x264
开始编译
cd ../build/fdk-aac
#此时所在目录:/d/java/ffmpeg/build/fdk-aac
#执行如下命令
#1. config
cmake ./../../sources/fdk-aac/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./../../installed
# 2. build
cmake --build . --config Release
# 3. install
cmake --install . --config Release
编译成功,如下图所示:
参考文档
- cmake编译不同的版本
cd debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
cd ../release
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
Step 12: Packaging Debug and Release — CMake 3.29.0-rc4 Documentation
- cmake指定安装目录
cmake --install . --config Release --prefix "/home/myuser/installdir"
Step 5: Installing and Testing — CMake 3.29.0-rc4 Documentation
2.4 编译x264源码
- 打开x64 Native Tools Command Prompt for VS 2022的命令行工具
- 进入
msys64
的安装目录
cd C:\msys64
- 执行
msys2_shell.cmd
脚本
.\msys2_shell.cmd -use-full-path
- 下载源码
#1. 进入到源码目录
cd sources #执行后当前目录: /d/java/ffmpeg/sources
#2. clone代码
git clone --depth 1 https://code.videolan.org/videolan/x264.git
- 修改编译脚本内容
cd sources/x264
curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD" > config.guess
sed -i 's/host_os = mingw/host_os = msys/' configure
- 配置与编译
cd build
mkdir x264
cd x264 #执行后当前目录: /d/java/ffmpeg/build/x264
CC=cl ./../../sources/x264/configure \
--prefix=./../../installed \
--enable-shared
make -j 8
make install
mv ./../../installed/lib/libx264.dll.lib ./../../installed/lib/libx264.lib
2.5 编译安装sdl2(ffplay需要)
- 下载源码
cd sources #执行后当前目录: /d/java/ffmpeg/sources
git clone --depth 1 https://github.com/libsdl-org/SDL.git -b SDL2
- 编译&安装
mkdir -p build/SDL
cd build/SDL #执行后,当前目录:/d/java/ffmpeg/build/SDL
#1.config
cmake ./../../sources/SDL/ \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_PREFIX=./../../installed
#2. build
cmake --build . --config Release --parallel
# 3. install
cmake --install . --config Release
- 安装完成
参考文档:
- SDL2/Installation - SDL Wiki
编译ffmpeg(msvc方式)
源码下载
- 方式1(推荐):
#从仓库充clone代码
cd /d/java/ffmpeg/sources
git clone --depth 1 https://github.com/FFmpeg/FFmpeg.git -b release/6.1
- 方式2: github仓库:GitHub - FFmpeg/FFmpeg: Mirror of https://git.ffmpeg.org/ffmpeg.git
- 方式3:官网:Download FFmpeg
安装与配置
- 打开x64 Native Tools Command Prompt for VS 2022的命令行工具
- 进入
msys64
的安装目录
cd C:\msys64
- 执行
msys2_shell.cmd
脚本
.\msys2_shell.cmd -use-full-path
执行后,会打开msys菜单命令行窗口
- 在msys中切换到ffmpeg存放编译产物的目录
#切换到ffmpeg存放编译产物的目录
cd /d/java/ffmpeg/build/ffmpeg
注:路径需要按Linux方式来设置
- 配置pkg-config
将x164、fdk-acc加到环境变量中,ffmpeg编译需要
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/d/java/ffmpeg/installed/lib/pkgconfig
export CC=cl
注:/d/java/ffmpeg/installed是第三方库的安装目录。
- 配置
配置用来设置编译器的类型以及参与编译的模块等
#此时所在目录:/d/java/ffmpeg/build/ffmpeg
export CC=cl
./../../sources/ffmpeg/configure \
--prefix=./../../installed \
--toolchain=msvc \
--enable-cross-compile \
--target-os=win64 \
--arch=x86_64 \
--enable-debug=3 \
--enable-yasm \
--enable-asm \
--enable-shared \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--enable-libfdk-aac \
--enable-libx264 \
--enable-sdl2 \
--extra-ldflags="-LIBPATH:./../../installed/lib/" \
--extra-cflags="-I./../../installed/include/"
- 编译
make -j 8
- 安装
make install
注:可能出现以下错误:
- 错误1:
fftools/opt_common.c(206): error C2065: “slib”: 未声明的标识符
fftools/opt_common.c(206): error C2296: “%”: 非法,左操作数包含“char [138]”类型
fftools/opt_common.c(206): error C2059: 语法错误:“数字上的错误后缀”
fftools/opt_common.c(206): error C2059: 语法错误:“%”
fftools/opt_common.c(206): error C2017: 非法的转义序列
fftools/opt_common.c(206): error C2015: 常量中的字符太多
fftools/opt_common.c(206): error C2001: 常量中有换行符
fftools/opt_common.c(237): error C2143: 语法错误: 缺少“)”(在“*”的前面)
fftools/opt_common.c(237): error C2143: 语法错误: 缺少“{”(在“*”的前面)
fftools/opt_common.c(237): error C2059: 语法错误:“)”
fftools/opt_common.c(238): error C2054: 在“options”之后应输入“(”
fftools/opt_common.c(278): error C2143: 语法错误: 缺少“)”(在“*”的前面)
fftools/opt_common.c(278): error C2143: 语法错误: 缺少“{”(在“*”的前面)
解决方案:
修改fftools/opt_common.c 源码文件, 将第 206 行注释掉,原因是 CC_IDENT 标识未定义引起的,如下所示:
static void print_program_info(int flags, int level)
{
const char *indent = flags & INDENT? " " : "";
av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
if (flags & SHOW_COPYRIGHT)
av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
program_birth_year, CONFIG_THIS_YEAR);
av_log(NULL, level, "\n");
//av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
}
- 错误2:
fftools/ffprobe.c(378): warning C4267: “=”: 从“size_t”转换到“int”,可能丢失数据
fftools/ffprobe.c(597): warning C4267: “函数”: 从“size_t”转换到“int”,可能丢失数据
fftools/ffprobe.c(2423): warning C4267: “函数”: 从“size_t”转换到“int”,可能丢失数据
fftools/ffprobe.c(2424): warning C4267: “函数”: 从“size_t”转换到“int”,可能丢失数据
fftools/ffprobe.c(3624): error C2001: 常量中有换行符
fftools/ffprobe.c(3625): error C2146: 语法错误: 缺少“)”(在标识符“writer_print_string”的前面)
fftools/ffprobe.c(3624): error C2198: “writer_print_string”: 用于调用的参数太少
make: *** [ffbuild/common.mak:81: fftools/ffprobe.o] Error 2
解决方案:
注释CC_IDENT
所在的行,如下所示:
static void ffprobe_show_program_version(WriterContext *w)
{
AVBPrint pbuf;
av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
writer_print_section_header(w, NULL, SECTION_ID_PROGRAM_VERSION);
print_str("version", FFMPEG_VERSION);
print_fmt("copyright", "Copyright (c) %d-%d the FFmpeg developers",
program_birth_year, CONFIG_THIS_YEAR);
//print_str("compiler_ident", CC_IDENT);
print_str("configuration", FFMPEG_CONFIGURATION);
writer_print_section_footer(w);
av_bprint_finalize(&pbuf, NULL);
}
修改后重新install即可。
configure 详细使用方式如下:
./configure --help
测试&运行
执行如下命令:
ffmpeg --help