开始千里之行的第一个三分钟。
为了省去自己手动装各种环境的麻烦,我决定使用 CMake + vcpkg 组合拳。
注意:默认情况下,vcpkg 会尽可能将库静态链接到你的程序中,除非这个库显式地不支持这么做(比如 Qt)。如果你的程序不计划开源,那么则需要首先禁用掉 FFmpeg 中的所有 GPL 库(这包括 h264 和 opus 等常用模块),然后要求 vcpkg 切换到动态链接模式。由于 vcpkg 的整体设计,单独给 FFmpeg 指定动态链接是非常困难的,所以你的其他库也会变成动态链接模式。如果你是程序写了一半才开始引入这个库,那么这么做可能炸掉你之前写的程序。如果你有闭源的需求,则最好不要通过 vcpkg 调用 FFmpeg.
简单地起一个 vcpkg.json 文件:
/* in file vcpkg.json */
{
"name": "foundation",
"version": "0.0.1",
"dependencies": [
"fmt",
"spdlog",
"ffmpeg",
"ffmpeg-bin2c",
],
"builtin-baseline": "2b65c20fc66eda893aa15a15a453c3cf09500b19"
}
其中 fmt 和 spdlog 是日志库,如果你需要使用其他日志库的话可以不加这个,同时修改 CMake 和代码中关于 spdlog 日志库的调用即可。
然后配置 CMake 使用 vcpkg 管理依赖:
/* in file CMakePresets.json */
{
"version": 4,
"configurePresets": [
{
"name": "default",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
}
]
}
指定项目需要使用 FFmpeg 相关的内容:
# in file CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(Foundation LANGUAGES C CXX)
find_package(spdlog CONFIG REQUIRED)
find_package(FFMPEG REQUIRED)
add_executable(Foundation main.cpp)
target_include_directories(Foundation PRIVATE ${FFMPEG_INCLUDE_DIRS})
target_link_libraries(Foundation PRIVATE spdlog::spdlog ${FFMPEG_LIBRARIES})
加载 CMake 工程时,vcpkg 会自动下载对应的源码包、编译并提供给 CMake 使用。首次加载 CMake 工程时由于要跑整个 FFmpeg 库的编译,速度会很慢(以及由于基本上都是在从 GitHub 拉取源码,为了保证编译速度,科学上网是必要的)。后续编译成功后加载速度就会恢复正常。
我们来枚举一下当前 FFmpeg 支持的编解码器来验证安装是没问题的:
// in file main.cpp
extern "C" {
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/opt.h"
}
#include "spdlog/spdlog.h"
int main() {
const AVCodec *codec = nullptr;
void *handle = nullptr;
while ((codec = av_codec_iterate(&handle))) {
spdlog::info("Found codec: {} ({})", codec->name, codec->long_name);
}
return 0;
}
注意到:当引用 FFmpeg 的头文件时,必须使用 extern "C" 包裹,否则 C++ 编译器会认为头文件里的函数是 C++ 函数(即经过名称修饰的函数),链接时会报找不到符号错误。
程序编译运行后,会输出所有 FFmpeg 支持的编解码器格式,形如:
(前略,非常多行)
[2026-05-24 16:28:03.915] [info] Found codec: vnull (null video)
[2026-05-24 16:28:03.915] [info] Found codec: anull (null audio)
观察输出,不难发现一些熟悉的身影,比如 mpeg4, h264, aac, opus 等等。不过,并不是所有的编码器都参与了编译。默认情况下,ffmpeg 依赖项目仅编译 LGPL 或更宽松授权的编码器,而 h264 和 opus 编码器都是 GPL 授权的。
要启用更严格授权的编码器或者非开放授权的编码器,则需要指示 vcpkg 打开对应的功能。比如,想要 FFmpeg 可以使用 NVENC 后端,则需要额外打开 nvcodec 功能:
/* in vcpkg.json */
{
"name": "foundation",
"version": "0.0.1",
"dependencies": [
"fmt",
"spdlog",
{
"name": "ffmpeg",
"features": [
"avcodec",
"avdevice",
"avfilter",
"avformat",
"swresample",
"swscale",
"nvcodec"
]
},
"ffmpeg-bin2c",
],
"builtin-baseline": "2b65c20fc66eda893aa15a15a453c3cf09500b19"
}























