11、视频转码与压缩:分辨率缩放、码率控制、H.264/H.265编码参数调优、CRF与CBR
视频转码与压缩,说白了就是「把视频从一种格式变成另一种格式,同时尽量把体积做小」。这活儿看着简单,但坑特别多。我刚开始做音视频处理时,觉得不就是调个参数嘛,结果压出来的视频要么糊成马赛克,要么文件大得离谱。后来踩了无数坑,才慢慢摸清楚这里面的门道。
今天咱们就聊聊视频转码的核心:分辨率缩放、码率控制,还有 H.264 和 H.265 的参数调优。嗯,CRF 和 CBR 这两个概念,我也会重点讲清楚。
核心观点:视频转码不是简单的「压缩」,而是在画质、文件大小、编码速度三者之间找平衡。你不可能同时做到「画质最好、体积最小、速度最快」——这是铁律。
分辨率缩放:不是简单拉大拉小
分辨率缩放,就是把视频的宽高尺寸改一改。比如 1920x1080 缩到 1280x720。听起来简单?但这里有个关键点:保持宽高比。
我见过不少新手直接把宽和高写死,结果画面被压扁了。你想想看,一个圆形的球被压成椭圆,那画面能看吗?
我的习惯:缩放时永远先计算目标宽度对应的正确高度,或者反过来。用代码算一下:
// 保持宽高比缩放
int targetWidth = 1280;
int targetHeight = (int)(originalHeight * (targetWidth / (float)originalWidth));
// 如果高度不是16的倍数,记得对齐
targetHeight = (targetHeight / 16) * 16;
嗯,这里要注意:高度最好对齐到 16 的倍数。为什么?因为大多数编码器在处理 16x16 的宏块时效率最高。不对齐的话,编码器会多做一些 padding 操作,浪费码率。
缩放算法也有讲究。我常用的三种:
- 最近邻插值:最快,但锯齿明显。适合实时预览或缩略图。
- 双线性插值:折中方案。大部分场景够用。
- 双三次插值:画质最好,但慢。适合离线转码。
我在项目中遇到过一个问题:把 4K 视频缩到 1080p 时,用双线性插值总觉得画面有点「糊」。后来换成双三次插值,清晰度明显提升。代价是编码时间多了 30%,但效果值得。
码率控制:CBR、VBR 和 CRF
码率控制,说白了就是「怎么分配比特给每一帧」。这里有三条路:CBR、VBR 和 CRF。
| 模式 | 特点 | 适用场景 |
|---|---|---|
| CBR(恒定码率) | 码率始终不变,画面质量波动大 | 直播、视频会议、网络带宽受限 |
| VBR(可变码率) | 码率动态变化,画面质量稳定 | 本地存储、点播、高质量存档 |
| CRF(恒定质量) | 以质量为基准,自动分配码率 | 个人存档、追求画质一致性 |
CBR 是最「死板」的模式。码率锁死,画面复杂时质量下降,简单时又浪费码率。但直播场景必须用 CBR,因为带宽是固定的。我曾经调一个直播项目,CBR 设了 2Mbps,结果画面里出现烟花特效时直接糊成一片。后来把码率提到 3Mbps,才勉强能看。
VBR 就灵活多了。它允许码率在一定范围内波动。我一般用 2-Pass VBR:第一遍分析视频复杂度,第二遍精确分配码率。效果比单遍好很多,但编码时间翻倍。
重点来了:CRF 是我个人最推荐的模式。
CRF 不是直接控制码率,而是控制「质量」。取值范围 0-51,数值越小质量越高。一般用 18-28:
- CRF 18:视觉无损,适合存档
- CRF 23:默认值,画质与体积平衡
- CRF 28:体积小,画质可接受
为什么我喜欢 CRF?因为它省心。你不需要猜码率设多少合适,只需要告诉编码器「我要这个质量」,剩下的它自己搞定。我在处理个人视频存档时,一律用 CRF 20,出来的效果和原片几乎看不出区别,体积却小了一半。
注意:CRF 不适合直播或文件大小有严格要求的场景。因为最终文件大小不可控。我曾经用 CRF 18 压了一段 10 分钟的 4K 视频,结果出来 800MB——比预期大了两倍。
H.264 与 H.265 编码参数调优
H.264 和 H.265,一个是老将,一个是新秀。H.265 在同等画质下体积能比 H.264 小 30%-50%,但编码时间也长得多。
调优参数时,我重点关注这几个:
preset(预设)
preset 控制编码速度和压缩率的平衡。从 ultrafast 到 placebo,速度越来越慢,压缩率越来越高。
- ultrafast / superfast:实时编码用,画质差
- medium:默认值,折中
- slow / slower:离线转码用,效果好
- placebo:几乎不用,收益极小
我个人的习惯:离线转码用 slow,直播用 veryfast。别用 placebo,它比 slow 慢 10 倍,压缩率只提升不到 1%。
profile(档次)
profile 决定了编码器支持的特性集。H.264 有 baseline、main、high 三个档次。
- baseline:最基础,兼容性最好,但压缩率低
- main:折中
- high:压缩率最高,但解码要求高
嗯,这里要注意:如果目标设备是老旧手机或机顶盒,用 high profile 可能解码不了。我踩过这个坑——压了一批视频给客户,结果他们的设备播不了,最后全部重压成 main profile。
关键帧间隔(GOP size)
关键帧(I帧)是视频的「锚点」。间隔越小,随机寻址越快,但码率越高。一般设 2-5 秒。
直播场景我设 2 秒(60帧的话就是 120),点播场景设 5 秒(250帧)。
实战:用 FFmpeg 调优
说了这么多,来点实际的。下面是我常用的几条 FFmpeg 命令:
# H.264 CRF 模式,slow preset
ffmpeg -i input.mp4 -c:v libx264 -preset slow -crf 20 -c:a aac -b:a 128k output.mp4
# H.265 CRF 模式,medium preset
ffmpeg -i input.mp4 -c:v libx265 -preset medium -crf 22 -c:a aac -b:a 128k output.mp4
# H.264 2-Pass VBR,目标码率 2Mbps
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 1 -an -f mp4 /dev/null
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 2 -c:a aac -b:a 128k output.mp4
一个小技巧:用 H.265 时,CRF 值可以比 H.264 高 2-4。比如 H.264 用 CRF 20,H.265 用 CRF 22 就能达到相近的画质,体积还能再小 20%。
避坑指南
最后分享几个我踩过的坑:
- 不要盲目追求高码率。我曾经把码率设到 50Mbps,结果画质和 20Mbps 没区别,文件却大了两倍多。码率超过一定阈值后,收益递减。
- 注意音频也要处理。很多人只压视频,音频还是原始 PCM 或高码率 AAC。视频压到 2Mbps,音频却占了 512Kbps,比例失调。
- 测试时用真实素材。别用纯色背景或静态画面测试,那测不出编码器的真实水平。用一段运动剧烈、场景切换频繁的视频来测。
视频转码这事儿,说难不难,说简单也不简单。核心就是理解「质量、体积、速度」这个三角关系,然后根据场景选合适的参数。多试几次,你就能找到自己的「黄金参数」了。
公众号:蓝海资料掘金营,微信deep3321