post(tutorials): does re-encoding to HEVC actually shrink your files? I measured it (EN+ZH) + og/banner
Deploy / build (push) Successful in 19s

Measured on real files with quality held fixed (SSIM vs the source, harness self-tested at 1.0000):
hevc_nvenc cq27 produced 115% and 119% of the source video bitrate on two of three files while cq30/31
landed 51-84%; libx265 crf26 landed 33.7/56.7/67.0% at min SSIM 0.988-0.993, i.e. 10-22% smaller than
NVENC at matched quality. Two sources with identical bpp (0.0437) shrank 49% vs 17%, so bpp classifies
files but does not predict the ratio. Notes the audio floor (a 33.7% video stream still yields a 53%
file because AAC dominates what is left) and why VP9/AV1 sources have no headroom (copy the video).
This commit is contained in:
2026-10-08 05:19:27 +08:00
parent 0b523f40d6
commit 541b00c958
6 changed files with 261 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

+18
View File
@@ -1185,6 +1185,24 @@ BANNERS['it-reported-success-nothing-had-changed'] = {
],
};
BANNERS['does-hevc-actually-shrink-your-files'] = {
titlebar: "root@media - does HEVC shrink it?",
lines: [
{ t: 'prompt', text: "$" }, { t: 'cmd', text: "measure.sh --source h264-a.mp4" },
{ t: 'dim', text: "nvenc cq27 -> 72.4% of source bitrate" }, { t: 'err', text: "nvenc cq27 -> 115.2% on the 720p file" },
{ t: 'prompt', text: "$" }, { t: 'cmd', text: "libx265 -crf 26 -preset medium" },
{ t: 'ok', text: "33.7% / 56.7% / 67.0% at min SSIM 0.99" }, { t: 'hl', text: "same quality, or the comparison is noise" },
{ t: 'dim', text: "software beats hardware by 10-22%" }, { t: 'dim', text: "VP9/AV1 sources: no headroom, copy" },
],
flow: [
{ n: '1', label: "classify bpp" },
{ n: '2', label: "encode" },
{ n: '3', label: "ssim" },
{ n: '4', label: "compare" },
{ n: '5', label: "cap size" },
],
};
// ---------- read frontmatter ----------
const postPath = join(ROOT, 'src', 'content', 'posts', `${slug}.md`);
let category = 'devops';
+6
View File
@@ -361,6 +361,12 @@ TERMINALS['it-reported-success-nothing-had-changed'] = `
<div class="line"><span class="prompt">$</span><span class="cmd">read-back hash -> mismatch</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="cmd">re-upload -> hash match</span><span class="fix">-> verified</span></div>`;
TERMINALS['does-hevc-actually-shrink-your-files'] = `
<div class="line"><span class="prompt">$</span><span class="cmd">hevc_nvenc -cq 27 -> 115% of source bitrate</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">the "high quality" default made it BIGGER</span></div>
<div class="line"><span class="prompt">$</span><span class="cmd">libx265 -crf 26 -> 56.7%</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="cmd">min SSIM 0.988 · 22% smaller than NVENC</span><span class="fix">-> measured</span></div>`;
// ---------- read frontmatter ----------
const postPath = join(ROOT, 'src', 'content', 'posts', `${slug}.md`);
if (!existsSync(postPath)) {
@@ -0,0 +1,148 @@
---
title: "Does Re-encoding to HEVC Actually Shrink Your Files? I Measured It."
description: "A measured comparison of HEVC encoders on real files: NVENC at cq27 made two of three files bigger, software x265 landed 10–22% smaller at matched quality, and one 1080p source shrank 49% while another shrank 17%."
pubDate: 2026-10-08
category: tutorials
tags: [ffmpeg, hevc, x265, nvenc, video]
ogImage: /og/does-hevc-actually-shrink-your-files.png
banner: /banners/does-hevc-actually-shrink-your-files.png
draft: false
---
## The assumption worth testing
"Convert it to HEVC, the files get smaller." It is repeated often enough
that nobody measures it. I had a reason to: a library of 582 course videos
where re-encoding had made files **bigger** in 50 of 54 cases, with the
average output at 111% of the original.
So I measured. Real files, one variable at a time, quality checked against
the source rather than assumed.
The short version:
- Re-encoding a **H.264** source to HEVC at matched quality shrank files by
**33–66%** — but the spread is huge and depends on the source, not just its
bitrate.
- A common "good quality" hardware setting (`hevc_nvenc` at cq27) made **two
of three** test files *larger* than the source.
- At matched quality, **software x265 is 10–22% smaller than NVENC**. Hardware
encoding buys time, not size.
- Re-encoding an already-efficient source (VP9/AV1 from YouTube) buys
nothing. It grows.
## Method: measure at equal quality, or don't bother
Comparing "output bitrate" alone is meaningless — any encoder can hit a low
bitrate by throwing quality away. The measurement has to hold quality fixed.
I encode a 60-second window of each source at several settings, and for each
output:
1. measure the output's **video bitrate** as a percentage of the source's
video bitrate (not the file size — audio is excluded so the two are
comparable), and 2. measure **SSIM against the source**, frame by frame,
downscaled to 480×270 for a stable metric, reporting min and mean.
One prerequisite: the harness must be self-consistent. Comparing a file with
*itself* through the same code path must return SSIM 1.0000. When mine did not
— it returned 0.87 on a file compared with itself, because one side was
decoded from a mid-file seek on an open-GOP source — I could have "measured"
anything and believed it.
```bash
# self-test: this must print 1.000000, or your comparison is lying to you
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 -
```
## Results
Three real sources from the library I was working on, all 25–30 fps H.264,
video bitrate as a percentage of the source's video bitrate:
| Setting | 1080p music (2720 kbps, bpp 0.0437) | 720p (1208 kbps, bpp 0.0437) | 1080×1920 vertical (4490 kbps, bpp 0.0722) |
|---|---|---|---|
| `hevc_nvenc` cq27 | 72.4% (min SSIM 0.9963) | **115.2%** (0.9935) | **119.3%** (0.9930) |
| `hevc_nvenc` cq30 | 51.0% (0.9945) | 82.6% (0.9907) | 83.8% (0.9901) |
| `hevc_nvenc` cq31 | 43.0% (0.9941) | 72.9% (0.9894) | 74.3% (0.9890) |
| `hevc_nvenc` cq30 + AQ/lookahead | 55.8% (0.9958) | 88.1% (0.9914) | 84.4% (0.9935) |
| `libx265` crf26 | **33.7%** (0.9927) | **56.7%** (0.9879) | **67.0%** (0.9913) |
| `libx265` crf28 | 26.4% (0.9910) | 45.0% (0.9852) | 53.2% (0.9888) |
Four things fall out of that table.
**1. The famous default is the wrong default.** cq27 is where a lot of the
internet lands when it says "HEVC, high quality" — and on two of three files
it produced a *bigger* video stream than the source it was replacing. That
is not an argument that HEVC is worse than H.264. It is an argument that a
fixed quality knob calibrated on your own test clip means nothing on someone
else's encode.
**2. The shrink depends on the source's efficiency, not its bitrate.** Samples
1 and 2 have identical bpp (bits per pixel per second) — 0.0437 — and one
shrank 49% where the other shrank 17%. The 720p file was already a decent
encode; the 1080p one was a fat one. Same bpp, different headroom. bpp is
still the cheapest first filter (it told me which *files* to re-encode), but
it does not predict the ratio.
**3. Software x265 beats NVENC on size, at equal quality.** Compare the rows
at similar SSIM: cq31 vs crf26 (min SSIM 0.9894 vs 0.9927 on the 720p file)
— 72.9% vs 56.7%. That is a 22% smaller file at a *higher* measured quality.
Across the set, analysis gives roughly **10–22%** extra saving. NVENC is not
worse at encoding; it is optimized for throughput. If your constraint is
disk, spend CPU; if it is time, spend GPU.
**4. Audio becomes the floor.** Sample 1's video stream dropped to 33.7% of
the source's video bitrate — but the *file* only reached 53.1% of the
original size on the full-length test, because after that drop the AAC audio
(matched to the source's audio bitrate, as iOS requires AAC in MP4) was
about 43% of the output's total bitrate. Once the video is this compressed,
the audio track is the next lever — and it is a much smaller one.
## What this means for VP9/AV1 sources
Everything above is about **H.264** sources. The modern YouTube formats are
a different story, and I measured that too: 14 sampled AVC1 sources had a
median bpp of 0.053 (the "compatibility ladder" YouTube serves to devices
that cannot do VP9/AV1 is generous), while the VP9/AV1 renditions of the
same material sit far lower. Re-encodable headroom: plenty on H.264, none on
VP9/AV1.
On a library of YouTube-sourced VP9/AV1 files, re-encoding with a hardware
encoder at cq27 produced files at **105–112%** of the originals — measurably
worse than leaving them alone. The correct action there is `-c copy`: keep
the video stream bit-identical and re-encode only the audio container (MP3
in MP4 is not playable on iOS; AAC is).
## The decision rules I actually use now
1. **Classify by bpp before encoding anything.** Bits per pixel per second
(`video_bitrate / (width × height × fps)`). It is one ffprobe call and it
separates "there is headroom here" from "leave it alone" better than
resolution or filesize does. 2. **Never re-encode a source that is already
efficient.** Copy the video stream, fix the audio if it needs it, and move
on. A re-encode cannot create headroom that is not there. 3. **Set quality,
not bitrate — then verify against the source.** A metric compared frame by
frame, with a self-test proving your harness works. 4. **Choose the encoder
by your bottleneck.** Disk → x265 (10–22% smaller at equal quality). Time →
NVENC. 5. **Cap the output.** Whatever you do, assert the result is not
bigger than the source. That single assertion would have caught the entire
111% problem before it touched 54 files. 6. **Remember the audio.** After
aggressive video compression, the audio track can be the largest remaining
component of the file.
## The measured outcome
On the 582-file library, with the tiering above and the read-back
verification I described elsewhere:
- **copy tier** (efficient sources, video bit-identical): ~100% of the
original — by design, quality preserved exactly.
- **mid tier** (NVENC, cq31): landed around **72%**.
- **fat tier** (x265, crf26): landed **33–44%**, median **39%**.
That is the honest answer to "does HEVC shrink my files": it depends on what
you are re-encoding, and the only way to know your number is to measure it
on your own files with quality held fixed.
@@ -0,0 +1,89 @@
---
title: "转成 HEVC 到底会不会让文件变小?我实测了"
description: "在真实文件上对 HEVC 编码器做的实测对比:NVENC cq27 让三个测试文件中的两个变得更大;同画质下软件 x265 比 NVENC 小 10–22%;同样是 1080p,一个源缩了 49%,另一个只缩了 17%。"
pubDate: 2026-10-08
category: tutorials
tags: [ffmpeg, hevc, x265, nvenc, video]
ogImage: /og/does-hevc-actually-shrink-your-files.png
banner: /banners/does-hevc-actually-shrink-your-files.png
draft: false
---
## 一个值得验证的假设
"转成 HEVC,文件就变小了。"这句话被重复得太多,以至于没人去实测它。我不得不测:我手上有一个 582 个课程视频的库,之前那轮重编码在 54 个文件里有 **50 个把文件变大了**,平均产出是原来的 111%。
所以我测了。真实文件、一次只改一个变量、画质对着源来量而不是靠假设。
简短版本:
- **H.264** 源转 HEVC、同画质下能省 **33–66%**——但跨度极大,取决于源,而不只是取决于码率。
- 一个很常见的"高质量"硬件设置(`hevc_nvenc` cq27)让**三个测试文件里的两个变得比源更大**。
- 同画质下,**软件 x265 比 NVENC 小 10–22%**。硬件编码买的是时间,不是体积。
- 对已经很高效率的源(YouTube 的 VP9/AV1)重编码一无所获,只会变大。
## 方法:要么在同画质下比,要么别比
只比"输出码率"是没有意义的——任何编码器都可以靠丢画质把码率压下来。测量必须把画质固定住。
我把每个源的 60 秒窗口用多种设置编码,然后对每一份输出:
1. 量**输出的视频码率**占**源视频码率**的百分比(不是文件体积——把音频排除掉,两者才可比);
2. 量**输出对源的 SSIM**,逐帧、缩小到 480×270 以获得稳定的度量,报告最小值和均值。
有一个前提:这套度量工具必须自洽。把一个文件和**它自己**走同一条代码路径比对,必须得到 SSIM 1.0000。当我的工具做不到时——它在一个和自己的比对中给出了 0.87,因为其中一侧是从 open GOP 源的中间 seek 解码的——我本可以"测出"任何结论并信以为真。
```bash
# 自检:这里必须打印 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` cq27 | 72.4%(min SSIM 0.9963) | **115.2%**(0.9935) | **119.3%**(0.9930) |
| `hevc_nvenc` cq30 | 51.0%(0.9945) | 82.6%(0.9907) | 83.8%(0.9901) |
| `hevc_nvenc` cq31 | 43.0%(0.9941) | 72.9%(0.9894) | 74.3%(0.9890) |
| `hevc_nvenc` cq30 + AQ/lookahead | 55.8%(0.9958) | 88.1%(0.9914) | 84.4%(0.9935) |
| `libx265` crf26 | **33.7%**(0.9927) | **56.7%**(0.9879) | **67.0%**(0.9913) |
| `libx265` crf28 | 26.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 个文件的库上,用上面的分档和我另文写的回读校验:
- **copy 档**(高效率源,视频逐位不变):约原体积的 **100%**——有意为之,画质精确保留。
- **中间档**(NVENC,cq31):落在 **72%** 左右。
- **"肥"档**(x265,crf26):落在 **33–44%**,中位数 **39%**。
这就是"HEVC 会不会让我的文件变小"的诚实答案:取决于你在重编码什么,而唯一知道你那个数字的办法,就是在你自己的文件上、把画质固定住去测一遍。