Skip to content

Commit 51db796

Browse files
committed
0.05
1 parent 4a60e11 commit 51db796

10 files changed

Lines changed: 1257 additions & 0 deletions

docs/ffmpeg/00-目录.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# FFmpeg 文档目录(命令行 + vcpkg + libav 入门)
2+
3+
FFmpeg 的使用大致分两类:
4+
5+
- **把它当工具**:用 `ffmpeg/ffprobe` 命令处理音视频(最常见,也最省心)
6+
- **把它当库**:用 `libavformat/libavcodec/libswscale/libswresample` 在 C/C++ 里做解码/编码/转封装
7+
8+
本目录按“先能用 → 再工程化 → 再深入”的顺序组织,默认面向 Windows + Visual Studio + vcpkg。
9+
10+
## 学习路线
11+
12+
- [01-安装与工程:vcpkg + CMake + VS(命令行与链接)](01-安装与工程-vcpkg-CMake-VS.md)
13+
- [02-命令行速查:转码、抽帧、拼接、音视频同步](02-命令行速查-转码-抽帧-拼接-同步.md)
14+
- [03-libav 入门:从打开文件到拿到帧(最小解码链路)](03-libav入门-打开文件-解码-拿到帧.md)
15+
- [04-概念总览:容器、编码、流、时间基、像素格式](04-概念总览-容器编码流时间基像素格式.md)
16+
- [05-编码参数与质量:CRF、码率、预设、GOP、像素格式](05-编码参数与质量-CRF码率预设GOP像素格式.md)
17+
- [06-滤镜与常见场景:filtergraph、缩放裁剪、叠加、水印、字幕](06-滤镜与常见场景-filtergraph-缩放裁剪叠加字幕.md)
18+
- [07-ffprobe 与排错:流选择(map)、同步、常见报错](07-ffprobe与排错-流选择map-同步-常见报错.md)
19+
20+
## 01 从这里开始
21+
22+
- 下一篇:见 [01-安装与工程:vcpkg + CMake + VS(命令行与链接)](01-安装与工程-vcpkg-CMake-VS.md)
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# 01-安装与工程:vcpkg + CMake + VS(命令行与链接)
2+
3+
目录页:见 [FFmpeg 文档目录](00-目录.md)
4+
5+
## 目标
6+
7+
- 在 Windows + VS 环境把 FFmpeg 安装到工程里(vcpkg)
8+
- 能稳定调用 `ffmpeg/ffprobe` 做命令行处理
9+
- 能在 CMake 工程里链接 FFmpeg 的库(libav*
10+
11+
---
12+
13+
## 1. 用 vcpkg 安装 FFmpeg(推荐)
14+
15+
FFmpeg 在 vcpkg 里的 port 名称就是 `ffmpeg`
16+
17+
```
18+
vcpkg install ffmpeg
19+
```
20+
21+
FFmpeg 的能力非常多,vcpkg 里也提供了一堆 feature。初学阶段你可以先接受一个工程口径:
22+
23+
- 先装默认的 `ffmpeg`,把“命令行能用 + 工程能链接 + 运行时 DLL 能找到”跑通
24+
- 之后再按需求加 feature(例如字幕、字体渲染、特定编码器、硬件加速等)
25+
26+
如果你已经在 OpenGL 教程里用过 VS + CMake + vcpkg toolchain,这里保持同一套口径即可:
27+
28+
- 固定 triplet(例如 `x64-windows`
29+
- CMake 配置时固定 vcpkg toolchain
30+
31+
参考(port 说明与 feature 列表):https://vcpkg.link/ports/ffmpeg
32+
33+
---
34+
35+
## 2. 命令行可用性:ffmpeg / ffprobe 在哪里
36+
37+
你可能会遇到“库安装了,但找不到 `ffmpeg.exe`”的情况。原因通常是:
38+
39+
- vcpkg 安装的是库本体;命令行工具是否安装/是否在 PATH 上,取决于 port feature 与你的使用方式
40+
- VS 启动调试时 PATH 与终端 PATH 不是一回事
41+
42+
建议工程化口径是:
43+
44+
- **开发期**:在你自己的工程里固定一个 `tools/``third_party/tools/`,把 `ffmpeg.exe/ffprobe.exe` 作为外部工具管理
45+
- **发布期**:明确把运行时依赖的 DLL 与工具一起打包(避免“只在我电脑能跑”)
46+
47+
如果你是通过 vcpkg 获取命令行工具,通常可以在 vcpkg 的 `installed/<triplet>/tools/ffmpeg/` 一类目录下找到它们(路径以你的 vcpkg 布局为准)。
48+
49+
---
50+
51+
## 3. CMake 链接 FFmpeg(libav*
52+
53+
FFmpeg 的库通常由这些组件组成:
54+
55+
- `libavformat`:容器/封装(读写 mp4/mkv/flv…)
56+
- `libavcodec`:编解码(H.264/H.265/AAC…)
57+
- `libavutil`:通用工具(时间基、字典、缓冲区、像素格式…)
58+
- `libswscale`:图像缩放与像素格式转换
59+
- `libswresample`:音频重采样与格式转换
60+
61+
vcpkg 的 `ffmpeg` port 提供 CMake 集成,典型用法是:
62+
63+
```cmake
64+
find_package(FFMPEG REQUIRED)
65+
target_include_directories(app PRIVATE ${FFMPEG_INCLUDE_DIRS})
66+
target_link_directories(app PRIVATE ${FFMPEG_LIBRARY_DIRS})
67+
target_link_libraries(app PRIVATE ${FFMPEG_LIBRARIES})
68+
```
69+
70+
如果你想让“工程可移植 + 配置更稳定”,建议把依赖放进 vcpkg manifest(`vcpkg.json`)并用 CMakePresets/VS 的 CMake 集成固定 toolchain 与 triplet。
71+
72+
### 3.1 链接不等于能跑:运行时 DLL 要能被找到
73+
74+
Windows 下最常见的问题是:
75+
76+
- 编译链接通过,但运行时报 “找不到 xxx.dll”
77+
78+
第一反应检查:
79+
80+
- DLL 是否在可执行文件同目录
81+
- 或者是否在 PATH 可搜索目录中
82+
- Debug/Release、x86/x64 是否混用了不同目录的 DLL
83+
84+
更推荐的工程习惯是:先把“能编译 + 能运行 + 能定位 DLL”跑通,再进入具体的解码/编码流程。因为 FFmpeg 真正难的部分往往不是 API,而是工程环境与数据路径。
85+
86+
---
87+
88+
## 4. License 的工程现实(你至少要知道的)
89+
90+
FFmpeg 里有不同 license 组合(LGPL/GPL/nonfree)对应不同功能组合与可分发性。初学阶段不需要深究条款,但需要知道:
91+
92+
- 你用的 FFmpeg build 是“带了哪些编码器/库”决定了你能不能用 `libx264``libx265`
93+
- 当你要把程序发布给别人时,license 选择会影响你能否合法分发对应二进制
94+
95+
工程口径:不确定就先用“功能更基础、可分发性更清晰”的组合,等你真的需要某个编码器/滤镜再补齐。
96+
97+
---
98+
99+
## 常见坑
100+
101+
- **Debug/Release 混用依赖**:同一个工程里用到不同 triplet/构建类型的库,会出现运行时找 DLL 或链接符号对不上的问题
102+
- **只链接了 avcodec**:很多符号实际在 avutil/avformat 里,缺一个就会一串 unresolved external
103+
- **把时间戳当成秒**:libav 的时间基是 `AVRational`,很多字段是“以 time_base 为单位”的整数
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# 02-命令行速查:转码、抽帧、拼接、音视频同步
2+
3+
目录页:见 [FFmpeg 文档目录](00-目录.md)
4+
5+
这章只追求“能直接抄走用”。建议先用 `ffprobe` 看清楚容器/编码/时长/帧率/音轨/字幕,再决定要不要转码。
6+
7+
如果你发现自己“会抄但不懂”,先把这两章看一遍:
8+
9+
- 概念:见 [04-概念总览:容器、编码、流、时间基、像素格式](04-概念总览-容器编码流时间基像素格式.md)
10+
- 参数:见 [05-编码参数与质量:CRF、码率、预设、GOP、像素格式](05-编码参数与质量-CRF码率预设GOP像素格式.md)
11+
12+
---
13+
14+
## 1. 先看信息:ffprobe
15+
16+
看流信息(视频/音频分别是什么编码):
17+
18+
```bash
19+
ffprobe -hide_banner -i input.mp4
20+
```
21+
22+
只看时长与关键元信息(输出更干净):
23+
24+
```bash
25+
ffprobe -v error -show_entries format=duration:format_tags=title -of default=nk=1:nw=1 input.mp4
26+
```
27+
28+
---
29+
30+
## 2. 转封装(不转码,最快)
31+
32+
只换容器(不重新编码):
33+
34+
```bash
35+
ffmpeg -i input.mp4 -c copy output.mkv
36+
```
37+
38+
只要视频,不要音频/字幕:
39+
40+
```bash
41+
ffmpeg -i input.mkv -map 0:v:0 -c copy out.mp4
42+
```
43+
44+
只要视频 + 第一条音频(多音轨文件建议显式 map):
45+
46+
```bash
47+
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -c copy out.mkv
48+
```
49+
50+
---
51+
52+
## 3. 常见转码(通用模板)
53+
54+
转 H.264 + AAC(最通用的组合之一):
55+
56+
```bash
57+
ffmpeg -i input.mov -c:v libx264 -pix_fmt yuv420p -c:a aac -b:a 192k output.mp4
58+
```
59+
60+
缩放到 720p(保持宽高比):
61+
62+
```bash
63+
ffmpeg -i input.mp4 -vf "scale=-2:720" -c:v libx264 -c:a copy output_720p.mp4
64+
```
65+
66+
---
67+
68+
## 4. 截取/裁剪(尽量不踩同步坑)
69+
70+
从 10s 开始取 5s(最稳的方式:重编码一遍):
71+
72+
```bash
73+
ffmpeg -ss 10 -t 5 -i input.mp4 -c:v libx264 -c:a aac out.mp4
74+
```
75+
76+
如果你只想“无损裁剪”(`-c copy`),需要接受:不一定从精确帧切、也可能音画有偏差:
77+
78+
```bash
79+
ffmpeg -ss 10 -t 5 -i input.mp4 -c copy out_copy.mp4
80+
```
81+
82+
---
83+
84+
## 5. 抽帧/导出图片序列
85+
86+
按帧率抽(每秒 2 帧):
87+
88+
```bash
89+
ffmpeg -i input.mp4 -vf "fps=2" frames/%06d.png
90+
```
91+
92+
按时间戳抽一张(第 3.5 秒):
93+
94+
```bash
95+
ffmpeg -ss 3.5 -i input.mp4 -frames:v 1 out.png
96+
```
97+
98+
---
99+
100+
## 6. 图片序列 ↔ 视频
101+
102+
图片序列转视频(30fps):
103+
104+
```bash
105+
ffmpeg -framerate 30 -i frames/%06d.png -c:v libx264 -pix_fmt yuv420p out.mp4
106+
```
107+
108+
视频转图片序列:
109+
110+
```bash
111+
ffmpeg -i input.mp4 frames/%06d.png
112+
```
113+
114+
---
115+
116+
## 7. 导出音频 / 改格式
117+
118+
导出 mp3:
119+
120+
```bash
121+
ffmpeg -i input.mp4 -vn -c:a libmp3lame -b:a 192k out.mp3
122+
```
123+
124+
导出 wav(PCM,便于做分析/波形处理):
125+
126+
```bash
127+
ffmpeg -i input.mp4 -vn -c:a pcm_s16le -ar 48000 -ac 2 out.wav
128+
```
129+
130+
---
131+
132+
## 8. 字幕:封装与烧录
133+
134+
把 srt 作为软字幕封装进 mkv:
135+
136+
```bash
137+
ffmpeg -i input.mp4 -i sub.srt -c:v copy -c:a copy -c:s srt out.mkv
138+
```
139+
140+
把字幕烧进画面(硬字幕):
141+
142+
```bash
143+
ffmpeg -i input.mp4 -vf "subtitles=sub.srt" -c:v libx264 -crf 20 -c:a copy out_hardsub.mp4
144+
```
145+
146+
---
147+
148+
## 9. 旋转/翻转
149+
150+
旋转 90°:
151+
152+
```bash
153+
ffmpeg -i input.mp4 -vf "transpose=1" -c:v libx264 -crf 20 -c:a copy out_rot.mp4
154+
```
155+
156+
水平翻转:
157+
158+
```bash
159+
ffmpeg -i input.mp4 -vf "hflip" -c:v libx264 -crf 20 -c:a copy out_hflip.mp4
160+
```
161+
162+
---
163+
164+
## 10. 水印/叠加
165+
166+
叠加 logo 到右上角:
167+
168+
```bash
169+
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=W-w-20:20" -c:v libx264 -crf 20 -c:a copy out_logo.mp4
170+
```
171+
172+
---
173+
174+
## 11. 常见质量/体积控制
175+
176+
CRF + preset(离线压缩常用):
177+
178+
```bash
179+
ffmpeg -i input.mp4 -c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p -c:a aac -b:a 160k out.mp4
180+
```
181+
182+
强行卡码率(带宽受限/推流常用):
183+
184+
```bash
185+
ffmpeg -i input.mp4 -c:v libx264 -b:v 2500k -maxrate 2500k -bufsize 5000k -g 60 -pix_fmt yuv420p -c:a aac -b:a 160k out.mp4
186+
```
187+
188+
---
189+
190+
## 12. 拼接(concat)
191+
192+
同编码参数的 mp4 拼接(推荐先转封装到 TS 再 concat,兼容性更好):
193+
194+
```bash
195+
ffmpeg -i a.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts a.ts
196+
ffmpeg -i b.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts b.ts
197+
ffmpeg -i "concat:a.ts|b.ts" -c copy -bsf:a aac_adtstoasc out.mp4
198+
```
199+
200+
如果你能保证输入文件编码参数完全一致,也可以用 concat demuxer(更标准):
201+
202+
准备一个 `list.txt`
203+
204+
```
205+
file 'a.mp4'
206+
file 'b.mp4'
207+
```
208+
209+
然后:
210+
211+
```bash
212+
ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4
213+
```
214+
215+
---
216+
217+
## 13. 常见同步问题的第一反应
218+
219+
- 先用 `ffprobe` 看:是否 VFR(可变帧率)、音频采样率是否一致、是否有多音轨
220+
- 只要你不是强制无损(`-c copy`),多数同步问题都能通过“重编码 + 统一参数”解决
221+
222+
如果你经常遇到“选错音轨/字幕/莫名其妙不同步/报错看不懂”,直接看:
223+
224+
- [07-ffprobe 与排错:流选择(map)、同步、常见报错](07-ffprobe与排错-流选择map-同步-常见报错.md)

0 commit comments

Comments
 (0)