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 知识体系总览

下面这张图,帮你把本章的核心逻辑串起来:

FFmpeg编码优化核心决策树 选择编码器 libx264(软件) h264_nvenc(NVIDIA) h264_vaapi(Intel/AMD) 预设:ultrafast/fast/medium 预设:fast/medium/slow 预设:fast/medium CRF(录制)或CBR(推流) CBR(推流首选) CBR(推流首选) 目标:低CPU + 稳定码率 + 可接受画质 说明:推流场景下,硬件编码器(nvenc/vaapi)+ fast预设 + CBR模式是最稳妥的组合

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。