远程播放 API

W3C 候选推荐标准草案

关于本文件的更多信息
本版本:
https://www.w3.org/TR/2024/CRD-remote-playback-20240430/
最新发布版本:
https://www.w3.org/TR/remote-playback/
最新编辑草案:
https://w3c.github.io/remote-playback/
历史:
https://www.w3.org/standards/history/remote-playback/
提交历史
实现报告:
https://www.w3.org/wiki/Second_Screen/Implementation_Status#Remote_Playback_API
编辑:
Mark Foltz (Google)
前任编辑:
Mounir Lamouri (Google)
Anton Vayvod (Google)
反馈:
GitHub w3c/remote-playback (拉取请求, 新问题, 打开的问题)
测试套件
GitHub web-platform-tests/remote-playback
w3c-test.org/remote-playback/

摘要

本规范定义了一个扩展 HTMLMediaElement 的 API,使网页能够控制媒体的远程播放。

本文件状态

本节描述了本文件发布时的状态。当前 W3C 发布的技术报告及其最新修订可在 W3C 技术报告索引(https://www.w3.org/TR/)中找到。

本文件由 Second Screen 工作组 作为 候选推荐标准草案发布,并采用 推荐流程

本文件基于工作组关于在外部展示型显示设备上呈现网页内容的经验,并在适当情况下复用了 Presentation API 规范中的设计模式和考虑[PRESENTATION-API]。

尽管本文件仍是 进行中的工作 并可能发生变化,工作组认为 API 的接口较为稳定。大部分在 问题跟踪器上的剩余问题目前认为是次要的,除了 第 41号 问题。

41号 问题 讨论了远程播放设备有望支持的媒体播放功能集合。工作组将进一步征求开发者反馈和实现经验,以识别这些功能在远程播放时的互操作性问题,并会根据收到的反馈进一步明确规范。

对于其他问题或建议,可以 提交 bug 或 向 邮件列表发送邮件。如有拼写等小编辑错误,欢迎提 pull request。

工作组欢迎所有人审查本文件,并将与 W3C 内相关小组合作,在无障碍、国际化、隐私、安全和技术架构原则等方面进行横向评审。

未有任何特性被标记为风险中

Second Screen 工作组将在候选推荐周期内为远程播放 API 制定测试套件,并准备实现报告。为使规范升级为提议推荐,每项特性必须有两个独立且可互操作的实现,如候选推荐标准退出标准章节所述。

作为候选推荐标准发布,并不意味着 W3C 及其成员的认可。候选推荐草案整合了工作组计划纳入后续候选推荐快照的所有变更。

本文件为草案,可能随时被其它文件更新、替换或废弃。不应将本文件作为正式引用。

本文件由工作组根据 W3C 专利政策 制定。 W3C 保持一份 与交付物相关的专利公开清单, 该页面还包含专利披露说明。如个人实际知悉其认为包含 必要权利要求的专利,则需按 W3C 专利政策第6节 披露信息。

本文件受 2023年11月3日W3C流程文档 管理。

1. 一致性

本规范中,被标记为“非规范性”(non-normative)的部分以及所有编写指南、图示、示例与注释,均非规范性内容。除此之外的内容均为规范性内容。

本文档中的关键字 MAYMUSTMUST NOTRECOMMENDEDSHOULD,应根据 BCP 14 [RFC2119] [RFC8174] 在且仅在全部为大写字母时,如上述用法那样进行解释。

本规范规定的符合性标准,仅适用于一种产品:实现本规范中相关接口的用户代理(user agent)。

以 ECMAScript 暴露本规范定义 API 的实现,必须依据 Web IDL 规范中 ECMAScript Bindings 的要求实现之 [WEBIDL]。

2. 简介

本节为非规范性内容。

本规范旨在让远程播放设备(如联网电视、投影仪或仅支持音频的扬声器)对网页可用,并兼容通过有线(HDMI、DVI 或类似接口)和无线技术(Miracast、Chromecast、DLNA、AirPlay或类似)连接的播放设备。

屏幕尺寸有限或扬声器不响亮的设备,无法为更多听众(如会议室的同事或家庭聚会的朋友)播放媒体内容。把媒体内容播放到外部更大和/或声音更大的远程播放设备有助于提升感官体验和媒体影响力。

本规范核心在于:允许作为 浏览上下文 的页面,发起并控制选定远程播放设备上的特定媒体元素的远程播放。远程播放的发起和控制方式留给 UA(User Agent)决定,以便兼容多种类型的远程设备。例如,通过 HDMI 或 Miracast 连接远程播放设备时,作为浏览上下文 的同一个 UA 会渲染远程媒体,但它可调用操作系统能力将内容输出至外部远程播放设备,而非本机播放。在这种“媒体镜像”场景下,浏览上下文与媒体播放器都在同一 UA 上运行,输出通过操作系统路由到远程播放设备。本规范对以这种方式连接的设备无特殊要求。

如果远程播放设备能够播放媒体、与浏览上下文通信,但无法自行获取媒体时,浏览上下文需获取媒体数据并传给远程播放设备渲染,这情况常称为媒体远距传输

如果远程播放设备既可获取又可播放媒体,并能与浏览上下文通信,则浏览上下文无需获取或渲染远程媒体。此时 UA 等同于代理,将必要的数据如媒体源传递给远程播放设备,由其自行播放,通常称为媒体推送。未来可通过定义标准协议强化这种连接方式,便于远程播放设备实现相关消息传递功能。

此处定义的 API,旨在为上述任一路径连接的 远程播放设备 服务。

3. 用例与需求

本节为非规范性内容。

本规范的用例和需求已单独整理,可点击这里查看。

4. 示例

本节展示了突出远程播放 API 主要特性的代码示例。其中 player.html 为播放页、负责控制远程播放,media.ext 为被远程播放的媒体文件。页面和媒体同样来自 https://example.org 域。更多细节请参阅代码示例内注释。

4.1 监控远程播放设备可用性示例

<!-- player.html -->
<!-- 支持远程播放的自定义控制视频元素 -->
<video id="videoElement" src="https://example.org/media.ext" />
<button id="deviceBtn" style="display: none;">选择设备</button>
<script>
  // 只要有一个远程播放设备,就显示“选择设备”按钮。
  const deviceBtn = document.getElementById("deviceBtn");
  const videoElem = document.getElementById("videoElement");

  function availabilityCallback(available) {
    // 依赖设备可用性,决定是否显示设备选择按钮。
    deviceBtn.style.display = available ? "inline" : "none";
  }

  videoElem.remote.watchAvailability(availabilityCallback).catch(() => {
    // 平台不支持设备可用性监控,仅在调用 remote.prompt() 后发现可用远程设备。
    // 简单起见,可以直接显示按钮;或者,自行实现按钮的第三种显示状态。
    deviceBtn.style.display = "inline";
  });
</script>

4.2 启动远程播放视频示例

<!-- player.html -->
<script>
  deviceBtn.onclick = () => {
    // 请求用户选择远程播放设备。
    videoElem.remote.prompt()
      // 更新界面,并监听连接状态。
      .then(updateRemotePlaybackState);
      // 如果未选择设备、取消了 UI 或未找到屏幕,不会触发 then。
  };
<script>

4.3 监控远程播放状态变化

<!-- player.html -->
<script>
  // 用户代理可能会自行发起远程播放,因此请检查初始状态以同步界面。
  if (videoElem.remote.state == "disconnected")
    switchToLocalUI();
  else
    switchToRemoteUI();

  videoElem.remote.onconnecting = switchToRemoteUI;
  videoElem.remote.onconnect = switchToRemoteUI;
  videoElem.remote.ondisconnect = switchToLocalUI;

  // 处理连接中/已连接状态。多次调用也没有影响。
  function switchToRemoteUI() {
    // 用于指示当前为“连接中”或“已连接”状态。通常只需展示播放控制即可,视频元素可隐藏。
    videoElem.style.display = "none";

    // 停止远程设备可用性监控。
    videoElem.remote.cancelWatchAvailability();
  };

  function switchToLocalUI() {
    // 恢复显示视频元素。
    videoElem.style.display = "inline";
    // 重新开始监控远程设备可用性。
    videoElem.remote.watchAvailability(availabilityCallback);
  };
<script>

5. API

5.1 常见用法

本地播放设备,指的是运行浏览上下文的设备及该设备默认的视频/音频输出。

本地播放设备 可能有额外输出,比如外接显示器或扬声器/耳机。只要选择输出的动作发生在用户代理外的系统层面,根据本规范,播放仍然视为在本地播放设备上完成。

远程播放设备 指除了本地播放设备以外,浏览上下文可用于播放媒体的任何其他设备。

媒体元素状态,指的是页面和/或用户通过用户代理实现所能观测到的单一 媒体元素 所有属性集合。本规范新引入的属性,为方便起见,不计入媒体元素状态

例如,paused 属性或媒体元素默认控件上对应的暂停/恢复按钮,反映的都是媒体元素状态

本地播放状态,指用户代理针对特定 媒体元素状态的实现,用于在本地播放设备上播放。

远程播放状态,指用户代理针对特定 媒体元素状态的实现,用于在对应远程播放设备上播放。

为获得良好用户体验,媒体元素状态state 变化时不应意外改变。同理,远程播放状态 也应与 媒体元素状态保持同步,比如媒体在 远程播放设备上暂停时,用户和页面都能直接感知该暂停。

本规范中所述任务的任务源媒体元素事件任务源

5.2 RemotePlayback 接口

WebIDL[Exposed=Window]
interface RemotePlayback : EventTarget {
  Promise<long> watchAvailability(RemotePlaybackAvailabilityCallback callback);
  Promise<undefined> cancelWatchAvailability(optional long id);

  readonly attribute RemotePlaybackState state;

  attribute EventHandler onconnecting;
  attribute EventHandler onconnect;
  attribute EventHandler ondisconnect;

  Promise<undefined> prompt();
};

enum RemotePlaybackState {
  "connecting",
  "connected",
  "disconnected"
};

callback RemotePlaybackAvailabilityCallback = undefined(boolean available);

RemotePlayback 对象允许页面检测 远程播放设备的可用性、连接并控制其播放。

RemotePlaybackState 枚举表示与远程播放设备的可能连接状态。

RemotePlaybackAvailabilityCallback 用于返回当前 远程播放设备可用性

5.2.1 监控远程播放设备可用性

RemotePlaybackAvailabilityCallback 是页面获取对应媒体元素 远程播放设备可用性的方式。如果用户代理能在后台 监控远程播放设备列表 (无需待处理 prompt() 请求), 则用户代理 必须 实现如下 RemotePlaybackAvailabilityCallback 行为。否则,watchAvailability() 返回的 promise 必须NotSupportedError 被拒绝。

5.2.1.1 可用性回调集合

用户代理 必须 记录通过 watchAvailability() 方法注册到每个媒体元素可用性回调集合。每个 RemotePlayback 对象的可用性回调集合由一组元组 (callbackId, callback) 组成,初始为空。其中:

  1. callbackId 是在给定 浏览上下文 所有 watchAvailability() 返回的唯一正整数;
  2. callbackRemotePlaybackAvailabilityCallback 对象。

每个媒体元素对应且仅对应一个 RemotePlayback 对象, 因此媒体元素的可用性回调集合 与其remote属性指向的 RemotePlayback对象的可用性回调集合一致。

所有已知 RemotePlayback 对象的 可用性回调集合 合并后,被称为 全局可用性回调集合

5.2.1.2 可用远程播放设备列表

用户代理 必须 维护一个 可用远程播放设备列表。该列表包含 远程播放设备,并基于特定实现的发现机制构建,内容为最近一次 监控远程播放设备列表 算法结果,若该算法未运行过则为空。

用户代理 可以 不支持持续运行 监控远程播放设备列表 算法,比如出于平台或功耗限制。在这种情况下,watchAvailability() 返回的 promise 必须NotSupportedError 被拒绝; 此时全局可用性回调集合为空,监控可用远程设备算法只会作为发起远程播放算法的一部分运行。

全局可用性回调集合非空时,用户代理 必须 持续监控远程播放设备列表,以便页面通过回调实时获得最新状态,只在有设备时提供远程播放。

用户代理应尽量避免在不必要时监控远程播放设备列表,以满足 节能非功能性需求。例如当全局可用性回调集合为空,或者所有有媒体元素且可用性回调非空的页面均为后台页时,可不运行监控算法。

某些 远程播放设备 由于功能、安全性或硬件限制,仅能播放部分媒体资源,比如只支持某些视频/音频格式的机顶盒、智能电视或网络扬声器。能合理确保某媒体资源远程播放可在该设备上成功播放的设备,称为 兼容远程播放设备

用户代理可以利用 srclang 属性,作为 track 元素的文本轨道语言提示,以辅助选择兼容远程播放设备

用户代理用于查找兼容远程播放设备时参考的媒体资源集合,称为 可用性资源集合

用于在选中远程播放设备发起远程播放媒体资源,称为 远程播放源。远程播放源必须属于媒体元素的可用性资源集合

可用性资源集合选择远程播放源的机制取决于实现,但用户代理应该将集合中的每个资源都视为候选远程播放源

针对某设备选择远程播放源的算法由用户代理和所支持的远程播放设备类型决定。例如在媒体镜像场景,用户代理可直接使用HTMLMediaElement资源选择算法;而若用媒体远距传输媒体推送,最优源可能取决于目标设备的获取与播放能力。

如果用户代理无法确定适合远程播放设备远程播放源建议用户代理把可用性资源集合中所有资源的元信息(如扩展 MIME 类型)发给设备,由其自行运行资源选择算法选定远程播放源

对于媒体元素,当可用远程播放设备列表为空, 或其中没有与 可用性资源集合中任何源兼容的设备, 则 远程播放不可用。否则称为可用。如果远程播放不可用则布尔值取 false,可用则为 true,称为媒体元素的可用性

若用户代理停止 监控远程播放设备列表 (如因用户操作或省电需求),应 应该false 调用所有 全局可用性回调集合 里的回调,以便页面及时调整用户体验。同时 把全部媒体元素的 可用性 设为 false,这样若将来恢复监控,可正确传播可用性信息。

5.2.1.3 获取 远程播放设备可用性信息

当调用 watchAvailability() 方法时,用户代理 必须 按如下步骤执行:

输入
callback,用于获取可用性信息的回调函数。
输出
promisePromise
  1. promise 为一个新的 Promise
  2. 返回 promise,并继续执行下列步骤:
  3. 如果该 disableRemotePlayback 属性存在于 媒体元素 上,拒绝 promise 并抛出 InvalidStateError ,中止所有剩余步骤。
  4. 如果用户代理无法在整个 浏览上下文 生命周期内 持续监控所有可用远程播放设备列表 (例如用户禁用了该功能),则并行执行如下步骤:
    1. 标记 promise 完成。
    2. 排队任务,以 false 参数调用 callback
    3. 中止所有剩余步骤。
  5. 如果用户代理无法持续 监控远程播放设备列表 ,但可在 发起远程播放 时短暂监控,则:
    1. NotSupportedError 异常拒绝 promise
    2. 中止所有剩余步骤。
  6. callbackId 为该 浏览上下文 内此前返回的所有 callbackIds 中唯一的正整数。
  7. 创建元组 (callbackId, callback), 并加入该 媒体元素可用性回调集合
  8. callbackId 完成 promise,并并行执行下列步骤:
    1. 排队任务,以 媒体元素可用性 的当前值作为参数调用 callback
    2. 若用户代理当前未 监控远程播放设备列表, 立即运行该算法。

一个简单的 callbackId 分配算法是在每个 浏览上下文 维护计数器,并在第 6 步递增。

为避免泄漏可用于指纹识别用户的信息,用户代理不得分配基于浏览器配置文件或某 远程播放设备的持久性信息的 callbackId
5.2.1.4 监控可用远程播放设备列表

如果 可用性回调集合非空,或存在尚未处理的 发起远程播放请求,则用户代理必须通过以下步骤监控可用远程播放设备列表

  1. 检索可用远程播放设备(采用具体实现机制),记为 newDevices
  2. 针对该 浏览上下文 已知的每个 媒体元素
    1. disableRemotePlayback 属性存在于 mediaElement 上,终止本元组所有剩余步骤,转入下一个。
    2. 设置 newAvailabilityValue 为使用 newDevices 列表(而不是 可用远程播放设备列表)计算出的该 媒体元素的可用性值。
    3. 若当前 可用性 不等于 newAvailabilityValue,则对该元素可用性回调集合中的每个 (callbackId, callback)
      1. 排队任务,以 newAvailabilityValue 作为参数调用 callback
  3. newDevices 更新 可用远程播放设备列表
5.2.1.5 停止监控远程播放设备可用性

当调用 cancelWatchAvailability() 方法时,用户代理 必须 按如下步骤运行:

输入
id,回调标识符。
输出
promisePromise
  1. promise 为一个新的 Promise
  2. 返回 promise,并继续执行如下步骤:
  3. 如果 disableRemotePlayback 属性存在于 媒体元素 上,拒绝 promise,抛出 InvalidStateError,中止所有剩余步骤。
  4. 如果参数 idundefined,则清空 可用性回调集合
  5. 否则,如果 id可用性回调集合 中任何 callbackId 相符,从集合中移除该项。
  6. 否则,拒绝 promise 并抛出 NotFoundError,中止所有剩余步骤。
  7. 可用性回调集合 现为空且不存在未处理的 远程播放请求,为节能取消任何待处理的 监控远程播放设备列表 任务。
  8. 标记 promise 完成。
用户代理用于监控 远程播放设备 可用性并判定某设备与选定 可用性资源集合 的兼容性的机制,留给用户代理自行实现。

5.2.2 提示用户改变远程播放状态

当调用 prompt() 方法时,用户代理 必须 执行以下步骤:

输入
无,但算法涉及媒体元素、其 remote 属性及其 可用性资源集合
输出
一个 Promise
  1. promise 为一个新的 Promise
  2. 返回 promise 并继续并行执行下列步骤。
  3. 如果该 disableRemotePlayback 属性存在于 媒体元素 上,则拒绝 promise,抛出 InvalidStateError, 并终止所有剩余步骤。
  4. 如果此前针对同一个 媒体元素 或同一 浏览上下文 有未决的 prompt() promise,用户代理可以OperationError 拒绝 promise 并终止所有剩余步骤。
    设计理由:用户代理可能会出现一个只在媒体元素或整个浏览上下文独占的对话框。在这种情况下,如果调用了第二次 prompt() 则无法再弹出新的 UI。
  5. 如果文档的 活动窗口 没有 瞬时激活,用 InvalidAccessError 拒绝 promise 并终止这些步骤。
  6. 可选:如果用户代理已知某些 媒体元素远程播放不可行(不关联当前 state可用远程播放设备列表),用 NotSupportedError 拒绝 promise 并终止所有剩余步骤。
    例如,只支持 媒体推送 时,媒体元素的 source 不是能传递给 URL 的远程设备。
  7. 如果用户代理需要显示 可用远程播放设备列表,且未监控远程播放设备列表,则应并行运行上述监控算法。
  8. 如果远程播放 不可用,且在请求用户权限结束前仍不可用,则用 NotFoundError 拒绝 promise,并终止所有剩余步骤。
  9. 请求用户更改远程播放状态的许可。
    示例 UI 如允许用户选择新的 远程播放设备、在本地/远程设备间切换,或断开远程播放设备连接
    用户可能因其它目的已选择某 远程播放设备,如镜像屏幕或页面内容,用户代理可跳过设备选择 UI 直接进入下一步。
  10. 如果用户选择了某个 远程播放设备 device发起远程播放,用户代理 必须 依次执行下述步骤:
    1. remote 对象的 state 设为 connecting
    2. 标记 promise 完成。
    3. 排队任务,在媒体元素的 remote 属性上 派发名为 connecting 的事件,事件不冒泡且不可取消,无默认动作。
    4. 为该 媒体元素 建立与远程播放设备的连接 device

    选择 远程播放设备 即表示用户授权使用该设备。

  11. 否则如果用户选择断开 远程播放设备 device,用户代理 必须 执行以下步骤:
    1. 标记 promise 完成。
    2. 对该 device 执行 断开远程播放设备连接 算法。
  12. 否则,视为用户拒绝授权使用该设备,用 NotAllowedError 拒绝 promise 并隐藏用户代理展示的 UI。
具体 UI 和设备选择实现方式由用户代理确定。例如,可以弹出对话框让用户选择可用设备(同意授权),也可取消选择(拒绝授权)。大多数情况下,设备会提供带有本地化与文本方向信息的用户友好名称,用户代理建议采用该名称并结合其本地化和文本方向(如已知)。

5.2.3 state 属性

state 属性表示 RemotePlayback 连接的当前状态。它可以根据连接状态取 RemotePlaybackState 的以下值之一:

  • connecting 表示用户代理正在尝试与选定的 远程播放设备 发起远程播放。当 prompt() 返回的 promise 被 fulfill 时为初始状态。此状态下媒体元素的本地播放继续,媒体命令仍作用于 本地播放状态
  • connected 表示已从本地切换到远程播放,所有媒体命令现在都作用于 远程播放状态
  • disconnected 表示远程播放尚未 发起 或发起失败或已停止。所有媒体命令将作用于 本地播放状态。可以通过调用 prompt() 发起远程播放。

5.2.4 与远程播放设备建立连接

当用户代理要 与远程播放设备建立连接 时,必须执行以下步骤:

输入
remote,要连接的 RemotePlayback 对象。
device,要连接的 远程播放设备
  1. 如果 remotestate 不为 "connecting",中止所有剩余步骤。
  2. 请求将 remote 连接到 device。此步骤的具体实现由用户代理决定。
  3. 如果连接成功,排队任务 执行下列操作:
    1. remotestate 设为 "connected"。
    2. 派发事件,事件名为 connect,对象为 remote
    3. 同步当前 媒体元素状态远程播放状态。具体由用户代理实现。
  4. 如果连接失败,排队任务 执行下列操作:
    1. remoteremote playback state 设为 "disconnected"。
    2. 派发事件,事件名为 disconnect,对象为 remote

远程播放状态为 "connected" 时,用户代理 暂停媒体元素的本地音视频输出。

如果用户代理为媒体元素 暴露了用户界面(如用默认控件),则 通过图标或其他方式展示其 远程播放状态为 "connected"。

用户代理与 远程播放设备 连接、选择 远程播放源、发起播放等机制均由用户代理决定。连接很可能需要提供可双向通信的封装,能将媒体命令传递到远程播放设备并接收其播放状态,以同步 媒体元素状态远程播放状态(除非使用 媒体镜像)。
用户代理建议在可能时,将本地化和文本方向信息传递给 远程播放设备,以便设备依据用户偏好调整其用户界面和功能。如,可以用这些信息选择与用户代理一致的默认文本轨道,并设置 HTTP 的 Accept-Language 头来获取媒体资源。
connected 状态且内容正由 远程播放设备 渲染时,用户代理不应本地渲染媒体元素输出。

5.2.5 浏览器发起远程播放

用户代理可以支持通过浏览器连接到远程播放设备。如可在 暴露给用户的界面 中添加合适控件,或当开启系统级镜像时进行。此功能称为 浏览器发起远程播放。支持此能力的用户代理 仅在用户有明确意图(如点击浏览器按钮)时才发起远程播放。

若用户代理支持 浏览器发起远程播放state 属性必须反映与 远程播放设备 的当前连接状态。浏览器发起或终止远程播放时,必须按本规范相关算法派发事件。

浏览器即将发起媒体元素远程播放先将其 state 初始化为 "connecting",然后启动与远程播放设备的连接流程。

支持浏览器发起远程播放的用户代理应考虑其与其它媒体播放相关浏览器策略的交互,如哪些 媒体元素 被允许播放 以及后台播放优化策略。

5.2.6 媒体命令与媒体播放状态

HTMLMediaElement 接口在与 远程播放设备 建立连接后即与远程媒体交互。

state 为 "connected" 时,下述规则关联 本地播放状态媒体元素状态远程播放状态

若发送命令失败,用户代理 可以 断开远程播放设备连接

远程播放设备 可以只实现用户代理播放引擎能力的子集,且某些 HTMLMediaElement API 在远程播放时并不总是适用。在这种情况下,本地播放状态 应尽可能反映媒体命令远程播放后实际的 远程播放状态

例如,若连接到不支持 fastSeek()远程播放设备 后调用 fastSeek(),则 seeking 属性应保持为 false,不会触发 seeking 事件。

5.2.7 断开远程播放设备连接

当用户代理需要断开远程播放设备连接时,必须执行如下操作:

输入
remote,即要停止播放的 RemotePlayback 对象。
device,即要断开的 远程播放设备
  1. 如果 remotestatedisconnected,终止后续所有步骤。
  2. 排队一个任务 执行下列步骤:
    1. 请求将 remotedevice 断开。此步骤的实现由用户代理具体决定。
    2. 更改 remotestatedisconnected
    3. 派发事件,事件名为 disconnect,目标为 remote
    4. 同步当前 媒体元素状态本地播放状态。此步骤实现由用户代理决定。

如果远程播放设备在播放过程中被突然断开(例如断电或网络中断),用户代理应当先运行监控可用远程播放设备列表的步骤,然后再运行 断开远程播放设备连接的步骤。这样可确保在 disconnect 事件派发前,先唤起 可用性回调集合,便于页面更新提示用户无法恢复播放。

当用户代理请求远程设备停止播放媒体时,设备可能实际上并不会真的停止,这取决于用户代理和设备的实现。在这种情况下,停止远程播放仅意味着用户代理与之断开,媒体元素切换到 disconnected 状态。

5.2.8 事件处理器

下列表格为实现 RemotePlayback 接口的对象必须支持的事件处理器 及其对应的 事件类型,作为 事件处理器 IDL 属性:

事件处理器 事件类型
onconnecting connecting
onconnect connect
ondisconnect disconnect

5.3 HTMLMediaElement 的扩展

WebIDLpartial interface HTMLMediaElement {
  [SameObject] readonly attribute RemotePlayback remote;

  [CEReactions] attribute boolean disableRemotePlayback;
};

remote 属性 必须 返回与 RemotePlayback 的实例,该实例关联此 媒体元素

5.3.1 disableRemotePlayback 属性

某些页面可能希望禁用远程播放 某个媒体元素,例如他们更希望通过 PresentationRequest 在展示屏上展示整个文档。为支持该场景,audiovideo 元素的内容属性列表增加了一个新的 disableRemotePlayback 属性。

同时,disableRemotePlayback IDL 属性新增到 HTMLMediaElement 接口,用于反映各元素 disableRemotePlayback 内容属性的取值。 disableRemotePlayback IDL 属性 必须 反映同名内容属性的值。

5.3.2 禁用远程播放

如果 disableRemotePlayback 属性存在于 媒体元素 上,则用户代理 不得 远程播放该媒体元素,也不得展示相关的 UI。

disableRemotePlayback 属性添加到 媒体元素 时,用户代理必须执行 禁用远程播放的操作:

  1. 拒绝所有待处理的 RemotePlayback 方法返回的 promise,异常类型为 InvalidStateError
  2. 清空该媒体元素的 可用性回调集合
  3. 如果其 state 不是 disconnected,则为该媒体元素处于连接或连接中状态的 远程播放设备 执行 断开远程播放设备连接 算法。

6. 安全与隐私注意事项

本节为非规范性内容。

6.1 个人可识别信息

通过 watchAvailability() 方法提供的 callback 机制会暴露有关本地局域网中 远程播放设备 是否存在的一比特信息。这可以与其他信息结合用于指纹识别用户。然而,该信息也与用户本地网络环境有关,因此风险是有限的。此外,设计上页面不会获得 远程播放设备 的可读名称。

该 API 允许监控可用远程播放设备列表。用户代理如何判断 远程播放设备媒体 元素资源 的兼容性和可用性属于实现细节。如果用户代理将 媒体资源 与特定类型设备的可用性挂钩,可以被用于探测用户拥有哪些 远程播放设备,无需用户同意。

如果用户通过浏览器设置关闭了后台监控,则用户代理不应监控可用远程播放设备列表

6.2 用户界面指引

来源展示

当用户被请求授权使用 远程播放设备 用于更改远程播放状态步骤时,用户代理应明确展示请求来自哪个源(origin)。

展示请求远程播放的源可以帮助用户理解是哪个内容发起了请求,尤其当请求来自子导航上下文时。例如,嵌入内容可能试图诱导用户点击以发起不受欢迎的远程播放请求。

显示将被展示内容的源,有助于用户知道该内容是否来自潜在可信源 (如 https:),是否为已知或预期的网站。

6.3 设备访问

远程播放 API 抽象了对显示器“本地”含义的界定,也就是说,它会把网络可访问显示器也作为本地显示器暴露。本 API 要求页面获得访问任意显示设备的用户许可,以减轻如在他人可见屏幕上展示不想要内容等问题。

6.4 本地与远程播放设备之间的消息通信

本规范不会强制本地播放设备与 本地播放设备远程播放设备 之间的通信协议,但用户代理应保证双方之间的消息机密性与真实性。

6.5 安全上下文

远程播放 API 并不局限于 [SECURE-CONTEXTS],因为 它提供的功能常被用户代理原生支持,无论 浏览上下文 是否安全。用户代理可选择在非安全上下文中始终返回空列表,使本 API 只适用于 [SECURE-CONTEXTS]。

A. 候选推荐标准退出标准

为推进本规范成为建议标准,必须至少有两个独立、可互操作的实现,每项功能均须如此。每项功能可由不同产品实现,不要求所有功能由同一产品支持。此外,实现还必须展示对媒体远距传输媒体推送场景的支持, 可以在同一产品,也可以在不同产品中实现。

本标准的判断术语定义如下:

独立性
每一实现必须由不同主体开发,不能共享、复用或派生于另一符合要求实现的代码。与本规范实现无关的代码片段可不受此限制。
可互操作
能通过官方测试套件中的相应测试案例。
实现
用户代理,需满足:
  1. 实现本规范。
  2. 公开向公众提供。该实现可为正式产品,亦可为公开测试版、预览版本或“夜间构建”。非正式产品至少应连续支持相关特性不少于一个月,以证明其稳定性。
  3. 非实验性(即不是仅为通过测试套件而设计、未来不会用于普通用途的版本)。

B. 参考文献

B.1 规范性参考文献

[dom]
DOM 标准. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
HTML 标准. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[PRESENTATION-API]
Presentation API. Mark Foltz; Dominik Röttsches. W3C. 2023年10月16日. W3C 候选推荐标准. URL: https://www.w3.org/TR/presentation-api/
[RFC2119]
用于RFC中指示需求级别的关键词. S. Bradner. IETF. 1997年3月. 最佳当前实践. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119关键词大小写歧义. B. Leiba. IETF. 2017年5月. 最佳当前实践. URL: https://www.rfc-editor.org/rfc/rfc8174
[WEBIDL]
Web IDL 标准. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

B.2 参考性文献

[SECURE-CONTEXTS]
安全上下文. Mike West. W3C. 2023年11月10日. W3C 候选推荐标准. URL: https://www.w3.org/TR/secure-contexts/
[url]
URL 标准. Anne van Kesteren. WHATWG. Living Standard. URL: https://url.spec.whatwg.org/