为什么一个 MP4 播放不了,以及容器到底是什么
播放不了的 MP4 很少是损坏的。扩展名只说明了容器,也就是装着各条流和它们时间戳的那个外壳。真正需要被解码的是里面的编解码器,同样是 .mp4,可以装着能在十年前的手机上播放的 H.264,也可以装着两年前的电视机根本碰不了的 AV1。这就是为什么一个 MP4 能播、另一个不能。
对任何视频文件都要问两个问题:它装在什么盒子里,以及画面是怎么压缩的。换盒子通常是免费的;换压缩方式从来不是。
容器是盒子,编解码器是画面
| 容器 | 视频编解码器 | 音频 | 支持情况 |
|---|---|---|---|
| MP4 | H.264、H.265,部分 AV1 | AAC、MP3 | 到处都能播 |
| WebM | VP8、VP9、AV1 | Opus、Vorbis | 仅浏览器 |
| MKV | 几乎什么都行 | AC-3、DTS,什么都行 | 桌面播放器,浏览器不行 |
| MOV | H.264、H.265、ProRes | AAC、PCM | Apple 生态、剪辑 |
| AVI | DivX、Xvid、MJPEG | MP3、PCM | 老旧的 Windows |
MKV 是最宽容的那个,适合归档而不适合分发:一个完全合法的 MKV 可以装着任何浏览器都打不开的组合。MOV 和 MP4 的结构大部分是共通的,所以两者之间的转换往往只是重写一遍索引。先检查一下文件:
input.mp4
Stream #0:0 Video h264 (High) 1920x1080 30 fps 4200 kb/s
Stream #0:1 Audio aac (LC) 48000 Hz stereo 128 kb/s
关键是“Video”后面那个词。“mp4”这个词几乎什么都没告诉你。
哪种编解码器能在哪里播
| 编解码器 | 同等画质所需比特 | 授权情况 | 支持情况 |
|---|---|---|---|
| H.264 (AVC) | 基准线,就算它 100% | 专利池,几乎在所有地方都已获授权 | 通用 |
| H.265 (HEVC) | 50 到 65% | 多个专利池竞争,费用高,悬而未决 | Apple 支持,浏览器参差不齐 |
| VP9 | 与 H.265 相近 | 免版税 | Chrome、Firefox、Edge、Android |
| AV1 | 30 到 50% | 免版税 | 较新的浏览器、较新的硬件 |
H.265 技术上很强,商业上很别扭,所以支持情况是沿着厂商阵营而不是技术边界分裂的。AV1 压缩效果最好,编码速度却慢得多,有时慢一个数量级,所以它适合编码一次、被观看很多次的视频。面向未知的受众时,MP4 里装 H.264 仍然是答案,视频压缩工具的目标也正是它。
码率、分辨率与帧率
码率是输出每秒的比特数,只有它决定文件大小:乘上时长就得到文件体积。
1920 x 1080 x 30 fps x 3 bytes = about 186 MB per second raw
delivered at 4 Mb/s = about 0.5 MB per second
分辨率翻倍会让像素数变成四倍,但需要的比特数不会,因为在更大的画面里相邻像素更相似,压缩效果更好。预期是二到三倍,所以把宽和高都减半是缩小文件最省力的办法之一:这就是视频缩放工具,而视频裁剪工具则是直接丢掉像素。帧率的影响温和一些,从 30 提到 60 大约增加 20 到 40% 而不是 100%,视频变速工具则是换个思路去缩短时间轴。
控制码率有三种方式:
- 恒定码率全程保持一个码率:静态镜头浪费比特,快速运动的画面则会崩掉。它适合带宽有硬上限的链路。
- 带目标值的可变码率会做平均,让各个场景之间互相借用比特。体积可预测,所以当输出必须塞进一个上限时用它。
- 恒定质量,通常是一个 CRF 值,它固定住画质,让码率自己去到该去的地方。体积不可预测,画质则很均匀,对于用来观看而不是流式传输的内容,这是默认选择。
对 H.264 来说,CRF 的范围是 0 到 51,越低越好:18 几乎与源文件无法分辨,23 是一个稳妥的默认值,超过 28 之后运动画面就会崩掉。这个刻度在不同编解码器之间并不通用。
关键帧,以及为什么裁剪有时是免费的
I 帧,也就是关键帧,是一整幅可以独立解码的完整画面。P 帧只存储相对于前一帧发生了什么变化。B 帧同时从前面和后面的帧做预测,压缩效果最好,这也是解码器有时要先把若干帧压着不显示的原因。
一个关键帧连同依赖它的那些帧构成一个图像组,网络视频编码器大约每两秒放一个关键帧。从图像组中间切开,幸存下来的帧就会引用一幅已经不在文件里的画面,这也是裁剪有两种模式的原因。直接复制流是瞬时且无损的,但切口只能落在关键帧上,所以起点最多可能漂移一个图像组的长度;重新编码则会在你指定的位置放一个关键帧,代价是时间和画质。视频裁剪工具两种都提供;除非帧的精确位置很关键,否则就用复制。
重新编码之所以损失画质,是因为每一轮有损压缩都会丢掉模型认为最不显眼的东西。再编码一次,第二轮就会把第一轮的编码瑕疵当成真实细节,把它们保留下来,再叠加上自己的瑕疵,于是误差在一代代之间累积。只换容器时就复制流,只处理音频时就复制画面,视频静音工具做的正是后者。视频旋转工具可以只设置一个旋转标志而不去动像素,不过忽略这个标志的播放器会显示原始方向。当像素非改不可时,请在一轮里把所有改动都做完。
音轨是另外一半
音频是一条独立的流,有自己的编解码器、采样率和声道布局,也是文件播不了的常见原因。一个能顺利解码 H.264 画面的浏览器,未必能解码 AC-3 或 DTS 环绕声,结果要么没声音,要么整个文件直接失败。MKV 格式的光盘转录文件经常这样翻车。
采样率是波形被测量的频次:CD 是 44100 Hz,视频标准是 48000 Hz。48000 Hz 的立体声 AAC 是稳妥的交付选择,语音接近 128 kb/s,音乐 192 kb/s。音频提取工具能把音轨抽出来,导出为 MP3、WAV、AAC 或 Opus。
把视频做成 GIF
GIF 是 1987 年的一种静态图像格式,动画是后来硬加上去的,没有真正的运动补偿。每一帧基本上是各自独立压缩的,所以五秒钟就能长到好几兆字节,而同一段素材做成无声 MP4 只有区区两三百千字节。它每帧最多 256 种颜色,只有一位透明度,也没有音频。
颜色限制正是画质的胜负所在。一个通用的固定调色板会让渐变出现色带,并迫使大量抖动,而那种噪点接近随机,压缩起来很糟,于是把文件撑大。从素材本身生成一个调色板,再把各帧映射上去,既能得到更好的画面,往往文件还更小;视频转 GIF 工具就会跑这一遍。GIF 要做得短而窄:两三秒,宽度 480 到 640 像素,每秒 10 到 15 帧。如果目标平台接受视频,就发一个静音的 MP4。
适合网页的参数
- 任何只要求“能播”的内容,就用 MP4 里的 H.264 配 AAC 音频。
- CRF 取 23 附近,带细小文字的录屏可以降到 20,背景素材可以放宽到 26。
- 先缩放到它实际展示的宽度,再去压缩,而不是反过来。
- 开启 faststart,让索引位于文件开头,这样下载还没完成就能开始播放。
这里的一切都在你自己机器的浏览器里运行,所以什么都不会被上传,限制来自内存而不是服务器配额。长时间 4K 文件的解码缓冲区可能把一个标签页耗尽,所以先裁剪,再缩放。