转码 Media Source Extensions™ 资源
在使用 Media Source Extensions 时,很可能需要对资源进行条件处理,然后才能进行流式传输。本文将介绍相关要求,并展示一个可用于适当编码资源的工具链。
入门
- 第一步也是最重要的一步是确保您的文件包含用户浏览器支持的容器和编解码器。
- 根据编解码器的不同,您可能需要对文件进行分段,以符合 ISO BMFF 规范。
- (可选) 如果您决定使用 HTTP 上的动态自适应流 (DASH) 进行自适应比特率流式传输,则需要将资源转码为多种分辨率。大多数 DASH 客户端都期望有一个对应的 Media Presentation Description (MPD) 清单文件,该文件通常在生成多种分辨率的资源文件时生成。
下面我们将介绍所有这些步骤,但首先让我们看看一个可以轻松完成此操作的工具链。
示例媒体
如果您想按照此处列出的步骤进行操作,但没有媒体可以进行实验,可以下载 《大朋兔》预告片。大朋兔由 Blender Foundation 拥有版权,并根据 知识共享署名 3.0 许可授权。在本教程中,您将看到文件名 trailer_1080p.mov,这就是下载的文件。
所需工具
在使用 MSE 时,以下工具是必备的
- ffmpeg — 一个命令行工具,用于将媒体转码为所需格式。您可以在 下载 FFmpeg 页面 下载适用于您系统的版本。从存档文件中提取可执行文件,并将其位置添加到您的 PATH 语句中。macOS 用户也可以使用 homebrew 安装 ffmpeg。
- Bento4 — 一套用于获取资源元数据和创建 DASH 内容的命令行工具。要安装,您需要根据您的操作系统和偏好,从提供的项目文件/源文件自行构建/编译应用程序。有关更多详细信息,请参阅 构建说明,或下载 预编译文件。将
bin目录的内容放在与 ffmpeg 相同的位置。 - python2 — Bento4 使用它。
在进入下一步之前,请确保成功安装了这些工具。
示例媒体应放置在 Bento4 的 utils 目录中,并在该目录中进行操作。
注意: 由于许可原因,预编译的 ffmpeg 不包含 libfdk_aac。Bento4 默认使用它,因此您可能需要编译 ffmpeg。如果您不需要它,请在 mp4-dash-encode.py 命令后面加上 --audio-codec=aac。
容器和编解码器支持
如 MSE 规范第 1.1 节:目标中所述,MSE 的设计不要求支持任何特定的媒体格式或编解码器。虽然理论上如此,但浏览器对特定容器/编解码器组合的支持各不相同。
要检查浏览器是否支持特定容器,可以将 MIME 类型字符串传递给 MediaSource.isTypeSupported() 方法。
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 不进行转码。相反,它只会复制音频和视频轨道,而不会执行任何转码,这比转码要快得多。
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。
ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy -movflags frag_keyframe+empty_moov bunny_fragmented.mp4
如果您已经有一个 MP4,但未正确分段,您可以再次使用 ffmpeg。
ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov fragmented.mp4
在两种情况下,Chrome 可能需要设置额外的 movie 标志。
-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 文件。
运行以下命令
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 上开始自适应比特率流式传输了。