跳到内容

媒体源扩展

基本概念

媒体源扩展规范定义了一组类,允许客户端实现自己的加载、缓冲和变体切换行为,而不是要求用户代理处理这些行为。

客户端 fetch() 媒体初始化片段和媒体片段,通常是单个分段 MP4 文件WebM 文件的子集,并将这些片段附加到 SourceBuffer 对象中,该对象通过 MediaSource 对象与 HTMLMediaElement 关联。

相关类

MediaSource

(.idl, .h, .cpp)

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

(.idl, .h, .cpp)

SourceBuffer 接受初始化片段和媒体片段的缓冲区,然后将这些缓冲区解析成媒体轨道和媒体样本。这些样本在 SourceBuffer 内部(在其 SourceBufferPrivate 对象内)进行缓存,并按需排入特定于平台的解码器。这些样本的主要存储机制是 SampleMap,它根据每个样本的 DecodeTime 和 PresentationTime 对样本进行排序。对于支持帧重排的编解码器(通常是 h.264 和 HEVC 等 MPEG 视频编解码器),这两个时间可能会有所不同。

客户端通过 appendBuffer() 附加这些片段,这会设置一个内部 updating 标志,触发 "updatestart" 事件,随后在解析完成后触发 "updateend" 事件并清除 updating 标志。附加结果可以通过查询 buffered 属性或查询 audioTracksvideoTrackstextTracks 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

(.h, .cpp)

SourceBufferPrivate 是一个半抽象基类,它接受初始化片段和媒体片段缓冲区,使用特定于平台的解析器解析这些缓冲区,并将生成的样本排入特定于平台的解码器。SourceBufferPrivate 还负责在 SampleMap 中缓存已解析的样本。

MediaTime

(.h, .cpp)

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

(.h, .cpp)

SampleMap 是一种高性能的二叉树存储结构,用于存放 MediaSamples。

因为解码器通常要求帧按解码时间顺序入队,而许多媒体源扩展算法按演示时间顺序工作,所以 SampleMap 包含两个二叉树结构:一个 decodeOrder() 映射和一个 presentationOrder() 映射。