媒体源扩展¶
基本概念¶
媒体源扩展规范定义了一组类,允许客户端实现自己的加载、缓冲和变体切换行为,而不是要求用户代理处理这些行为。
客户端 fetch()
媒体初始化片段和媒体片段,通常是单个分段 MP4 文件或WebM 文件的子集,并将这些片段附加到 SourceBuffer 对象中,该对象通过 MediaSource 对象与 HTMLMediaElement 关联。
相关类¶
MediaSource¶
MediaSource 有两个作用:
- 创建 SourceBuffer 对象。
- 将这些 SourceBuffer 对象与 HTMLMediaElement 关联。
一旦创建,客户端可以通过 isTypeSupported(type)
查询容器和编解码器支持,通过 addSourceBuffer(type)
创建 SourceBuffer 对象,显式设置 MediaSource 的 duration
,并通过 endOfStream(error)
发出流结束信号。
在创建任何 SourceBuffer 对象之前,MediaSource 必须与 HTMLMediaElement 关联。MediaSource 可以直接设置为 HTMLMediaElement 的 srcObject
。或者,DOMURL 的扩展允许从 MediaSource 对象创建 ObjectURL,并且该 ObjectURL 可以设置为 HTMLMediaElement 的 src
。
当 MediaSource 对象成功与 HTMLMediaElement 关联时,会触发 "sourceopen"
事件;当解除关联时,会触发 "sourceclose"
事件。MediaSource 对象的状态可以通过其 readyState
属性查询。
SourceBuffer¶
SourceBuffer 接受初始化片段和媒体片段的缓冲区,然后将这些缓冲区解析成媒体轨道和媒体样本。这些样本在 SourceBuffer 内部(在其 SourceBufferPrivate 对象内)进行缓存,并按需排入特定于平台的解码器。这些样本的主要存储机制是 SampleMap,它根据每个样本的 DecodeTime 和 PresentationTime 对样本进行排序。对于支持帧重排的编解码器(通常是 h.264 和 HEVC 等 MPEG 视频编解码器),这两个时间可能会有所不同。
客户端通过 appendBuffer()
附加这些片段,这会设置一个内部 updating
标志,触发 "updatestart"
事件,随后在解析完成后触发 "updateend"
事件并清除 updating
标志。附加结果可以通过查询 buffered
属性或查询 audioTracks
、videoTracks
和 textTracks
TrackList 对象来查看。
MediaSourcePrivate¶
(.h)
MediaSourcePrivate 是一个抽象基类,允许 MediaSource 通过平台边界与特定于平台的 MediaSource 实现进行通信。
当 GPU 进程启用时,WebContent 进程中的 MediaSourcePrivate 通常是 MediaSourcePrivateRemote,它将命令和属性跨越 WebContent/GPU 进程边界传递。
对于 Apple 端口,MediaSourcePrivate 通常是 MediaSourcePrivateAVFObjC。
对于基于 GStreamer 的端口,MediaSourcePrivate 通常是 MediaSourcePrivateGStreamer。
在运行 DumpRenderTree/WebKitTestRunner 时,可以启用“模拟”MediaSourcePrivate,并创建 MockMediaSourcePrivate。这对于编写平台无关的测试非常有用,这些测试直接操作平台无关的 MediaSource 和 SourceBuffer 对象。
SourceBufferPrivate¶
SourceBufferPrivate 是一个半抽象基类,它接受初始化片段和媒体片段缓冲区,使用特定于平台的解析器解析这些缓冲区,并将生成的样本排入特定于平台的解码器。SourceBufferPrivate 还负责在 SampleMap 中缓存已解析的样本。
MediaTime¶
MediaTime 是一个有理数时间类,用于处理媒体文件中常见的时间值。MediaTime 的单位是秒。
MP4 和 WebM 等媒体容器将时间值表示为“时间基准”和“时间值”之间的比率。这些值不一定能精确地表示为浮点值,否则会产生累积舍入误差。例如,视频格式中常见的帧速率是 29.97fps,然而该值是 30000/1001 的近似值。因此,包含 29.97fps 内容的视频轨道的媒体文件将声明一个 30000 的“时间基准”标量,并且每个帧将具有 1001 的“时间值”持续时间。
媒体源扩展算法对样本之间的小间隙非常敏感,由于其有理数行为,MediaTime 通过避免浮点舍入误差来保证样本的连续性。
MediaTime 提供了方便的方法来从浮点值转换 (createTimeWithDouble()
) 和转换为浮点值 (toDouble()
)。
MediaSample¶
(.h)
MediaSample 是一个抽象基类,表示从媒体片段解析出的样本。MediaSample 具有 presentationTime()
、decodeTime()
和 duration()
,每个都是 MediaTime 值,用于在 SampleMap 中相互关联地排序这些样本。对于支持帧重排的编解码器,每个样本的 presentationTime()
和 decodeTime()
可能会有所不同。
SampleMap¶
SampleMap 是一种高性能的二叉树存储结构,用于存放 MediaSamples。
因为解码器通常要求帧按解码时间顺序入队,而许多媒体源扩展算法按演示时间顺序工作,所以 SampleMap 包含两个二叉树结构:一个 decodeOrder()
映射和一个 presentationOrder()
映射。