一、安装编译工具
# 更换pacman源
sed -i "s#mirror.msys2.org/#mirrors.ustc.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*
pacman -Sy
# 安装依赖
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
pacman -S mingw-w64-x86_64-nasm mingw-w64-x86_64-yasm
pacman -S git pkg-config
说明:
base-devel
:提供编译和开发软件所需的基础工具集,包含 常用的工具如 make, patch, autoconf, automake, libtool, gettext, texinfo 等mingw-w64-x86_64-toolchain
:MinGW-w64 的完整工具链,用于在 Windows 上编译 64 位应用程序,包含 编译器(如 gcc, g++)、链接器、调试器(gdb)以及相关的开发库和头文件。mingw-w64-x86_64-nasm
:NASM(Netwide Assembler)是一个开源的 x86 和 x86-64 汇编器。mingw-w64-x86_64-yasm
:YASM 是一个模块化的汇编器,支持 x86 和 x86-64 架构,兼容 NASM 语法。git
:用于从 Git 仓库下载源码(如git clone
)。pkg-config
:用于检索已安装库的编译和链接信息。
二、通过pacman安装依赖
2.1 常见依赖库
查询包名 网址:packages.msys2.org/queue
分类 | 库名称 | 用途 | FFmpeg 配置选项 | pacman 安装命令 |
---|---|---|---|---|
视频编码 | libx264 |
H.264 视频编码(高效、广泛使用的视频编码标准) | --enable-libx264 |
pacman -S mingw-w64-x86_64-x264 |
libx265 |
H.265/HEVC 视频编码(高压缩率,适用于 4K/8K 视频) | --enable-libx265 |
pacman -S mingw-w64-x86_64-x265 |
|
libvpx |
VP8/VP9 视频编码(WebM 格式,适用于网络视频) | --enable-libvpx |
pacman -S mingw-w64-x86_64-libvpx |
|
libtheora |
Theora 视频编码(开源视频格式) | --enable-libtheora |
pacman -S mingw-w64-x86_64-libtheora |
|
libwebp |
WebP 图像和视频编码(高效图像压缩格式) | --enable-libwebp |
pacman -S mingw-w64-x86_64-libwebp |
|
libaom |
AV1 视频编码(下一代开源视频编码,高效压缩) | --enable-libaom |
pacman -S mingw-w64-x86_64-libaom |
|
libdav1d |
AV1 视频解码(高性能 AV1 解码器,适合播放) | --enable-libdav1d |
pacman -S mingw-w64-x86_64-dav1d |
|
libxvid |
MPEG-4 视频编码(老式但仍使用的视频编码标准) | --enable-libxvid |
pacman -S mingw-w64-x86_64-xvidcore |
|
音频编码 | libfdk-aac |
AAC 音频编码(高质量音频编码,支持 HE-AAC) | --enable-libfdk-aac |
pacman -S mingw-w64-x86_64-fdk-aac |
libmp3lame |
MP3 音频编码(广泛使用的音频格式) | --enable-libmp3lame |
pacman -S mingw-w64-x86_64-lame |
|
libopus |
Opus 音频编码(低延迟、高质量,适合网络传输) | --enable-libopus |
pacman -S mingw-w64-x86_64-opus |
|
libvorbis |
Vorbis 音频编码(开源音频格式,常用于 Ogg 容器) | --enable-libvorbis |
pacman -S mingw-w64-x86_64-libvorbis |
|
libspeex |
Speex 音频编码(针对语音优化的压缩格式) | --enable-libspeex |
pacman -S mingw-w64-x86_64-speex |
|
libflac |
FLAC 音频编码(无损音频压缩格式) | --enable-libflac |
pacman -S mingw-w64-x86_64-flac |
|
其他常用功能 | libass |
字幕渲染(支持 ASS/SSA 字幕格式) | --enable-libass |
pacman -S mingw-w64-x86_64-libass |
zlib |
数据压缩(用于压缩和解压文件或流) | --enable-zlib |
pacman -S mingw-w64-x86_64-zlib |
|
freetype |
字体渲染(用于字幕和文本绘制) | --enable-libfreetype |
pacman -S mingw-w64-x86_64-freetype |
|
fontconfig |
字体管理(优化字体选择和配置) | --enable-fontconfig |
pacman -S mingw-w64-x86_64-fontconfig |
|
openal |
音频处理(支持 3D 音频和空间音效) | --enable-openal |
pacman -S mingw-w64-x86_64-openal |
|
libsdl2 |
多媒体交互(用于 ffplay 的图形界面和音频输出) | --enable-sdl2 |
pacman -S mingw-w64-x86_64-libsdl2 |
|
openssl |
支持 HTTPS 和其他加密协议(如 RTMPS) | --enable-openssl |
pacman -S mingw-w64-x86_64-openssl |
|
librtmp |
RTMP 流媒体协议支持(用于直播推流/拉流) | --enable-librtmp |
pacman -S mingw-w64-x86_64-librtmp |
|
libpng |
PNG 图像支持(用于图像处理和帧提取) | --enable-libpng |
pacman -S mingw-w64-x86_64-libpng |
|
libjpeg-turbo |
JPEG 图像支持(加速 JPEG 编码/解码) | --enable-libjpeg |
pacman -S mingw-w64-x86_64-libjpeg-turbo |
2.2 ffmpeg编译安装
最小化配置:x264、x265、fdk-aac 和 lame
安装依赖:
pacman -S mingw-w64-x86_64-x264 mingw-w64-x86_64-x265 mingw-w64-x86_64-fdk-aac mingw-w64-x86_64-lame
ffmpeg 4.4.1 编译:
wget https://ffmpeg.org/releases/ffmpeg-4.4.1.tar.xz
tar xf ffmpeg-4.4.1.tar.xz && cd ffmpeg-4.4.1
./configure \
--prefix=$(pwd)/../ffmpeg_build \
--disable-everything \
--disable-doc \
--enable-shared \
--enable-muxer=mp4,flv,mp3,wav \
--enable-demuxer=mp4,mov,mp3,aac \
--enable-encoder=libx264,libx265,libfdk_aac,libmp3lame \
--enable-decoder=aac,h264,hevc,mp3 \
--enable-protocol=file,http \
--enable-filter=aresample \
--enable-bsf=aac_adtstoasc \
--enable-gpl \
--enable-nonfree \
--enable-libx264 \
--enable-libx265 \
--enable-libfdk-aac \
--enable-libmp3lame \
--extra-cflags="-I$(pwd)/../3rdparty_mingw64/include" \
--extra-ldflags="-L$(pwd)/../3rdparty_mingw64/lib"
# 可能报shr错误,修改完再编译。
make -j$(nproc) && make install
编译错误:“Error: operand type mismatch for shr
” 是由于汇编代码中存在类型不匹配的错误,导致无法通过汇编阶段编译。
解决办法:修改libavcodec/x86/mathops.h
代码
- 将
ci
改为c
- 将
ic
改为c
#define MULL MULL
static av_always_inline av_const int MULL(int a, int b, unsigned shift)
{
int rt, dummy;
__asm__ (
"imull %3 \n\t"
"shrdl %4, %%edx, %%eax \n\t"
:"=a"(rt), "=d"(dummy)
//:"a"(a), "rm"(b), "ci"((uint8_t)shift)
:"a"(a), "rm"(b), "c"((uint8_t)shift)
);
return rt;
}
#define NEG_SSR32 NEG_SSR32
static inline int32_t NEG_SSR32( int32_t a, int8_t s){
__asm__ ("sarl %1, %0\n\t"
: "+r" (a)
//: "ic" ((uint8_t)(-s))
: "c" ((uint8_t)(-s))
);
return a;
}
#define NEG_USR32 NEG_USR32
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
__asm__ ("shrl %1, %0\n\t"
: "+r" (a)
//: "ic" ((uint8_t)(-s))
: "c" ((uint8_t)(-s))
);
return a;
}
参考:https://blog.csdn.net/qq_47733361/article/details/132901423
这是编译后的库文件:
./
├── bin # dll动态库、x.lib动态库导入库
│ ├── avcodec-58.dll
│ ├── avcodec.lib
│ ├── ...
│ └── swscale.lib
├── include
│ ├── ....
│ └── libswscale
├── lib # .def库的函数导出文件,.dll.a 是动态库导入库
│ ├── avcodec-58.def
│ ├── libavcodec.dll.a
│ ├── .....
│ └── swscale-5.def
└── share
└── ffmpeg
三、ffmpeg依赖库(手动编译安装)
库类型:依赖库为动态库+ffmpeg为动态库
3.1 编译依赖库
设置终端代理(仅当前会话有效):
export http_proxy="http://127.0.0.1:11819"
export https_proxy="http://127.0.0.1:11819"
(1)编译x264
# 下载源码
git clone https://code.videolan.org/videolan/x264.git
# 配置
./configure \
--prefix=$(pwd)/../3rdparty_mingw64 \
--enable-shared \
--disable-cli
# 编译安装
make -j$(nproc) && make install
(2)编译x265
注意: 不要使用pacman安装的cmake,因为无法生成指定构建系统文件。
# 如果已安装,则重命名cmake
mv /usr/bin/cmake /usr/bin/cmake_bak
# 设置环境变量,系统安装的cmake路径是:D:\Program\Program Files\CMake\bin
export PATH="/d/Program/Program Files/CMake/bin:$PATH"
# 下载源码
git clone https://bitbucket.org/multicoreware/x265_git.git
# 配置(只编译静态库,而且设定运行时库为静态库)
mkdir tmp && cd tmp
# 不能使用cmake -G "MinGW Makefiles" 会卡死
cmake -G "MSYS Makefiles" \
-DCMAKE_INSTALL_PREFIX=$(pwd)/../../3rdparty_mingw64 \
-DENABLE_SHARED=ON \
-DENABLE_CLI=OFF \
../source
# 编译安装
make -j$(nproc) && make install
(3)编译fdk-aac
# 下载源码
wget https://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-2.0.1.tar.gz
tar -xf fdk-aac-2.0.1.tar.gz && cd fdk-aac-2.0.1/
# 生成configure脚本(可选)
./autogen.sh
# 配置
./configure \
--prefix=$(pwd)/../3rdparty_mingw64 \
--enable-shared=yes \
--enable-static=no
# 编译安装
make -j$(nproc) && make install
(4)编译lame
# 下载源码
wget https://sourceforge.net/projects/lame/files/lame/3.100/lame-3.100.tar.gz
# 配置
./configure \
--prefix=$(pwd)/../3rdparty_mingw64 \
--enable-shared=yes \
--enable-static=no \
--disable-frontend
# 编译安装
make -j$(nproc) && make install
编译问题:无法导出lame_init_old函数
解决办法:在include/libmp3lame.sym文件删除lame_init_old
函数。
3.2 编译ffmpeg
# 下载源码
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg-4.4.1
cd ffmpeg-4.4.1
git checkout n4.4.1
# 设置.pc文件搜索路径
export PKG_CONFIG_PATH=$(pwd)/../3rdparty_mingw64/lib/pkgconfig:$PKG_CONFIG_PATH
# 配置
./configure \
--prefix=$(pwd)/../ffmpeg_build \
--disable-everything \
--disable-doc \
--enable-shared \
--enable-muxer=mp4,flv,mp3,wav \
--enable-demuxer=mp4,mov,mp3,aac \
--enable-encoder=libx264,libx265,libfdk_aac,libmp3lame \
--enable-decoder=aac,h264,hevc,mp3 \
--enable-protocol=file,http \
--enable-filter=aresample \
--enable-bsf=aac_adtstoasc \
--enable-gpl \
--enable-nonfree \
--enable-libx264 \
--enable-libx265 \
--enable-libfdk-aac \
--enable-libmp3lame \
--extra-cflags="-I$(pwd)/../3rdparty_mingw64/include" \
--extra-ldflags="-L$(pwd)/../3rdparty_mingw64/lib"
# 编译安装
make -j$(nproc) && make install
四、vscode使用ffmpeg库
项目目录结构:
./
├── 3rd # 第三方依赖库
│ └── ffmpeg_4.4.1
│ ├── include # 头文件
│ ├── lib # 静态库库
│ └── share
├── build # 编译目录
├── CMakeLists.txt # cmake配置文件
├── set_env.ps1 # msys2配置脚本(使我们能在powershell上使用msys2)
└── src # 源码目录
└── main.c
CMakeLists.txt文件内容:
cmake_minimum_required(VERSION 3.10)
project(ffmpeg_test VERSION 1.0)
set(CXX_STANDARD 11)
set(CXX_STANDARD_REQUIRED True)
# 设置可执行文件输出目录为 bin
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin)
# 配置FFmpeg(avcodec.lib时动态库的导入库)
set(FFMPEG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/ffmpeg-4.4.1)
include_directories(${FFMPEG_DIR}/include)
set(FFMPEG_LIBS
${FFMPEG_DIR}/bin/avdevice.lib
${FFMPEG_DIR}/bin/avfilter.lib
${FFMPEG_DIR}/bin/avformat.lib
${FFMPEG_DIR}/bin/avcodec.lib
${FFMPEG_DIR}/bin/swscale.lib
${FFMPEG_DIR}/bin/swresample.lib
${FFMPEG_DIR}/bin/avutil.lib
)
# 编译和链接依赖库
add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${PROJECT_NAME} PRIVATE ${FFMPEG_LIBS} )
# 使用file(GLOB)获取所有DLL文件
file(GLOB FFMPEG_DLLS "${FFMPEG_DIR}/bin/*.dll")
# 添加自定义命令,在构建后复制DLL文件到输出目录
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${FFMPEG_DLLS}
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
)
set_env.ps1脚本内容:
# =============================================================================
# MSYS2 配置参数(可修改)
# =============================================================================
# MSYS2安装路径
$MSYS2_DIR = "D:\Program\msys64"
# 选择MSYS2子系统: MINGW64, MINGW32, MSYS, CLANG64
$MSYSTEM = "MINGW64"
# 是否继承当前环境变量PATH (yes=继承, no=不继承)
$MSYS2_PATH_TYPE = "inherit"
# =============================================================================
# 以下内容请勿修改
# =============================================================================
# 设置输出编码为 UTF-8
$OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# 检查 MSYS2 目录是否存在
if (-not (Test-Path $MSYS2_DIR)) {
Write-Error "Error: MSYS2 directory not found at $MSYS2_DIR"
Write-Error "Please update MSYS2_DIR in this script to your MSYS2 installation path."
exit 1
}
# 设置基本环境变量
$env:MSYS = "winsymlinks:nativestrict"
$env:MSYS2_ARG_CONV_EXCL = "*"
$env:MSYSTEM = $MSYSTEM
$env:MSYS2_PATH_TYPE = $MSYS2_PATH_TYPE
# 更新 PATH 环境变量
$env:Path = "$MSYS2_DIR\$MSYSTEM\bin;$MSYS2_DIR\usr\bin;$env:Path"
Write-Host "MSYS2 $MSYSTEM environment loaded successfully."
Write-Host ""
# 验证环境
$bashPath = "$MSYS2_DIR\usr\bin\bash.exe"
if (Test-Path $bashPath) {
Write-Host ""
Write-Host "MSYS2 Environment Information:"
Write-Host "----------------------------"
try {
$unameOutput = & $bashPath -c "uname -a"
if ($LASTEXITCODE -eq 0) {
Write-Host $unameOutput
} else {
Write-Warning "Failed to execute uname command"
exit 1
}
} catch {
Write-Warning "Failed to execute uname command"
exit 1
}
Write-Host "----------------------------"
Write-Host "MSYS2 environment loaded successfully."
Write-Host ""
} else {
Write-Error "Error: bash.exe not found at $bashPath"
exit 1
}
# 查看 系统上所有环境变量
# Get-ChildItem Env:
# 查看powershell配置文件内容
# notepad $PROFILE
main.c文件内容:
#include <stdio.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
int main() {
// 待检查的编解码器列表
const char *codecs[] = {
"libx264", // H.264 编码器
"libx265", // HEVC 编码器
"libfdk_aac", // AAC 编码器
"libmp3lame", // MP3 编码器
NULL // 结束标记
};
printf("FFmpeg 集成编解码器状态检查:\n");
printf("===========================\n");
// 遍历并检查每个编解码器
for (int i = 0; codecs[i] != NULL; i++) {
const AVCodec *codec = avcodec_find_encoder_by_name(codecs[i]);
if (!codec) {
// 若编码器未找到,尝试查找解码器
codec = avcodec_find_decoder_by_name(codecs[i]);
}
if (codec) {
printf("[✅] %-12s : 已启用 (类型: %s)\n",
codecs[i],
codec->type == AVMEDIA_TYPE_VIDEO ? "视频" : "音频");
} else {
printf("[❌] %-12s : 未启用或未编译\n", codecs[i]);
}
}
return 0;
}
构建命令
# 在vscode的powershell 执行set_env.ps1脚本,配置msys2
.\set_env.ps1
# 生成构建系统(在项目根目录下执行)
cmake .. -G "MinGW Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
# 编译(在build目录下执行)
cmake --build . --config Release