[译] 优化 MP4 视频以获得更快的流传输速度

3,767 阅读7分钟

优化 MP4 视频以获得更快的流传输速度

随着 Flash 的衰落移动设备的爆炸式增长,越来越多的内容正在以 HTML5 视频的方式发布。你可以通过 用 HTML5 视频片段代替 GIF 动画 的方式来优化你的网站速度。然而,视频文件本身就有大量可优化的地方,你可以借此提升它们的性能。

其中最重要的一点是视频文件必须经过适当优化才能作为 HTML5 视频在线播放。如果没有这种优化,视频可能会延迟数百毫秒,而只是试图播放视频的访问者也可能会浪费兆字节的带宽。在这篇文章中,我将向你展示如何优化视频文件以获得更快的流传输速度。

MP4 流媒体是如何工作的

在我们 上一篇文章 的讨论中,HTML5 视频是一种跨浏览器观看视频的方式,不需要类似 Flash 的插件。截止到 2016 年,存储在 MP4 容器文件中的 H.264 编码视频(下文将简称为 MP4 视频)已成为所有在线 HTML5 视频的标准格式。所以当我们讨论如何优化 HTML5 视频,其实我们是在讨论如何优化 MP4 视频以获取更快的播放。而我们优化的方式与 MP4 文件的结构以及流媒体传输的工作原理息息相关。

MP4 文件由叫做 原子 的数据块组成。这些原子用以存储字幕和章节等内容, 当然也包括视频和音频等显而易见的数据。而视频和音频原子的元数据,以及有关如何播放视频的信息,如尺寸和每秒的帧数,则存储在叫做 moov 的特殊原子中。你可以认为 moov 原子是某种意义上的 MP4 文件目录

当你播放视频时,程序会查找 MP4 文件,定位 moov 原子的位置,然后借此去查找视频和音频的起始位置来开始播放。遗憾的是,原子可能以任意顺序排列,所以程序一开始并不知道 moov 原子在哪里。如果你已经拥有整个视频文件,查找 moov 原子是完全没问题的。但如果暂时没有整个文件,比如流传输 HTML5 视频时,就需要另辟蹊径了。这才是流媒体的重点!你无需先下载整个视频即可开始观看。

当流传输时,你的浏览器请求视频资源并开始接收文件的开始部分。程序查找 moov 原子是否在开始的部分。如果 moov 原子不在开始位置,它必须下载整个文件才能尝试找到 moov,或者浏览器可以从最末端的数据开始下载视频文件的不同小片段,以试图找到 moov原子。

所有这些试图找到 moov 的行为浪费了时间和带宽。遗憾的是,在找到 moov 之前,视频是无法播放的。 我们可以在下面的屏幕截图中看到浏览器的瀑布图,该浏览器试图使用 HTML5 视频来流传输未优化的 MP4 文件:

mp4-no-moov

你可以看到浏览器在播放视频之前发起了三次请求。 在第一次请求中,浏览器通过 HTTP range request 下载了 552 KB 的第一部分视频。 我们可以通过 HTTP 状态码 206 Partial Content 以及查看响应头的详细信息来发现这些。然而,moov 原子并未包含在内,所以浏览器无法开始视频播放。接下来,浏览器通过 HTTP range request 获取了后面的 21 KB 视频文件。它包含 moov 原子,告诉浏览器视频和音频流的开始位置。最后,浏览器发起了第三个也是最后一个 HTTP range request,以获取音频/视频数据并可以开始播放视频。这导致浪费了超过半兆字节的带宽以及 210 ms 的播放延迟!仅仅是因为浏览器找不到 moov 原子。

如果你的服务器没有配置 HTTP range request,情况甚至会更糟:浏览器无法跳过查找 moov 这一步,以至于不得不下载整个文件。这也是你需要 支持部分下载来优化你的网站 的另一个原因。

为 HTML5 流传输准备 MP4 视频的理想方法是(重新)组织文件,以便 moov处于最开始的位置。这样一来,就可以避免浏览器下载整个视频或者为了尝试找到 moov 而浪费时间发起额外的请求。具有流优化视频的网站的瀑布图如下:

mp4-fast-start

开始位置包含 moov 的文件,视频会下载播放得更快,带来的结果是更好的用户体验。

如何优化 MP4 视频以获得更快的流传输速度

我们已经知道为了优化视频的 HTML5 流传输,你需要重新组织 MP4 原子,以便 moov 原子处于开始位置。 那么我们如何做呢?大部分视频编码软件都有一个 **“针对网页优化”**或 **“针对流传输优化”**的选项来做这件事。当你创建视频时,你需要查看你视频编码设置以确认它是优化的。例如,在下面的屏幕截图中,我们可以看到开源视频编码工具 Handbrake“Web Optimized” 选项,用来将 moov 原子放在开始位置:

handbrake

如果你从原始资源视频创建 MP4 文件,这是一个可行的解决方案,但是如果你已经有一个 MP4 文件了呢?

你可以重组已存在的视频来优化它在网页流传输的表现。例如,开源的命令行视频编码工具 FFMpeg 就可以重组 MP4 文件的结构来让 moov 原子处于开始位置。不同于初始编码视频那样非常耗时和占用 CPU ,重组文件很容易操作。而且,他不会对原始视频质量造成任何影响。以下是用 ffmpeg 来优化一个叫做 input.mp4 的视频文件流传输的例子,导出的视频叫做 output.mp4

ffmpeg -i input.mp4 -movflags faststart -acodec copy -vcodec copy output.mp4

-movflags faststart 参数告诉 ffmpeg 把 MP4 视频的原子们重新排序以使得 moov 位于开始位置。我们同样指示 ffmpeg 拷贝视频和音频数据而不是重新编码,所以没有任何改变。

为了 Rigor 网站的顾客,我们向 Rigor 优化添加了新的检测工具。我们的性能分析和优化产品,可以检测还没有针对 HTM5 视频流传输进行优化的 MP4 文件。如果你只是想快速检测自己网站,你可以用 我们免费的性能报告

总结

不管你是将 GIF 动画转化为 MP4 视频片段,还是已经有一堆 MP4 视频,如果你优化文件结构,你都可以使得这些视频加载并开始播放de更快。通过重排原子让 moov 原子处于开始位置,使得浏览器跳过发送额外的 HTTP range request,避免尝试定位 moov 原子。这允许浏览器立即开始流视频传输。你通常可以在最初创建视频时配置一个选项,以优化流传输。 如果你已有文件,则可以使用 ffmpeg 之类的程序对文件进行重排,而不更改其内容。

如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏