转成 HEVC 到底会不会让文件变小?我实测了

· 6 分钟 · tutorials ffmpeghevcx265nvencvideo

一个值得验证的假设

“转成 HEVC,文件就变小了。“这句话被重复得太多,以至于没人去实测它。我不得不测:我手上有一个 582 个课程视频的库,之前那轮重编码在 54 个文件里有 50 个把文件变大了,平均产出是原来的 111%。

所以我测了。真实文件、一次只改一个变量、画质对着源来量而不是靠假设。

简短版本:

方法:要么在同画质下比,要么别比

只比”输出码率”是没有意义的——任何编码器都可以靠丢画质把码率压下来。测量必须把画质固定住。

我把每个源的 60 秒窗口用多种设置编码,然后对每一份输出:

  1. 量输出的视频码率占源视频码率的百分比(不是文件体积——把音频排除掉,两者才可比);
  2. 量输出对源的 SSIM,逐帧、缩小到 480×270 以获得稳定的度量,报告最小值和均值。

有一个前提:这套度量工具必须自洽。把一个文件和它自己走同一条代码路径比对,必须得到 SSIM 1.0000。当我的工具做不到时——它在一个和自己的比对中给出了 0.87,因为其中一侧是从 open GOP 源的中间 seek 解码的——我本可以”测出”任何结论并信以为真。

# 自检:这里必须打印 1.000000,否则你的比对工具在骗你
ffmpeg -i any.mp4 -f rawvideo -pix_fmt yuv420p a.yuv
ffmpeg -i any.mp4 -f rawvideo -pix_fmt yuv420p b.yuv
ffmpeg -i a.yuv -i b.yuv -lavfi ssim -f null -

结果

三个来自我在处理的素材库的真实源,都是 25–30 fps 的 H.264;表中数字为输出视频码率占源视频码率的百分比:

设置1080p 音乐(2720 kbps,bpp 0.0437)720p(1208 kbps,bpp 0.0437)1080×1920 竖屏(4490 kbps,bpp 0.0722)
hevc_nvenc cq2772.4%(min SSIM 0.9963)115.2%(0.9935)119.3%(0.9930)
hevc_nvenc cq3051.0%(0.9945)82.6%(0.9907)83.8%(0.9901)
hevc_nvenc cq3143.0%(0.9941)72.9%(0.9894)74.3%(0.9890)
hevc_nvenc cq30 + AQ/lookahead55.8%(0.9958)88.1%(0.9914)84.4%(0.9935)
libx265 crf2633.7%(0.9927)56.7%(0.9879)67.0%(0.9913)
libx265 crf2826.4%(0.9910)45.0%(0.9852)53.2%(0.9888)

这张表里掉出来四件事。

1. 那个”著名默认值”是错的默认值。 网上说”HEVC,高质量”时,很多人会落到 cq27 —— 而在三个文件里的两个上,它产出的视频流比它要替换掉的源还大。这并不是说 HEVC 比 H.264 差,而是说:一个在你自己的测试片段上校准出来的固定质量旋钮,对别人编好的文件毫无意义。

2. 缩小的幅度取决于源的效率,而不是码率。 样本 1 和样本 2 的 bpp(每像素每秒位数)完全相同——都是 0.0437——一个缩了 49%,另一个只缩了 17%。720p 那个本身已经是不错的编码,1080p 那个是”肥”的。同样的 bpp,不同的余量。bpp 仍是最便宜的第一道筛子(它告诉了我该重编码哪些文件),但它预测不了比例。

3. 同画质下软件 x265 比 NVENC 更小。 比较 SSIM 接近的那两行:cq31 vs crf26(在 720p 文件上 min SSIM 0.9894 vs 0.9927)——72.9% vs 56.7%,也就是说文件小了 22%,而量出来的画质更高。整体看,多出来的节省大约是 10–22%。这不是说 NVENC 编得差,而是它为吞吐量做了优化。约束是磁盘就花 CPU,约束是时间就花 GPU。

4. 音频会成为地板。 样本 1 的视频流降到了源视频码率的 33.7%——但在全片测试里,整个文件只降到原体积的 53.1%,因为在视频降下来之后,AAC 音轨(跟随源的音频码率,因为 iOS 要求 MP4 里是 AAC)大约占了输出总码率的 43%。视频压到这个程度之后,音轨就是下一个杠杆——而且是个小得多的杠杆。

这对 VP9/AV1 源意味着什么

上面讲的都是 H.264 源。现代 YouTube 格式是另一回事,我也测了:抽样 14 个 AVC1 源,bpp 中位数是 0.053(YouTube 给不支持 VP9/AV1 的设备发的那条”兼容梯队”,码率给得很足),而同一批素材的 VP9/AV1 版本要低得多。可压缩的余量:H.264 上很多,VP9/AV1 上没有。

在一个由 YouTube VP9/AV1 组成的素材库上,用硬件编码器以 cq27 重编码,产出是原文件的 105–112%——明显不如不动它。这种情况下正确的动作是 -c copy:让视频流逐位不变,只重编音频容器(MP4 里的 MP3 在 iOS 上放不了,AAC 可以)。

我现在实际在用的判断规则

  1. 动手之前先按 bpp 分类。 每像素每秒位数(视频码率 / (宽 × 高 × 帧率))。一次 ffprobe 调用,它区分”有余量”和”别碰它”的能力,比分辨率或文件大小都强。
  2. 已经很高效率的源绝不重编码。 复制视频流、需要的话修音频,然后走开。重编码变不出本来不存在的余量。
  3. 设质量,不设码率——然后对着源验证。 逐帧比对的度量,加上一个证明工具本身可用的自检。
  4. 按瓶颈选编码器。 磁盘 → x265(同画质小 10–22%)。时间 → NVENC。
  5. 给输出加上限。 无论怎么做,都要断言结果不比源更大。就这一条断言,本可以在那 54 个文件被碰之前就抓住整个 111% 的问题。
  6. 别忘了音频。 视频被压狠之后,音轨可能是文件里剩下的最大部分。

实测结果

在那个 582 个文件的库上,用上面的分档和我另文写的回读校验:

这就是”HEVC 会不会让我的文件变小”的诚实答案:取决于你在重编码什么,而唯一知道你那个数字的办法,就是在你自己的文件上、把画质固定住去测一遍。

Lee Teong Hoe

Lee Teong Hoe · Mr Hoelee

Full-stack developer & DevOps engineer based in Malaysia. I run my own production infrastructure and build web systems for small businesses — this blog is the living record.

Hiring? Profile & stack · Malaysian SME? Website design & development ↗ · All posts