3. 编码参数调优:CRF、preset、tune、profile、level 详解
H.265 编码参数多得像满天星,但真正决定画质、码率和兼容性的,其实就几个核心参数。今天我把它们拆开揉碎了讲清楚。
我个人习惯把编码参数分成两类:质量控制类和兼容性约束类。CRF 和 preset 属于前者,profile 和 level 属于后者。tune 嘛,算是个场景优化开关。
一句话总结:CRF 定画质,preset 定速度,tune 定场景,profile 定功能集,level 定上限。
3.1 CRF:恒定质量因子
CRF 是 H.265 里最直观的质量控制参数。它的范围是 0 到 51,默认值通常是 28。数值越小,画质越好,文件也越大。
我做过一个测试:同一段 1080p 视频,CRF 18 的文件大小是 CRF 28 的 3 倍多。但说实话,肉眼在普通显示器上几乎看不出区别。所以我的建议是——别盲目追求低 CRF。
| CRF 值 | 画质等级 | 适用场景 | 文件大小参考 |
|---|---|---|---|
| 0-17 | 视觉无损 | 存档、后期制作 | 极大 |
| 18-22 | 高画质 | 本地收藏、影视 | 较大 |
| 23-28 | 平衡 | 网络分发、直播 | 适中 |
| 29-35 | 可接受 | 移动端、低带宽 | 较小 |
| 36-51 | 低质量 | 预览、缩略图 | 极小 |
我的经验:直播推流用 CRF 24-26 就够了。我曾经试过 CRF 18 推流,结果观众端卡成幻灯片——码率飙到 15Mbps,CDN 直接限流了。
3.2 Preset:速度与压缩率的博弈
Preset 控制的是编码器在「算」和「省」之间的取舍。x265 提供了从 ultrafast 到 placebo 共 10 个等级。
你想想看,preset 越慢,编码器会尝试更多的运动搜索模式、更精细的块划分、更复杂的率失真优化。代价就是——CPU 占用飙升。
# 快速预设(适合直播)
ffmpeg -i input.mp4 -c:v libx265 -preset veryfast -crf 26 output.mp4
# 平衡预设(适合点播)
ffmpeg -i input.mp4 -c:v libx265 -preset medium -crf 22 output.mp4
# 高质量预设(适合离线转码)
ffmpeg -i input.mp4 -c:v libx265 -preset slow -crf 18 output.mp4
| Preset | 编码速度 | 压缩率 | 推荐场景 |
|---|---|---|---|
| ultrafast / superfast | 极快 | 低 | 实时推流、低延迟 |
| veryfast / faster | 快 | 中低 | 直播、快速转码 |
| medium | 中等 | 中等 | 默认值,通用 |
| slow / slower | 慢 | 高 | 离线转码、存档 |
| veryslow / placebo | 极慢 | 极高 | 终极压缩(收益递减) |
避坑指南:我曾经在直播场景用了 preset slow,结果编码延迟直接飙到 2 秒以上。直播对延迟敏感,veryfast 或 faster 才是正解。别为了省那 5% 的码率牺牲实时性。
3.3 Tune:场景定制优化
Tune 参数是给编码器一个「场景提示」。告诉它:你现在要处理的是电影、动画、还是屏幕录制?编码器会根据提示调整内部算法。
常用的 tune 选项有这些:
- film:适合电影、真人视频,保留更多纹理细节
- grain:适合有颗粒感的胶片或噪点较多的视频
- animation:适合卡通、动画,锐化边缘,减少色块
- fastdecode:牺牲压缩率换取解码速度
- zerolatency:禁用 lookahead 和 B 帧,追求最低延迟
# 电影场景
ffmpeg -i movie.mp4 -c:v libx265 -preset medium -crf 22 -tune film output.mp4
# 直播低延迟
ffmpeg -i live_input -c:v libx265 -preset veryfast -crf 26 -tune zerolatency output.ts
我的习惯:做直播推流时,-tune zerolatency 几乎是必选项。它强制编码器不使用 B 帧,减少编码缓存,延迟能降到 200ms 以内。但代价是码率会高 10-15%。
3.4 Profile:功能集约束
Profile 定义了编码器可以使用哪些工具。H.265 主要有三个 profile:
| Profile | 色深 | 支持特性 | 兼容性 |
|---|---|---|---|
| Main | 8-bit | 基础功能 | 最广泛 |
| Main10 | 10-bit | HDR、更高精度 | 较广泛 |
| Main12 | 12-bit | 专业制作 | 有限 |
说白了,profile 就是告诉解码器:「我用到了哪些高级功能,你准备好了吗?」
举个例子。HDR 视频必须用 Main10 profile,因为 8-bit 根本存不下 HDR 的亮度范围。但如果你用 Main10 编码,老设备(比如 5 年前的机顶盒)可能解不了。
我曾经踩过的坑:给客户做 OTT 平台时,用了 Main10 profile 编码 4K 内容。结果有 30% 的用户反馈黑屏。查了半天,发现他们的终端只支持 Main profile。后来我加了降级策略:检测到设备不支持 Main10 时,自动转码为 Main 8-bit。
3.5 Level:分辨率与码率上限
Level 定义了视频的「天花板」——最大分辨率、最大帧率、最大码率。它是解码器能否流畅播放的硬约束。
H.265 的 level 从 1 到 6.2,每个 level 都有明确的规格:
| Level | 最大分辨率 | 最大帧率 | 最大码率(Main) |
|---|---|---|---|
| 3.0 | 720×576 | 50 fps | 6 Mbps |
| 3.1 | 1280×720 | 60 fps | 10 Mbps |
| 4.0 | 1920×1080 | 60 fps | 12 Mbps |
| 4.1 | 1920×1080 | 60 fps | 20 Mbps |
| 5.0 | 3840×2160 | 60 fps | 25 Mbps |
| 5.1 | 3840×2160 | 60 fps | 40 Mbps |
| 6.0 | 7680×4320 | 60 fps | 60 Mbps |
| 6.1 | 7680×4320 | 120 fps | 120 Mbps |
嗯,这里要注意:level 不是越高越好。你设了 level 5.1,解码器就必须支持 4K@60fps 和 40Mbps 码率。如果用户设备只支持 level 4.1,那你的 4K 流就播不了。
# 指定 level 4.1(1080p 上限)
ffmpeg -i input.mp4 -c:v libx265 -profile:v main -level:v 4.1 output.mp4
# 不指定 level(编码器自动推断)
ffmpeg -i input.mp4 -c:v libx265 -profile:v main10 output.mp4
我的建议:做多码率自适应流(比如 HLS 或 DASH)时,每个码率档位都显式指定 level。比如 1080p 档用 level 4.1,4K 档用 level 5.1。这样解码器能提前知道自己的「能力边界」,避免播放失败。
3.6 参数组合实战建议
说了这么多,到底怎么搭配?我直接给几个实战组合:
| 场景 | CRF | Preset | Tune | Profile | Level |
|---|---|---|---|---|---|
| 直播推流(低延迟) | 26 | veryfast | zerolatency | main | 4.1 |
| 点播(通用) | 23 | medium | film | main | 4.1 |
| 4K HDR 点播 | 20 | slow | film | main10 | 5.1 |
| 动画/卡通 | 24 | medium | animation | main | 4.0 |
| 存档(最高质量) | 16 | veryslow | grain | main10 | 6.0 |
最后说一句:参数是死的,场景是活的。别死记硬背这些值。拿一段你的真实视频,跑几个组合对比一下,比看十篇文章都管用。