3. FFmpeg编码优化:选对编码器,卡顿少一半
编码器选不对,推流卡顿是必然的。我在早期做直播项目时,就吃过这个亏——明明带宽够、机器也不差,观众却一直喊卡。后来才发现,是编码器配置出了问题。
这一章,我带你彻底搞懂FFmpeg的编码器选择、预设调优和码率控制模式。说白了,就是让你知道:什么场景该用什么编码器,怎么调才能不卡。
3.1 三大编码器:libx264、h264_nvenc、h264_vaapi
FFmpeg支持的H.264编码器很多,但实际推流常用的就三个:libx264(软件编码)、h264_nvenc(NVIDIA显卡硬件编码)、h264_vaapi(Intel/AMD显卡硬件编码)。
它们各有各的脾气,选错了就是灾难。
| 编码器 | 类型 | CPU占用 | 画质/码率效率 | 适用场景 |
|---|---|---|---|---|
| libx264 | 软件编码 | 高 | 最高 | 服务器端、画质优先 |
| h264_nvenc | NVIDIA硬件编码 | 低 | 中等 | 游戏推流、低延迟场景 |
| h264_vaapi | Intel/AMD硬件编码 | 低 | 中等偏低 | 集成显卡、低功耗设备 |
核心结论:libx264画质最好,但吃CPU;nvenc速度快,画质够用;vaapi适合低端设备,别指望它出精品。
我记得有一次,客户要求用低配服务器做4路1080p推流。我一开始用了libx264,结果CPU直接飙到95%,画面开始掉帧。换成h264_nvenc后,CPU降到20%,推流稳稳的。嗯,这就是选对编码器的价值。
3.2 编码预设:ultrafast、fast、medium到底差在哪?
预设(preset)控制的是编码器的速度与画质平衡。FFmpeg的libx264从ultrafast到placebo共有10个级别,但推流常用的就三个:ultrafast、fast、medium。
你想想看,预设越慢,编码器花的时间越多,画质越好,但CPU占用也越高。推流是实时任务,不能为了画质把CPU跑满,否则就会卡顿。
| 预设 | 编码速度 | CPU占用 | 画质 | 推流场景建议 |
|---|---|---|---|---|
| ultrafast | 极快 | 极低 | 差 | 低配机器、移动端推流 |
| fast | 快 | 低 | 中等 | 大多数直播场景 |
| medium | 中等 | 中等 | 好 | 服务器端、画质优先 |
我的习惯:如果是游戏推流或低延迟场景,我一般用fast预设。既保证了画质,又不会让CPU成为瓶颈。ultrafast我只有在树莓派这种设备上才用。
举个例子,同样是推1080p@30fps的视频:
# ultrafast预设(CPU友好,画质一般)
ffmpeg -i input.mp4 -c:v libx264 -preset ultrafast -b:v 2000k -f flv rtmp://...
# fast预设(推荐,平衡之选)
ffmpeg -i input.mp4 -c:v libx264 -preset fast -b:v 2000k -f flv rtmp://...
# medium预设(画质好,CPU压力大)
ffmpeg -i input.mp4 -c:v libx264 -preset medium -b:v 2000k -f flv rtmp://...
我曾经在项目中遇到过一个问题:用medium预设推流,服务器CPU一直90%以上,偶尔出现编码队列积压,导致画面卡顿。换成fast预设后,CPU降到60%,卡顿消失了。画质差异?观众根本看不出来。
3.3 CRF vs CBR:码率控制模式怎么选?
码率控制模式,说白了就是决定编码器怎么分配码率。推流场景下,最常用的两种模式是CRF(恒定质量)和CBR(恒定码率)。
很多人一上来就用CRF,觉得画质好。但推流不是录视频,CRF在某些场景下会害了你。
| 模式 | 特点 | 码率波动 | 适用场景 |
|---|---|---|---|
| CRF | 恒定质量,码率动态变化 | 大 | 本地录制、点播转码 |
| CBR | 恒定码率,质量动态变化 | 小 | 直播推流、RTMP传输 |
避坑指南:我曾经在直播项目里用了CRF模式,结果画面静止时码率降到几百kbps,画面一动码率飙到5Mbps。CDN直接扛不住,观众端疯狂缓冲。后来换成CBR,码率稳稳的,卡顿问题解决了。
为什么会这样?因为CRF的目标是保持画质恒定,码率会根据画面复杂度自动调整。而直播推流要求码率稳定,否则CDN和播放器都会出问题。
CBR模式下,编码器会强制输出固定码率。画面简单时,编码器会填充空数据;画面复杂时,编码器会降低画质来维持码率。虽然画质有波动,但码率稳定,推流更可靠。
具体用法:
# CRF模式(适合录制,不适合推流)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset fast output.mp4
# CBR模式(推流推荐)
ffmpeg -i input.mp4 -c:v libx264 -b:v 2000k -minrate 2000k -maxrate 2000k -bufsize 4000k -preset fast -f flv rtmp://...
注意CBR的参数:-b:v设置目标码率,-minrate和-maxrate都设成一样,-bufsize一般是目标码率的2倍。这样编码器就会老老实实输出固定码率。
3.4 知识体系总览
下面这张图,帮你把本章的核心逻辑串起来:
3.5 实战建议:不同场景的编码配置
说了这么多,直接给结论吧。以下是我在项目中验证过的配置方案:
- 游戏推流(低延迟、高帧率):h264_nvenc + fast预设 + CBR 6000kbps
- 服务器端转码(画质优先):libx264 + medium预设 + CBR 4000kbps
- 低配设备推流(树莓派、旧笔记本):h264_vaapi + fast预设 + CBR 1500kbps
- 移动端推流(手机直播):libx264 + ultrafast预设 + CBR 2000kbps
小技巧:如果你不确定用哪个预设,先从fast开始。它是最安全的中间选项。CPU还有余力就降到medium,CPU吃紧就升到ultrafast。