提示

返回博客列表

CRF 不是万能钥匙:ffmpeg 码率控制、两遍编码与码率分配实战

事情的起点是一个很普通的客户问题:"为什么你们转出来的 1080p 电影是 800M,隔壁服务商是 4G?是不是你们偷偷降了码率?"

我第一反应是"没降啊,我们一直用 -crf 23"。但话到嘴边又咽回去了——因为我发现自己其实也说不清 -crf 23 到底意味着多大的码率、多大的文件。

后来我花了一周,把 ffmpeg 里几种码率控制模式从头捋了一遍,又拿同一段素材跑了十几组对比。结论是:CRF 不是万能的,CQ 不是 CRF,CBR 和 VBR 是两回事,2-pass 才是精确控制大小的终极手段。用错模式,轻则浪费带宽,重则画质崩坏。

TL;DR:CRF 是"定画质、不定大小",适合离线分发,-crf 23 是 x264 的默认甜点;硬件编码器的 CQ 看着像 CRF,但量纲不同、同数值画质更低,而且 NVENC 用 CQ 必须加 -b:v 0;CBR 固定码率、靠 maxrate/bufsize 压住峰值,是直播刚需;VBR 在总码率不变的前提下按复杂度分配;2-pass 先分析再编码,在指定码率下画质最接近最优,代价是接近两倍耗时。先想清楚你要"定大小"还是"定画质",再选模式。

目录

一、先分清"码率"和"画质"的关系

在聊模式之前,得先把两个概念掰开。

码率(bitrate)是每秒消耗的比特数,单位一般是 kbps 或 Mbps。它直接决定文件大小:

文件大小 ≈ 码率 × 时长

一段 10 分钟、平均 5Mbps 的视频,大小约 5Mbps × 600s ÷ 8 ≈ 375MB。所以客户问的"为什么 800M 和 4G",本质就是码率差了五倍。

画质取决于"码率够不够",而不是"码率多不多"。同一个画面,码率给到一定程度之后再加码率,肉眼已经看不出区别——这就是收益递减。真正决定画质的是"码率 × 编码效率":同样的码率,x265 通常比 x264 画质好(效率高),但更慢。

所以"转 1080p 用多少码率"这个问题,永远不能脱离两个前提回答:用什么编码器、分辨率是多少。这也是为什么网上那些"万能码率表"十有八九会翻车。

二、CRF:单遍编码的默认选择

CRF(Constant Rate Factor)是 x264/x265 的默认码率控制模式,也是大多数人天天在用的那个。

它的目标不是固定码率,而是固定"感知画质"。编码器会根据画面复杂度实时分配码率:静止画面给少,运动、复杂纹理的画面给多。所以在同一段视频里,码率是浮动的,但观感质量基本稳定。

CRF 的取值是 0–51(x264),0 是无损,23 是默认,51 最差。数值越低画质越好、文件越大:

CRF(x264) 大致画质 1080p 典型码率 适合场景
18 视觉无损 8–12 Mbps 归档、母片
23 很好 3–6 Mbps 默认分发
28 可接受 1.5–3 Mbps 快速预览、带宽紧张

命令很简单:

ffmpeg -i input.mp4 -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k output.mp4

这里有两个容易混淆的点,先说清楚:

  1. CRF 不是码率。-crf 23 绝不等于 23Mbps,它只是一个质量因子,最终码率由内容复杂度决定。所以同样 -crf 23,一部动作片可能是 6Mbps,一部访谈可能只有 2Mbps。
  2. x265 的 CRF 和 x264 不可直接对比。x265 的默认 CRF 是 28,大致对应 x264 的 23,两个数字不能互换套用。

CRF 最大的缺点也在这里:你无法预知最终文件大小。它适合"我只要画质好,大小无所谓"的离线分发场景;一旦要精确控制大小(比如压进 700M、控制在某个码率上限),CRF 就抓瞎了,这时候得上 2-pass,后面会讲。

三、CQ:硬件编码器的"伪 CRF"

GPU 编码器(NVENC、QSV、VAAPI)也提供"类似 CRF"的参数:NVENC 叫 CQ(Constant Quantizer),QSV 叫 ICQ,VAAPI 叫 global_quality。很多教程直接说"CQ 就是硬件版的 CRF,把 -crf 换成 -cq 就行"——这句话错得离谱。

关键差异在量纲:软编 CRF 是基于心理视觉的 rate factor,而硬件 CQ 本质是 quantizer(量化参数)。两者不是一回事,同样写 23,硬件 CQ 出来的画质通常不如软编 CRF。原因也很现实:硬件编码器为了实时性,在运动估计、模式决策这些环节做了大幅简化。

NVENC 的正确用法:

ffmpeg -i input.mp4 -c:v h264_nvenc -preset p4 -cq 23 -b:v 0 -c:a aac -b:a 128k output.mp4

注意那个 -b:v 0:NVENC 默认是 VBR 模式,必须显式把码率置 0,才会真正进入 CQ 模式。漏了它,-cq 直接失效,退化成 VBR,你会得到一堆忽大忽小的文件还以为 CQ 在起作用。

一个粗略的经验换算:NVENC 的 CQ 要画质达到 x264 CRF 23 的水平,大概要压到 -cq 19–21 甚至更低,代价是文件更大。所以硬件 CQ 的正确姿势不是"省码率",而是"用码率换速度"——同样的画质,它比软编快一个数量级,但文件更大。

四、CBR 与 VBR:直播和固定带宽的刚需

CBR(Constant Bit Rate)固定码率,VBR(Variable Bit Rate)可变码率,这是另一对概念。

  • CBR:每一秒的码率都尽量恒定。适合直播、RTC、以及 CDN 或协议要求"带宽可预测"的场景。缺点是在复杂画面会画质下降,简单画面又浪费带宽。
  • VBR:总码率不变的前提下,把码率往复杂画面集中。适合离线编码,画质利用率更高。

直播场景的标准 CBR 写法:

ffmpeg -i input.mp4 \
  -c:v libx264 -preset veryfast \
  -b:v 2500k -maxrate 2500k -bufsize 5000k \
  -g 50 -keyint_min 50 -sc_threshold 0 \
  -c:a aac -b:a 128k \
  -f flv rtmp://your-server/live/stream

这里 maxrate 和 bufsize 是 CBR 的灵魂:

  • maxrate 限制输出码率峰值,超过这个值的帧会被压缩或丢。
  • bufsize 是 VBV 缓冲区大小,决定了码率允许波动的幅度。

两者要成对设置,配比经验是 bufsize 取 maxrate 的 1–2 倍:bufsize 太小,码率波动被掐得太死、画质变差;太大,峰值就压不住了。只写 -b:v 不写 maxrate/bufsize,那它其实是在按 VBR 跑,峰值照样会飙。

五、两遍编码 2-pass:离线归档的终极质量

2-pass 是最"重"但最"稳"的模式,专门解决"我要精确控制大小/码率,又不想损失画质"的问题。

原理分两步:

  1. 第一遍:完整扫一遍内容,记录每一帧、每个片段的复杂度,输出一个统计文件,不产出最终视频。
  2. 第二遍:拿着统计文件重新编码,把目标码率"聪明地"分配到各个片段——复杂画面多给,简单画面少给,总码率卡死在目标值。

命令:

# 第一遍:只分析,不编码音频
ffmpeg -y -i input.mp4 -c:v libx264 -preset slow -b:v 4000k -pass 1 -an -f mp4 NUL

# 第二遍:正式编码
ffmpeg -y -i input.mp4 -c:v libx264 -preset slow -b:v 4000k -pass 2 -c:a aac -b:a 128k output.mp4

(Linux/macOS 下把 NUL 换成 /dev/null。)

两个容易踩的坑:

  1. 第一遍漏了 -an,音频被白白编了一遍,纯属浪费。
  2. 两遍的 -b:v 必须一致,-preset 也要一致,否则统计信息和实际编码对不上。

对比记忆:CRF 是"定画质、不定大小",2-pass 是"定大小、最优化画质"。什么时候值得花两倍时间去跑 2-pass?就是"压进 700M""控制在 4Mbps 以下"这种硬性大小约束出现的时候。

六、码率分配:分辨率和码率的匹配

模式选对了,还要给对码率。分辨率越高需要的码率越高,但关系不是线性的——4K 的像素是 1080p 的四倍,但码率并不需要四倍,因为编码效率随分辨率提升也更好。

下面是 x264 的经验参考值,不是金科玉律,但能帮你快速定位"是不是给多了/给少了":

分辨率 帧率 最低可用码率 推荐码率
360p 24–30 600k 1M
720p 24–30 1.5M 2.5–4M
1080p 24–30 2.5M 4–8M
4K 24–30 8M 15–25M

判断码率是否给够,别靠肉眼硬看,用工具量化:ffmpeg 自带的 libvmaf 能输出 VMAF 分数(0–100,越高越好),或者更轻量的 SSIM。VMAF 低于 85 基本就能看出明显瑕疵了。

七、同一素材的实测对比

拿一段 2 分钟、含大量运动的 1080p30 素材,同一台机器(软编用 8 核 CPU,硬编用一块消费级 NVIDIA)各跑一遍:

模式 参数 文件大小 平均码率 VMAF 耗时
CRF 18 libx264 210M 14M 97.1 3m
CRF 23 libx264 84M 5.6M 93.8 2.4m
CRF 28 libx264 40M 2.7M 87.5 2m
CQ 23 h264_nvenc 120M 8M 90.2 20s
2-pass 4M libx264 60M 4M 92.9 4.8m

从这张表能读出几个结论:

  1. CRF 23 是甜点:画质 93.8 已经很好,大小也克制。
  2. 硬件 CQ 是拿码率换速度:同样写 23,它比软编 CRF 23 大了 43%,画质反而低,但快了 7 倍。
  3. 2-pass 的价值在"稳":锁定 4M 上限的同时,VMAF 还能干到 92.9,接近 CRF 23 的水平。

八、坑清单

  • 硬件 CQ 忘加 -b:v 0,静默退化成 VBR,CQ 白设。
  • 直播用 CBR 只写 -b:v 不写 maxrate/bufsize,峰值压不住、卡顿断流。
  • -crf 和 -b:v 同时写,ffmpeg 会报错或忽略其中一个,别混用。
  • 2-pass 第一遍漏 -an,白编一遍音频;两遍参数不一致,统计作废。
  • 拿 x265 的 CRF 数字套 x264(或反过来),画质/大小完全对不上。
  • 把硬件 -cq 当软编 -crf 的等价值,以为 23 = 23。
  • 给 720p 配 4M 是浪费,给 1080p 配 1M 是灾难——先对表再动手。

九、选型速查表

场景 推荐模式 关键参数
离线分发、画质优先 CRF -crf 23
精确控制大小 2-pass -b:v 目标码率 -pass 2
直播、固定带宽 CBR -b:v -maxrate -bufsize
GPU 实时转码 CQ -cq 23 -b:v 0
归档母片 CRF 低值 -crf 18 -preset slow

最后回到开头那个客户问题:800M 和 4G 的差别,从来不是"谁降了码率",而是两边选了不同的模式、不同的质量目标。CRF 23 没问题,有问题的是"拿 CRF 去应付所有场景"——想清楚要"定大小"还是"定画质",码率控制这一关才算真正过了。


本文由在线视频下载工具 VidDown 提供,支持 B 站、抖音、YouTube 等平台无水印视频下载。

想亲手试试?用 VidDown 一键解析下载

粘贴视频链接即可解析,多平台支持、网页端即用;下载桌面客户端解锁海外平台本地解析,开通会员更享不限次下载。

顶部