用于媒体源扩展的资产转码

在使用媒体源扩展时,您可能需要在流式传输资产之前对其进行预处理。本文将带您了解要求,并向您展示可以用来适当地编码资产的工具链。

入门

  1. 第一步也是最重要的一步是确保您的文件包含用户浏览器支持的容器和编解码器。
  2. 根据编解码器,您可能需要对文件进行分段以符合 ISO BMFF 规范
  3. (可选) 如果您决定使用基于 HTTP 的动态自适应流式传输 (DASH) 进行自适应码率流式传输,则需要将资产转码为多种分辨率。大多数 DASH 客户端都期望有一个相应的媒体演示描述 (MPD) 清单文件,该文件通常在生成多种分辨率的资产文件时生成。

下面我们将介绍所有这些步骤,但首先让我们看一下可以使用来轻松完成此操作的工具链。

示例媒体

如果您想按照此处列出的步骤操作,但没有要试验的媒体,您可以获取 《大象席德》的预告片。大象席德由 Blender 基金会拥有版权,并根据 知识共享署名 3.0 许可证授权。在本教程中,您将看到文件名 trailer_1080p.mov,它是下载的文件。

所需工具

在使用 MSE 时,以下工具是必不可少的

  1. ffmpeg — 用于将您的媒体转码为所需格式的命令行实用程序。您可以在 FFmpeg 下载页面 下载适合您系统的版本。从存档文件中解压缩可执行文件,并将它的位置添加到您的 PATH 语句中。OSX 用户也可以使用 homebrew 安装 ffmpeg。
  2. Bento4 — 一套用于获取资产元数据和创建 DASH 内容的命令行实用程序。要安装,您需要根据您的操作系统和偏好从提供的项目文件/源文件自行构建/编译应用程序。有关更多详细信息,请参阅 构建说明。预构建文件在 这里。将 bin 目录的内容放在与 ffmpeg 相同的位置。
  3. python2 — Bento4 使用它。

在继续下一步之前,请确保已成功安装这些工具。

示例媒体应放在 Bento4 的 utils 目录中,并在其中进行操作。

注意:由于许可原因,预构建的 ffmpeg 不包含 libfdk_aac。Bento4 默认使用它,因此您需要根据需要编译 ffmpeg。如果您不需要它,请在 mp4-dash-encode.py 命令行中添加 --audio-codec=aac

容器和编解码器支持

MSE 规范第 1.1 节:目标 中所述,MSE 的设计并非要求支持任何特定媒体格式或编解码器。虽然在理论上这是正确的,但浏览器对特定容器/编解码器组合的支持有所不同。

要检查浏览器是否支持特定容器,您可以将 MIME 类型的字符串传递给 MediaSource.isTypeSupported() 方法

js
MediaSource.isTypeSupported("audio/mp3"); // false
MediaSource.isTypeSupported("video/mp4"); // true
MediaSource.isTypeSupported('video/mp4; codecs="avc1.4D4028, mp4a.40.2"'); // true

该字符串是容器的 MIME 类型,后面可以可选地跟随编解码器列表。虽然 MIME 类型很容易弄清楚,但我们可以使用 mp4info 实用程序来获取编解码器字符串。

目前,所有现代浏览器都支持具有 H.264 视频和 AAC 音频编解码器的 MP4 容器,而其他容器则不支持。

要将我们的示例媒体从 QuickTime MOV 容器转换为 MP4 容器,我们可以使用 ffmpeg。由于 MOV 容器中的音频编解码器已经是 AAC,视频编解码器是 h.264,因此我们可以指示 ffmpeg 不要执行转码。相反,它将只复制音频和视频轨道,而不会执行任何转码,这比必须转码快得多。

bash
ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy bunny.mp4

检查分段

为了正确地流式传输 MP4,我们需要使资产成为 ISO BMF 格式的 MP4。如果没有正确分段,任何给定的 MP4 文件都不能保证与 MSE 兼容。这意味着容器中的元数据是分散的,而不是集中在一起的。

要检查 MP4 文件是否为正确的 MP4 流,您可以再次使用 mp4info 实用程序列出 MP4 的原子。

注意:分段版本略大于原始版本,因为额外的元数据分散在整个文件中。这通常会导致文件大小增加 1% 或更少。

分段

如果您有一个尚未成为 MP4 的资产,ffmpeg 可以在转码过程中使用 -movflags frag_keyframe+empty_moov 命令行标志处理发出正确分段的 MP4。

bash
ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy -movflags frag_keyframe+empty_moov bunny_fragmented.mp4

如果您已经有一个 MP4 文件,但它没有正确分段,您也可以再次使用 ffmpeg

bash
ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov fragmented.mp4

在这两种情况下,Chrome 可能需要设置一个额外的电影标志

bash
-movflags frag_keyframe+empty_moov+default_base_moof

拥有正确分段的 MP4 文件就是开始所需的一切。如果您希望使用自适应码率流式传输,您将不得不创建多种分辨率的编码。虽然 MSE 足够灵活,允许您创建自己的实现,但强烈建议您使用现有的 DASH 客户端,因为 DASH 是一种规范良好的应用程序协议。

创建用于 DASH 的内容

假设您已通过 $PATH 访问了 ffmpeg 和 Bento4 的实用程序,您可以运行 Bento4 的 mp4-dash-encode.py Python 脚本,以生成多种分辨率的内容的多个编码。然后可以使用 Bento4 的 mp4-dash.py Python 脚本生成客户端所需的相应 MPD 文件。

运行以下命令

bash
python mp4-dash-encode.py -b 5 -v bunny_fragmented.mp4
python mp4-dash.py video_0*

这将输出以下文件

output
├── audio
│   └── und
├── stream.mpd
└── video
    ├── 1
    ├── 2
    ├── 3
    ├── 4
    └── 5

注意:mp4-dash-encode.py 不会显示 ffmpeg 错误消息。您可以通过指定 -d 选项来查看它。

注意:如果显示 "Invalid duration specification for force_key_frames: 'expr:eq(mod(n" 作为错误消息,请修改 mp4-dash-encode.py 并从 "-force_key_frames 'expr:eq(mod(n,%d),0)'" 中删除两个 "'"

摘要

视频编码完毕且自适应码率媒体生成后,您现在可以使用 DASH 和 MSE 开始在 Web 上进行自适应码率流式传输。