零成本提升视频服务器负载?我们可是认真的

视频编码

2018-12-07

随着Flash格式的衰落以及移动设备开发的增长,越来越多的内容使用HTML5视频呈现。开发者可以使用HTML5视频替换GIF的方式来优化业务。另外,视频文件本身也有很多的优化方案,开发者可以基于这些方案来优化视频的性能。 对于HTML5视频文件最重要的优化在于视频流。未经优化的视频流会导致上百毫秒的播放延迟以及大量带宽浪费。本文将向你解释如何优化视频文件以获取更快的视频流。

# MP4视频流如何工作

不同于Flash视频的基于插件的播放方式,HTML5视频是一种跨浏览器的播放方式。2016年起,MP4容器文件(简称为MP4视频)中的H.264编码视频即作为在线HTML5视频的标准格式。我们在这里讨论的优化HTML5视频,其实我们真正想要做的是对MP4视频文件进行优化从而更快将视频内容呈现给用户。因此优化的关键在于我们需要了解MP4文件格式以及流媒体播放原理。 MP4文件由多个被称为原子的数据块组成。原子存储的数据包括字幕,章节,以及必要的音频数据和视频数据。记录了音频视频原子位置,视频尺寸,播放帧率这类信息的元数据(meta data),存储在一个名为moov的特殊原子中。开发者可以认为moov原子是MP4文件的内容表。 播放一个视频时,播放器会从MP4文件中找到moov原子,通过解析该原子获取音视频的起始然后开始播放。不幸的是视频文件中的原子可以以任何顺序组合,播放器开始的时候并不知道moov原子的位置。对于已经完整获取视频文件来说检索moov的工作还算轻松,但是在尚未完整获取的视频文件的播放场景中,例如HTML5视频流这种播放场景。这就是视频流的关键!无需下载完整视频即可播放。 视频流播放时,播放器请求视频,随后开始获取文件。播放器会查看moov原子是否就在文件头的附近。如果moov原子不在文件头附近,则要么播放器下载完整视频文件去查找moov,要么播放器下载视频文件尾部的一小块数据,从这段数据中查看moov是否存在。 这种查找moov的工作是耗时且浪费带宽的。不幸的是,只有找到moov才能开始播放视频。下面的截图显示了播放器播放一个未经优化的HTML5视频流文件的瀑布流程图: undefined

从上图可以看到,开始播放视频前播放器发起了3个请求。 首次HTTP range请求,拿到头部的552KB数据。我们称为206 Partial Content HTTP响应,播放器查看请求回来的视频头部数据(部分视频文件而非完整视频文件)。然而moov原子不在这段数据中,所以播放器无法播放。 接下来,播放器再次发起range请求获取视频尾部的21KB数据。这段数据中就包含了moov原子,告知播放器音视频流的起始点。 最后,播放器发起第三次也是最后一次请求以获取音视频数据,开始播放视频。 本例中浪费了半兆带宽,延时210毫秒后才开始播放视频!原因仅仅是播放器无法找到moov原子。 如果你的服务器不支持HTTP range请求的话情况将会更糟糕;播放器无法下载部分文件只能下载完整文件来查询moov。这也是为什么需要开发者优化服务器,支持部分下载。 理想的方案是调整为HTML5视频流播放的MP4视频的文件格式,将moov原子放在尽可能视频文件中靠前的位置。采用这种方法可以让播放器避免下载整个文件或是浪费时间发起额外请求以获取moov。下面的截图显示了播放器播放一个优化后的HTML5视频流文件的瀑布流程图: undefined

将moov放在文件开始后,视频加载和播放的速度变快了,用户体验更好了。

# 如何优化MP4

我们看到优化HTML5视频流只需重组MP4原子,将moov原子置于文件首部。那么我们如何重组MP4文件?绝大多数视频编码软件都有"optimize for web"或"optimize for streaming"选项可以做到这点。你只需在开始编码前确定配置已经包含该优化项。下图来自于开源视频编码软件 – Hndbrake。 undefined

该解决方案适用于使用原始视频源创建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放在文件起始位置。参数还定义拷贝而不是重新编码音视频数据,因此不会改变任何内容。

# 实际效果

以上内容翻译自"Optimizing MP4 Video for Fast Streaming"。那么实际效果如何?我们用实际数据进行说明。

# 优化原理

优化视频格式,减少连接次数。

# 实验环境

测试样本:优化前视频/优化后视频 服务器:一个简单的带宽限制的http服务器 测试页面:标准的HTML5视频页面 PC环境:Ubuntu播放器,浏览器 移动环境:手机

# 实验结果

2018-12-07 10-10-23屏幕截图.png

# 实验结论

优化后,每个视频客户端最少可以减少 50% 的连接数

# 实际收益

不考虑带宽不足,只考虑连接数的限制情况下,优化后,每个视频服务器,可以多服务 1 倍的用户