4. 视频滤镜核心
转码这件事,说白了就是让视频「改头换面」。我刚开始接触 FFmpeg 时,以为转码就是一条命令搞定的事。后来踩了不少坑才明白——真正的转码是一条流水线,每个环节都藏着细节。
这一章,咱们就把这条流水线拆开来看。
4.1 转码的五步流水线
FFmpeg 的转码流程,本质上就是五步:
- 解封装(Demuxer)—— 把容器拆开,拿到音频流、视频流、字幕流
- 解码(Decoder)—— 把压缩的数据解成原始帧(YUV / PCM)
- 滤镜处理(Filter)—— 对原始帧做缩放、裁剪、调色、加字幕等操作
- 编码(Encoder)—— 把处理后的原始帧重新压缩
- 封装(Muxer)—— 把压缩后的流再装进新的容器
我画了一张流程图,帮你直观理解这条线:
你看,数据从左边进去,一路经过五个工位,最后从右边出来。每个工位干的事都不一样。
4.2 解封装与解码
解封装,就是把 MP4、MKV、AVI 这些「包装盒」拆开。包装盒里装着视频流(H.264/H.265)、音频流(AAC/MP3)、字幕流等。FFmpeg 的 -f 参数可以指定封装格式,但大多数时候它会自动识别。
解码,是把压缩的视频数据还原成原始帧。比如 H.264 解码成 YUV 像素数据,AAC 解码成 PCM 音频采样。
我个人习惯用这条命令查看流的详细信息:
ffprobe -v error -show_entries stream=index,codec_name,codec_type -of default=noprint_wrappers=1 input.mp4
输出大概长这样:
[STREAM]
index=0
codec_name=h264
codec_type=video
[/STREAM]
[STREAM]
index=1
codec_name=aac
codec_type=audio
[/STREAM]
嗯,这里要注意:解封装和解码是两个独立步骤。你可以只解封装不解码(比如只提取字幕),也可以解封装后直接复制流(-c copy),跳过解码和编码。
-c copy 就行,速度极快,画质无损。我经常用这招给视频「换壳」。
4.3 滤镜处理
滤镜处理是转码中最灵活的一环。它工作在解码之后、编码之前,操作的是原始帧数据。
常见的滤镜操作包括:
- 缩放:
scale=1280:720 - 裁剪:
crop=640:480:0:0 - 旋转:
transpose=1 - 调色:
eq=brightness=0.1:saturation=1.5 - 叠加文字/图片:
drawtext/overlay
滤镜的语法是 -vf(视频滤镜)和 -af(音频滤镜)。多个滤镜用逗号分隔:
ffmpeg -i input.mp4 -vf "scale=1280:720,eq=brightness=0.05" -c:a copy output.mp4
我曾经在项目中遇到过一个问题:客户要求把一批 4K 视频压成 1080p,同时要调亮画面。如果先转码再调色,得跑两遍。用滤镜链一步搞定,省了一半时间。
4.4 编码与封装
编码,是把处理后的原始帧重新压缩。这是最吃 CPU/GPU 的环节。编码器的选择直接影响输出质量和文件大小。
封装,是把编码后的流再装进新的容器。这一步基本不消耗性能,但决定了输出文件的兼容性。
来看一个完整的转码命令:
ffmpeg -i input.mp4 \
-c:v libx264 -b:v 2M \
-c:a aac -b:a 128k \
-vf "scale=1280:720" \
output.mp4
这条命令干了什么?
- 解封装 input.mp4
- 解码视频流(H.264)和音频流(AAC)
- 视频经过 scale 滤镜缩放到 1280x720
- 视频用 libx264 编码,码率 2 Mbps
- 音频用 AAC 编码,码率 128 kbps
- 封装成 MP4
4.5 关键参数详解:-c:v、-c:a、-b:v
这三个参数是转码命令里的「三剑客」。我刚开始用 FFmpeg 时,经常搞混它们的作用。下面这张表帮你理清:
| 参数 | 全称 | 作用 | 常用值 |
|---|---|---|---|
-c:v |
codec:video | 指定视频编码器 | libx264, libx265, h264_nvenc, copy |
-c:a |
codec:audio | 指定音频编码器 | aac, mp3, libopus, copy |
-b:v |
bitrate:video | 设置视频目标码率 | 1M, 2M, 500k |
重点:
-c:v copy表示视频流不重新编码,直接复制。速度快,画质无损。-c:a copy同理,音频流直接复制。-b:v只对编码器生效。如果用了-c:v copy,设置-b:v是无效的。
举个例子,我想把视频从 MP4 转成 MKV,同时保持画质不变:
ffmpeg -i input.mp4 -c:v copy -c:a copy output.mkv
这条命令只做解封装和封装,不解码不编码,几秒钟就能搞定一个 10GB 的视频。
但如果我想压缩视频,就得指定编码器和码率:
ffmpeg -i input.mp4 -c:v libx264 -b:v 1M -c:a aac -b:a 96k output.mp4
-b:v 写成了 -b,结果 FFmpeg 报错说参数不识别。后来查文档才发现,-b 是全局码率参数,现在已经废弃了。一定要写成 -b:v 和 -b:a。
4.6 转码流水线的实际应用
理解了五步流程和关键参数,你就可以组合出各种转码方案。下面是我总结的几种常见场景:
| 场景 | 命令核心 | 适用情况 |
|---|---|---|
| 格式转换(无损) | -c:v copy -c:a copy |
MP4 → MKV,只换容器 |
| 压缩视频 | -c:v libx264 -b:v 1M |
减小文件体积 |
| 缩放+压缩 | -vf scale=... -c:v libx264 -b:v 1M |
4K 转 1080p 并压缩 |
| 提取音频 | -vn -c:a copy |
只保留音频流 |
| 提取视频 | -an -c:v copy |
只保留视频流 |
你看,核心就是那五步。你可以在任意步骤插入操作,也可以跳过某些步骤。FFmpeg 的灵活性就在这里。
-an 或 -vn 测试视频或音频部分,确认没问题再合起来跑。这样排查问题快很多。