2. 码率控制:CBR、VBR、CRF 的原理与适用场景
码率控制,说白了就是决定「每一秒视频给多少比特」。给多了浪费带宽,给少了画面崩。我做了这么多年流媒体,见过太多人一上来就纠结编码参数,其实码率控制策略选错了,后面调啥都白搭。
今天咱们就把 CBR、VBR、CRF 这三兄弟掰开揉碎讲清楚。你想想看,搞懂了它们,你至少能解决 80% 的推流画质问题。
2.1 三者的核心区别
先给个直观对比。我习惯用一句话概括:
- CBR:不管画面多复杂,每秒比特数死死按住不动。
- VBR:画面简单给少点,画面复杂给多点,但总码率有个平均值。
- CRF:不管码率怎么变,我就要每一帧的质量差不多。
嗯,这里要注意——CRF 其实不是严格意义上的码率控制,它是质量驱动的。但大家经常把它放在一起比较,所以我也放进来讲。
| 特性 | CBR | VBR | CRF |
|---|---|---|---|
| 码率波动 | 几乎无波动 | 允许一定波动 | 波动最大 |
| 画质稳定性 | 复杂场景画质下降 | 较稳定 | 最稳定(按质量) |
| 输出文件大小 | 可精确预测 | 可大致预测 | 不可预测 |
| 适用场景 | 直播推流、IPTV | 点播、视频上传 | 本地存档、后期处理 |
一句话记住:CBR 保带宽,VBR 保平衡,CRF 保质量。三者不可兼得,你得根据场景选。
2.2 CBR(恒定码率)—— 直播场景的「老黄牛」
CBR 的原理很简单:编码器每秒钟输出固定的比特数。比如你设了 2 Mbps,那不管画面是静态PPT还是爆炸特效,编码器都得想办法把码率压到 2 Mbps。
怎么做到的?靠调整量化参数(QP)。画面简单的时候 QP 低一点,画质好;画面复杂的时候 QP 被迫拉高,画质就崩了。我在项目中遇到过好几次,直播体育赛事时,球员快速跑动那几秒,画面全是马赛克——这就是 CBR 的典型痛点。
什么时候用 CBR?
- 直播推流:RTMP、SRT、HLS 直播,接收端带宽是固定的,码率不能乱跳。
- IPTV/有线电视:传输信道是固定带宽,必须严格控码率。
- 低延迟场景:WebRTC 通话,码率波动会导致缓冲和卡顿。
我曾经踩过的坑:有一次做大型活动直播,用了 CBR 2 Mbps,结果现场大屏切换动画时画面直接糊成一片。后来我加了 VBV(视频缓冲校验器)缓冲区限制,才勉强稳住。记住,CBR 一定要配合 VBV 参数使用,否则编码器会为了保码率疯狂拉高 QP。
CBR 的典型 FFmpeg 配置
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -minrate 2M -maxrate 2M -bufsize 4M output.ts
这里 -bufsize 是关键,它决定了编码器能有多大的「缓冲区」来平滑码率波动。一般设为目标码率的 2 倍。
2.3 VBR(可变码率)—— 点播场景的「聪明人」
VBR 就聪明多了。它允许码率在一定范围内浮动:简单画面给少点,复杂画面给多点。最终码率会落在一个平均值附近。
你想想看,一部电影里,对话场景和爆炸场景的信息量能一样吗?VBR 就是让编码器「按需分配」比特。我个人习惯在点播场景里首选 VBR,因为同样的平均码率,VBR 的画质比 CBR 好 20%-30%。
VBR 的两种模式
- 1-pass VBR:一遍过,编码器边走边猜。速度快,但码率分配不够精准。
- 2-pass VBR:第一遍分析视频复杂度,第二遍按分析结果分配码率。质量更好,但耗时翻倍。
我的建议:如果是离线转码,比如视频平台的后台处理,一定要用 2-pass VBR。虽然慢一点,但码率分配更合理,画质更稳定。直播场景就别想了,2-pass 延迟太高。
VBR 的典型 FFmpeg 配置
# 1-pass VBR
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -maxrate 4M -bufsize 4M output.mp4
# 2-pass VBR
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 1 -f mp4 /dev/null
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 2 output.mp4
2.4 CRF(恒定质量)—— 本地存档的「完美主义者」
CRF 的思路完全不同。它不管码率是多少,只关心每一帧的质量是否一致。你设一个 CRF 值(比如 23),编码器就会尽量让每一帧的感知质量都接近这个水平。
为什么会这样?CRF 背后是「感知编码」的思想。编码器会分析每一帧的复杂度,简单帧给低码率,复杂帧给高码率,但最终视觉质量保持一致。说白了,CRF 是「质量优先」的策略。
我记得有一次帮朋友压一个 4K 素材,他用 CBR 压出来 50 Mbps,文件大得吓人。我换成 CRF 18,码率只有 30 Mbps,但肉眼根本看不出区别。这就是 CRF 的威力——它把比特花在了刀刃上。
CRF 值的含义
| CRF 值 | 质量 | 典型码率(1080p) | 适用场景 |
|---|---|---|---|
| 0 | 无损 | 极高 | 存档、后期 |
| 18-22 | 视觉无损 | 8-15 Mbps | 本地存档、剪辑素材 |
| 23-28 | 高/中 | 3-8 Mbps | 点播分发 |
| 29-35 | 低 | 1-3 Mbps | 移动端、低带宽 |
注意:CRF 不能控制输出码率。如果你设了 CRF 18,遇到复杂场景码率可能飙到 50 Mbps。所以 CRF 绝对不适合直播推流——你没法保证接收端能扛住这种码率波动。
CRF 的典型 FFmpeg 配置
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium output.mp4
-preset 也很重要。它控制编码速度和压缩率:ultrafast 最快但文件大,veryslow 最慢但文件小。我一般用 medium 或 slow,平衡速度和体积。
2.5 核心逻辑流程图
下面这张图帮你理清三者的决策路径。每次选码率控制策略时,按这个流程走一遍,基本不会错。
2.6 实战选择建议
说了这么多,到底怎么选?我直接给你几个场景,你照着套就行:
- 场景一:抖音/快手直播 → CBR + VBV。平台对码率波动很敏感,超了会被截断或卡顿。
- 场景二:B站上传视频 → 2-pass VBR。平台会二次转码,你给一个码率稳定的源文件,二压后画质损失最小。
- 场景三:本地备份家庭录像 → CRF 20-22。质量优先,文件大小无所谓。
- 场景四:WebRTC 视频通话 → CBR + 动态码率调整。WebRTC 内部有拥塞控制,CBR 配合它最稳。
- 场景五:电影级离线转码 → CRF 18 + preset slow。画质接近无损,适合存档和后期调色。
一个小技巧:如果你不确定选哪个,先跑一段 CRF 23 看看码率分布。如果码率波动在可接受范围内,就继续用 CRF;如果波动太大,再切到 VBR 2-pass。我经常用这个「试错法」快速确定策略。
2.7 避坑指南
最后分享几个我踩过的坑,你遇到了直接绕开:
- 坑一:直播用 CRF。码率飙到 50 Mbps 的时候,观众端直接卡死。别问我怎么知道的。
- 坑二:CBR 不设 VBV。编码器为了保码率,QP 会瞬间拉高,画面出现「闪崩」。设
-bufsize是必须的。 - 坑三:VBR 用 1-pass 做高质量点播。1-pass 的码率分配不够精准,复杂场景容易翻车。2-pass 多花一倍时间,但值得。
- 坑四:CRF 值设太低。CRF 0 是无损,但文件大小可能是 CRF 18 的 10 倍。除非你有无限硬盘,否则别低于 18。
嗯,码率控制这块就讲这么多。记住核心原则:直播用 CBR,点播用 VBR,存档用 CRF。搞懂这三者的区别,你的推流质量至少能上一个台阶。