Copyright © 2024 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
本规范定义了一个扩展 HTMLMediaElement
的 API,使其能够从网页控制媒体的远程播放。
本节描述本文档 发布时的状态。当前 W3C 出版物列表以及本技术报告的最新修订版可在 https://www.w3.org/TR/ 的 W3C 技术 报告索引中找到。
本文档由第二屏幕工作 组使用 推荐标准轨道发布为 候选推荐标准草案。
本文档建立在该工作组将 Web 内容呈现在外部演示类显示器上的经验之上,并在适当情况下复用 Presentation API 规范中的模式 和设计考虑因素 [PRESENTATION-API]。
尽管本文档仍然是正在进行的工作,并且 可能发生变化,但工作组认为 API 接口已经 稳定。目前议题跟踪器上列出的其余大多数议题 在现阶段都被认为是次要问题,只有 议题 #41 除外。
议题 #41 讨论了远程播放 设备预期支持的一组媒体播放功能。该工作组将寻求更多开发者 反馈和实现经验,以确定这些功能在远程播放期间使用时 是否存在任何互操作性问题,并将 根据收到的反馈进一步澄清本规范。
对于其他议题或疑虑,可以提交错误报告,或 向邮件 列表发送电子邮件。对于拼写错误之类的小型编辑性更改, 欢迎发送拉取请求。
工作组邀请所有人审阅本文档,并将 与 W3C 的相关工作组合作,就 无障碍、国际化、隐私、安全和技术 架构原则开展横向审查。
尚未发现任何功能存在风险。
第二屏幕工作组将在候选推荐标准阶段为 Remote Playback API 开发测试套件,并 准备实现报告。要使本规范推进到 提议推荐标准阶段,必须证明每项功能都有两个独立且可互操作的实现, 具体要求详见候选推荐标准退出 标准一节。
作为候选推荐标准发布并不 表示获得 W3C 及其成员的认可。候选 推荐标准草案整合了 自上一份候选推荐标准以来工作组 打算纳入后续候选推荐标准快照的更改。
这是一份草案文档,可能随时由其他 文档更新、替换或废弃。除作为正在进行的工作外, 不宜以其他方式引用本文档。
本文档由一个 按照 W3C 专利 政策运作的工作组制作。 W3C 维护一份 与该工作组交付成果有关的所有专利 披露的公开列表; 该页面还包含 披露专利的说明。任何实际 知悉某项专利,并认为该专利包含 必要权利要求的个人, 必须按照 W3C 专利政策第 6 节披露相关信息。
本文档受 2023 年 11 月 3 日的 W3C 流程文档管辖。
除标记为非规范性的章节外,本规范中的所有创作指南、图示、示例和注释均为非规范性的。本规范中的其他所有内容均为规范性的。
本文档中的关键词 可以、必须、不得 、建议 和 应该 应按照 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释,但仅限于这些关键词像此处所示那样全部采用大写形式时。
本规范定义了适用于单一 产品的一致性标准:实现本规范所包含接口的用户代理。
使用 ECMAScript 暴露本 规范中定义的 API 的实现必须以与 Web IDL 规范中定义的 ECMAScript 绑定一致的方式实现这些 API [WEBIDL]。
本节为非规范性内容。
本规范旨在使联网电视、投影仪或纯音频扬声器等远程播放设备可供 Web 使用,并考虑通过有线 (HDMI、DVI 或类似技术)和无线技术(Miracast、 Chromecast、DLNA、AirPlay 或类似技术)连接的播放设备。
屏幕尺寸受限或扬声器音量较小的设备无法 向更多受众播放媒体内容,例如会议室中的一群 同事,或家中的朋友和家人。在外部更大和/或声音更响亮的远程播放 设备上播放媒体内容,有助于提高所播放媒体的 感知质量和影响力。
从本质上讲,本规范使充当 浏览 上下文的页面能够在选定的远程播放设备上发起和控制特定媒体元素的远程播放。 远程播放如何发起和控制由 UA 决定,以便 支持以多种不同方式连接的远程播放设备。例如,当远程播放 设备使用 HDMI 或 Miracast 连接时,充当 浏览 上下文的同一 UA 会渲染远程媒体。但是,它并非 在同一设备上播放媒体,而是可以使用操作系统提供的任何 方式来使用外部远程 播放设备。在这种情况下,浏览 上下文 和媒体播放器都运行在同一 UA 上,并使用操作系统 将播放器输出路由到远程播放设备。 这种情况通常称为媒体 镜像。本规范不对 以这种方式连接的远程播放设备提出任何要求。
如果远程播放设备能够播放媒体并 与浏览 上下文通信,但无法获取 媒体,则浏览 上下文需要获取媒体数据并 将其传递给远程播放设备进行渲染。这种情况 通常称为媒体远程传送。
如果远程播放设备能够获取并播放 媒体 并与浏览 上下文通信,则浏览 上下文无需获取或渲染远程媒体。在这种 情况下,UA 充当代理,通过传递媒体源等 必要数据,请求远程播放 设备自行播放媒体。这种情况通常称为媒体 投送。未来可以通过定义一种标准协议来增强 这种连接显示器的方式,以便传递 远程播放设备可以选择 实现的这类消息。
此处定义的 API 旨在供通过上述任一 方式连接到远程播放设备的 UA 使用。
本节为非规范性内容。
本规范的用例和要求记录在一份 单独的文档中,可在此处获取。
本节展示了一些代码示例,重点说明 Remote Playback API 主要
功能的用法。在这些示例中,
player.html 实现用于控制
远程播放的播放器页面,而 media.ext 是要
远程播放的媒体文件。页面和媒体均由域名
https://example.org 提供。有关更多详细信息,请参阅
代码示例中的注释。
<!-- player.html -->
<!-- 支持远程播放并带有自定义控件的 video 元素。 -->
<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>
<!-- player.html -->
<script>
deviceBtn.onclick = () => {
// 请求用户选择一个远程播放设备。
videoElem.remote.prompt()
// 更新 UI 并监视连接状态。
.then(updateRemotePlaybackState);
// 否则,用户取消了选择 UI,或未找到任何屏幕。
};
<script>
<!-- player.html -->
<script>
// 远程播放可能由用户代理发起,
// 因此请检查初始状态,以使 UI 与其同步。
if (videoElem.remote.state == "disconnected")
switchToLocalUI();
else
switchToRemoteUI();
videoElem.remote.onconnecting = switchToRemoteUI;
videoElem.remote.onconnect = switchToRemoteUI;
videoElem.remote.ondisconnect = switchToLocalUI;
// 同时处理 'connecting' 和 'connected' 状态。多次调用
// 不会执行任何操作。
function switchToRemoteUI() {
// 向用户指示当前状态为 'connecting' 或 'connected'。
// 例如,隐藏 video 元素,因为只需要控件。
videoElem.style.display = "none";
// 停止监视远程播放设备的可用性。
videoElem.remote.cancelWatchAvailability();
};
function switchToLocalUI() {
// 显示 video 元素。
videoElem.style.display = "inline";
// 再次开始监视设备可用性。
videoElem.remote.watchAvailability(availabilityCallback);
};
<script>
本地 播放设备是浏览 上下文运行所在的设备,以及 该设备具有的默认视频/音频输出。
远程播放设备 是除本地播放设备之外, 浏览 上下文可用于播放媒体的任何其他设备。
媒体 元素状态是单个 媒体 元素 的所有属性的集合,这些属性可由页面和/或用户通过 用户代理实现观察到。为方便起见, 本规范引入的新属性不被视为媒体元素状态 的一部分。
paused 属性或媒体
元素默认控件上反映该状态的暂停/继续
按钮,都属于媒体元素状态的一部分。
本地 播放状态是用户代理针对特定媒体元素状态的实现,用于在媒体元素 的本地播放设备上进行播放。
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 返回当前的
远程播放设备可用性。
RemotePlaybackAvailabilityCallback
是页面获取相应媒体元素的
远程播放设备可用性的方式。如果用户
代理能够在后台监视
可用远程播放设备列表
(而无需等待对prompt() 的请求),则用户代理
必须实现下文定义的
RemotePlaybackAvailabilityCallback
行为。否则,
watchAvailability()
返回的 promise 必须以
NotSupportedError
拒绝。
用户代理必须跟踪通过
watchAvailability()
方法向每个媒体元素注册的可用性
回调集合。每个
RemotePlayback 对象的可用性
回调集合表示为一个元组集合
(callbackId, callback),
初始为空,其中:
watchAvailability()
返回的 id 中唯一;
RemotePlaybackAvailabilityCallback
对象。
由于每个媒体
元素都有且只有一个RemotePlayback
对象,因此可用性
回调集合
与该元素的 remote
属性所引用的 RemotePlayback 对象的可用性
回调集合是同一个集合。
浏览
上下文所知的所有RemotePlayback
对象的所有可用性
回调集合合并后的集合称为全局
可用性回调集合。
用户代理必须维护一个可用远程 播放设备列表。此列表包含远程 播放 设备,并根据特定于实现的 发现机制进行填充。它被设置为监视 可用远程播放 设备列表算法的最新结果;如果该算法尚未运行, 则为空列表。
用户代理可以不支持持续运行
监视可用远程播放设备列表
的算法,例如,由于平台或功耗
限制。在这种情况下,由
watchAvailability()
返回的 promise 必须以
NotSupportedError
拒绝,
全局可用性
回调集合将为空,并且监视
可用远程播放设备列表的算法将仅作为
发起远程播放算法的一部分运行。
当全局 可用性回调集合非空时, 用户代理必须持续监视 可用远程播放设备列表,以便页面 可以跟踪通过已注册回调收到的最后一个值, 从而仅在存在可用设备时提供远程播放。
为满足 节能非功能性要求,用户代理应尽可能不监视 可用 远程播放设备列表。例如, 当全局 可用性回调集合为空时,或者当所有具有 非空可用性回调集合的媒体元素所在页面均处于 后台时,用户代理可能选择不运行监视 算法。
某些远程播放设备可能由于功能、安全或硬件限制, 只能播放一部分媒体资源。 例如,只能渲染特定视频和/或音频格式的 机顶盒、智能电视或联网扬声器。如果用户代理能够合理保证 由某媒体资源指定的媒体 能够在某设备上成功进行远程播放,我们就称该设备是该媒体资源的 兼容远程播放设备。
用户代理为查找兼容远程 播放设备而考虑过的某媒体 元素的媒体资源 称为 可用性源集合。
某媒体 元素中用于在选定远程播放设备上发起远程 播放的媒体资源 称为远程播放源。远程播放 源必须属于该媒体元素的可用性源 集合。
从可用性源集合中选择远程播放源的 机制由具体实现决定, 但用户代理应该将 可用性源集合中的每个资源都视为潜在的远程 播放源。
如果用户代理无法确定适用于远程播放设备的远程播放源, 则 建议用户代理将可用性源 集合中所有资源的元数据(例如 扩展 MIME 类型) 发送给远程播放设备,使其可以运行自己的 资源 选择算法并选择远程 播放 源。
如果可用远程
播放
设备列表为空,或者其中没有任何设备与媒体
元素的可用性源集合中的任何源兼容,
则该媒体
元素的远程播放是不可用的。否则,远程播放是
可用的。
对于某媒体元素,如果远程
播放不可用,则设置为 false,
如果可用,则设置为 true 的
boolean 称为该媒体元素的
可用性。
如果用户代理停止
监视可用远程播放设备列表
(例如由于用户控制或为节省电量),它应该
使用 false 调用全局可用性
回调集合中的所有回调,以便页面可以适当地更新
其用户体验。它还应该将所有媒体元素的
可用性值设置
为 false,以便如果用户代理稍后恢复
监视可用远程播放设备列表,可用性信息能够
正确传播。
当调用
watchAvailability()
方法时,用户代理必须运行以下步骤:
Promise。
Promise。
disableRemotePlayback
属性存在于媒体元素上,则以
InvalidStateError
拒绝 promise
并中止所有剩余步骤。
false 作为参数调用 callback。
NotSupportedError
异常拒绝 promise。
为 callbackId 分配值的一种简单算法是 为每个浏览 上下文维护一个计数器,并 在步骤 6 中递增该计数器。
如果可用性回调集合 非空,或者 存在等待中的 发起远程播放请求,则用户代理 必须通过运行以下步骤来监视可用远程播放 设备列表:
disableRemotePlayback
属性存在于 mediaElement 上,则中止
此元组的所有
剩余步骤并继续处理下一个元组。
当调用 cancelWatchAvailability()
方法时,用户代理必须运行以下步骤:
Promise。
Promise。
disableRemotePlayback
属性存在于
媒体元素上,则以
InvalidStateError
拒绝 promise,
并中止所有剩余步骤。
undefined,
则清空可用性
回调集合。
NotFoundError 拒绝
promise,并
中止所有剩余步骤。
当调用 prompt() 方法时,
用户代理必须运行以下步骤:
Promise。
Promise。
disableRemotePlayback
属性存在于
媒体元素上,则以
InvalidStateError
拒绝
promise,并中止所有剩余步骤。
prompt() 的调用已经存在一个
尚未敲定的 promise,则用户代理可以以 OperationError
异常拒绝
promise,并中止所有
剩余步骤。
InvalidAccessError
异常拒绝 promise 并中止这些步骤。
state或可用远程
播放设备列表无关),则以NotSupportedError
拒绝 promise,并中止所有剩余步骤。
NotFoundError
异常拒绝 promise,并
中止所有剩余步骤。
state
设置为connecting。
connecting,该属性属于媒体
元素。该事件不得冒泡,不得
取消,并且没有默认操作。
通过选择远程播放 设备,用户即授予 许可以使用该设备。
NotAllowedError
异常拒绝 promise,并隐藏用户代理显示的 UI。
state 属性表示
RemotePlayback 连接的当前状态。根据连接
状态,它可以取RemotePlaybackState
的以下值之一:
当用户代理要与 远程播放设备建立连接时,它必须运行以下步骤:
RemotePlayback 对象。
state
不等于 "connecting",则中止所有
剩余步骤。
disconnected"。
disconnect。
当远程播放状态为
"connected" 时,用户代理应该暂停媒体元素的本地音频和视频输出。
如果用户代理
正在为媒体元素向用户公开
用户界面(即使用
默认控件),则用户代理应该通过图标或
其他方式传达远程播放状态为
"connected" 这一事实。
用户代理可以支持从浏览器连接 到远程播放设备。这可以通过 向向用户 公开的用户界面添加适当的媒体控件,或者当用户激活系统范围的 显示镜像时来实现。此功能称为浏览器 发起的远程播放。支持 浏览器发起的远程播放的用户代理应该仅在用户通过 用户手势表达了这样做的意图时发起远程 播放,例如点击浏览器中的按钮。
如果用户代理支持浏览器发起的
远程播放,
则 state 属性必须反映与远程播放设备连接的当前状态。当浏览器
发起或终止远程播放时,它必须按照与远程播放设备建立
连接以及
与远程播放
设备断开连接的算法触发相应事件。
如果浏览器将
在新创建的媒体元素上发起远程播放,则它
应该将其 state 属性的值初始化为
"connecting",然后按照
与远程播放
设备建立连接的步骤操作。
一旦与远程
播放
设备的连接建立,
HTMLMediaElement
接口就会与远程
播放的媒体进行交互。
当 RemotePlayback 对象的state
为
"connected" 时,以下条件将
本地播放状态、媒体元素状态和
远程播放状态关联起来:
HTMLMediaElement
对象上发出的所有媒体命令发送给远程播放
设备,以更改其远程播放状态;
如果发送任何命令失败,用户代理可以 与远程播放 设备断开连接。
远程播放设备可以仅实现用户
代理播放引擎的一部分
功能,并且某些HTMLMediaElement
API 在远程播放期间并不总是
适合使用。在这种情况下,在远程播放期间不受支持的
媒体命令执行后,
本地播放状态应尽可能
准确地反映实际远程播放状态。
例如,当连接到不支持
fastSeek()
的远程播放
设备时调用它,
HTMLMediaElement
的
seeking
属性应保持为 false,并且不应触发任何
seeking
事件。
当用户代理要与远程 播放设备断开连接时,它必须执行以下操作:
RemotePlayback 对象。
state
为 disconnected,则中止所有
剩余步骤。
state 更改为
disconnected。
disconnect。
如果远程播放设备在播放期间突然断开连接
(例如由于断电或网络断开),
用户代理应该先运行监视
可用远程播放设备列表的步骤,再运行
与远程播放
设备断开连接的步骤。这使得
可用性
回调集合中的回调可以在触发
事件之前被调用,从而使
页面可以更新自身,以表明无法恢复播放。
disconnect
disconnected 状态。
以下是实现
RemotePlayback 接口的对象必须作为
事件处理程序
IDL 属性支持的事件处理程序
(以及它们对应的
事件
处理程序事件类型):
| 事件处理程序 | 事件处理程序事件类型 |
|---|---|
onconnecting
|
connecting
|
onconnect
|
connect
|
ondisconnect
|
disconnect
|
HTMLMediaElement
的扩展
WebIDLpartial interface HTMLMediaElement {
[SameObject] readonly attribute RemotePlayback remote;
[CEReactions] attribute boolean disableRemotePlayback;
};
remote 属性必须
返回与该
媒体元素
关联的RemotePlayback 实例。
某些页面可能希望禁用某个媒体
元素的远程播放;例如,它们可能更愿意使用
PresentationRequest
在演示屏幕上呈现完整文档。为支持
此用例,在 audio 和 video 元素的内容属性列表中
添加了新的 disableRemotePlayback 属性。
对应的disableRemotePlayback
IDL 属性会
反映每个元素的 disableRemotePlayback
内容属性值,并被添加到 HTMLMediaElement 接口中。
disableRemotePlayback
IDL 属性必须
反映同名内容属性。
如果disableRemotePlayback
属性存在于
媒体
元素上,则用户代理不得远程播放
该媒体元素,也不得提供任何用于执行此操作的 UI。
当disableRemotePlayback
属性被添加到
媒体
元素时,用户代理必须运行以下步骤来
禁用远程播放:
InvalidStateError
拒绝所有由
RemotePlayback 方法返回的等待中 promise。
state 不是
disconnected,则对媒体元素已连接或正在连接的远程
播放设备运行与远程
播放设备断开连接算法。
本节为非规范性内容。
调用通过
watchAvailability()
方法提供的 callback,会泄露通常通过
局域网发现的
远程播放设备是否存在的一位
信息。这可能与其他
信息结合使用来对用户进行指纹识别。不过,此信息
也取决于用户的本地网络环境,因此风险
得以降低。此外,按照设计,远程
播放设备的人类可读名称不会透露给页面。
该 API 支持监视可用远程播放 设备列表。用户代理如何确定远程播放设备与媒体 元素的资源 之间的兼容性和 可用性属于实现细节。如果用户代理将 媒体资源 与特定类型的设备进行匹配以确定其可用性, 则此功能可用于在未经用户 同意的情况下探测用户拥有哪种 远程播放设备的信息。
如果用户通过浏览器设置禁用了后台监视, 用户代理就不应监视可用远程 播放设备列表。
Remote Playback API 抽象了显示器中的“本地” 含义,也就是说,它将可通过网络访问的显示器公开为 如同本地显示器一样。Remote Playback API 要求 页面获得用户许可后才能访问任何显示器,以缓解 可能出现的问题,例如在其他人可看到的显示器上 显示不需要的内容。
本规范不会强制规定 本地播放设备与远程播放 设备之间的通信协议,但用户代理应对它们之间的消息 保密性和真实性提供一定保证。
Remote Playback API 并不限于 [SECURE-CONTEXTS],因为 它向 Web 应用公开了一项用户代理通常 在所有媒体上原生提供的功能,而不考虑浏览 上下文。 用户代理可以将 API 限制为 [SECURE-CONTEXTS],方法是在 非安全上下文中执行监视可用远程播放设备列表 算法时始终返回空列表。
要使本规范推进到提议推荐标准阶段, 每项功能都必须至少有两个独立且可互操作的 实现。每项功能可以由一组不同的 产品实现,并不要求所有功能都由 单个产品实现。此外,实现必须证明支持 媒体远程传送和媒体投送这两种情况, 可以 在同一产品中实现,也可以在不同产品中实现。
就这些标准而言,我们定义以下术语:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: