halfsize

halfsize / 指定大小

把视频压到你指定的体积

目标大小不是一个「参数」,而是一份预算:每一秒分到 字节 × 8 ÷ 时长 比特,再减去音频和封装开销。看清这份预算之后,画质问题自己就有答案了, 做不到的目标也不会再被当成编码器的问题。

每个目标能给视频留多少码率

扣掉 128 kbps 音轨和约 2% 的封装开销之后:

时长5 MB10 MB20 MB25 MB50 MB100 MB
15 秒2.5 Mbps5.1 Mbps10.3 Mbps12.9 Mbps26.0 Mbps52.1 Mbps
30 秒1.2 Mbps2.5 Mbps5.1 Mbps6.4 Mbps12.9 Mbps26.0 Mbps
1 分钟525 kbps1.2 Mbps2.5 Mbps3.1 Mbps6.4 Mbps12.9 Mbps
2 分钟199 kbps525 kbps1.2 Mbps1.5 Mbps3.1 Mbps6.4 Mbps
5 分钟—133 kbps395 kbps525 kbps1.2 Mbps2.5 Mbps
10 分钟——133 kbps199 kbps525 kbps1.2 Mbps

「—」表示低于工具会尝试的下限:视频码率不到 80 kbps,就没有「视频」可言了。这种情况下它会直接告诉你这段时长最小能压到多少。

这张表可以直接读成一句话:每秒 100 kbps 是幻灯片。500 kbps 够 540p 和人物讲话, 1.2 Mbps 撑得起 720p,2.5 Mbps 是舒服的 720p 或勉强及格的 1080p。5 Mbps 以上, 花的字节多半在胶片的颗粒上。

每个目标要付出多少画质

同一个 60 秒 1080p30、18 Mbps 的源片(136 MB),本地编码后用 VMAF 逐帧和原片对比:

目标输出分辨率VMAF看起来
20 MB19.45 MB1280×72088.3轻微变软
16 MB15.59 MB960×54084.8变软,边缘仍干净
10 MB9.77 MB960×54082.9变软,运动开始拖影
5 MB4.93 MB640×36072.0明显损失,小字糊掉

关键在分辨率那一列。它宁愿先降分辨率,也不让编码器挨饿,因为 640×360 的 500 kbps 比 1920×1080 的 500 kbps 好看。如果你更想保住画面尺寸,用 --no-downscale, 代价是更软。

一个目标一条命令

$ npx halfsize 假期.mp4 --to 10mb

  target     10.0 MB
  plan       H.264  960x540  1.18 Mbps  audio 128 kbps  2-pass
  scale      1920x1080 → 960x540

  136 MB  →  9.77 MB   小 14 倍   比目标小 2.3%
  VMAF 82.9   SSIM 0.958   变软,运动拖影

任何数字都行:--to 25mb、--to 50mb、--to 700k、 --to 1.5gb。单位是 k、mb、gb,按十进制算, 因为平台的上限就是这么写的。

如果目标比原文件还大,就停手。往上重编码花的是原片没有的码率,得到的只是有损文件的有损副本。 50 MB、100 MB 只对本来就更小的片子有意义。

为什么有些目标根本做不到

十分钟塞进 10 MB,画面加声音一共 133 kbps。这不是编码器能修的事,算术不会因为换了 codec 就改变。0.1.9 起,工具会在编码前先算这笔账,并告诉你这段时长最小能压到多少, 一秒就知道,而不是十分钟之后才知道。

诚实的解法按顺序是:剪短;去掉音频(--no-audio,128 kbps 下每分钟能省约 1 MB); 降分辨率然后接受它。

常见问题

20 MB 能装几分钟?

1.2 Mbps 的 720p 大约两分钟;400 kbps 的低运动 540p 大约五分钟。十分钟就是 133 kbps,一眼看得出来。

能压到比原文件更大的体积吗?

可以,但没有收益:花的是原片没有的码率。保留原片更好。

字节数是精确的吗?

不是。会故意落在目标以下 1–3%,因为上限按十进制算、系统显示的是二进制。超了会修正码率再编一次。

不想指定大小怎么办?

用 --crf 20 按画质编。代价是没有体积保证,而后者往往才是你要的。

音频占了多少?

默认 128 kbps,因为 64 kbps 的人声会发薄。--no-audio 可以整个去掉。

相关