音频输出设备 API

W3C 候选推荐草案

有关本文档的更多详细信息
此版本:
https://www.w3.org/TR/2025/CRD-audio-output-20251009/
最新发布版本:
https://www.w3.org/TR/audio-output/
最新编辑草案:
https://w3c.github.io/mediacapture-output/
历史:
https://www.w3.org/standards/history/audio-output/
提交历史
实现报告:
https://wpt.fyi/audio-output
编辑:
Guido Urdaneta (Google)
Youenn Fablet (Apple)
前编辑:
Justin Uberti (Google) - 截至
反馈:
GitHub w3c/mediacapture-output拉取请求新议题开放议题
public-webrtc@w3.org 主题行为 [audio-output] … 消息主题 …归档
参与
邮件列表

摘要

本文档定义了一组 JavaScript API,使 Web 应用程序能够管理音频在用户音频输出 设备上的呈现方式。

本文档状态

本节描述本文档在发布时的状态。当前 W3C 出版物列表以及本技术报告的最新修订版,可在 W3C 标准和草案 索引中找到。

WebRTC 和设备与传感器工作组打算很快将此 规范作为候选推荐发布。因此,本文档是 广泛审查请求。

本文档由 Web 实时 通信工作组 作为 候选推荐草案,使用 推荐轨道发布。

作为候选推荐发布并不 意味着 W3C 及其成员的认可。候选 推荐草案会整合工作组 打算包含在后续候选推荐快照中的、相对于上一候选推荐的变更。

这是一份草案文档,可能随时被其他 文档更新、替换或废弃。除作为进行中的工作外, 不宜引用本文档。

本文档由一个依据 W3C 专利 政策运作的小组 产生。 W3C 维护一份 与该小组交付物相关的任何专利披露的公开列表; 该页面还包括 披露专利的说明。若某人实际 知晓某项专利,并且该人认为该专利包含 必要权利要求, 则必须依照 W3C 专利政策第 6 节披露该信息。

本文档受 2025 年 8 月 18 日 W3C 流程文档约束。

1. 简介

本节是非规范性的。

此提案允许 JavaScript 将媒体元素的音频输出定向到系统或用户代理 默认设备之外的、被允许的设备。这在各种实时通信场景以及 通用媒体应用中都很有帮助。例如,应用程序可以使用此 API 以编程方式将输出定向到蓝牙耳机或免提扬声器之类的设备。

2. HTMLMediaElement 扩展

当支持音频输出设备 API 时,本节规定对 HTMLMediaElement [HTML] 的补充。

当调用 HTMLMediaElement 构造器时,用户 代理 MUST 添加以下初始化步骤:

  1. 让该元素具有一个 [[SinkId]] 内部槽, 初始化为 ""

WebIDLpartial interface HTMLMediaElement {
  [SecureContext] readonly attribute DOMString sinkId;
  [SecureContext] Promise<undefined> setSinkId (DOMString sinkId);
};

属性

sinkId,类型为 DOMString,只读

此属性包含正在通过其传送输出的音频设备的 ID;如果输出是 通过用户代理默认设备传送的,则为空字符串。如果非空,则此 ID 应等于 deviceId 属性,该属性属于 enumerateDevices() 返回的某个 MediaDeviceInfo 值。

获取时,该 属性 MUST 返回 [[SinkId]] 槽的值。

方法

setSinkId

如果应用程序被允许从给定 设备播放输出,则设置音频输出应通过其呈现的音频设备的 ID。

当调用此方法时,用户代理必须运行以下 步骤:

  1. globalObject 当前设置对象 相关全局对象

  2. documentglobalObject 关联 Document

  3. 如果 document 被允许使用"speaker-selection" 标识的特性,则返回一个 使用新的 DOMException 拒绝的 promise, 其名称为 NotAllowedError

  4. 如果 globalObject 没有瞬态 激活, 则用户代理 MAY 返回一个以 DOMException 对象拒绝的 promise, 该对象的 name 属性具有 InvalidStateError 值。

  5. element 为调用此方法的 HTMLMediaElement 对象。

  6. sinkId 为该方法的第一个参数。

  7. 如果 sinkId 等于 element[[SinkId]], 则返回一个以 undefined 解决的 promise。

  8. p 为一个新的 promise。

  9. 并行运行以下子步骤:

    1. 如果 sinkId 不是空字符串,并且不匹配 enumerateDevices() 结果会提供的任何音频输出设备, 则用新的 DOMException 拒绝 p, 其名称为 NotFoundError, 并中止这些子步骤。

    2. 如果 sinkId 不是空字符串,并且 若它不是当前用户代理默认设备,则应用程序不会被允许 通过 sinkId 标识的设备播放音频输出, 则用新的 DOMException 拒绝 p, 其名称为 NotAllowedError, 并中止这些子步骤。

    3. element 的底层音频输出设备切换 到由 sinkId 标识的音频设备。

      如果此子步骤成功,并且媒体 元素的 paused 属性为 false,则音频 MUST 停止从该元素的 sinkId 属性所表示的设备播放输出,并将开始 从 sinkId 标识的设备播放输出

    4. 如果前一子步骤失败,则用新的 DOMException 拒绝 p, 其名称为 AbortError, 并中止这些子步骤。

    5. 排入一个任务,该任务运行以下步骤:

      1. element[[SinkId]] 设为 sinkId

      2. 解决 p

  10. 返回 p

2.1 算法

2.1.1 接收端不再可用

由媒体元素的 sinkId 属性标识的音频设备可能变得 不可用, 例如它被拔出时。

当由 sinkId 属性标识的音频设备不再 可用时,用户代理必须不采取任何动作。例如,如果由 sinkId 标识的设备不再可用时,媒体元素的 paused 属性为 false,则播放会照常继续。 在这种情况下,因为媒体元素所附接到的设备不可用, 所以音频不会被呈现。

以下段落是非规范性的。

如果应用程序希望对设备 变化作出反应,则应用程序可以监听 devicechange 事件并查询 enumerateDevices() 以获得更新后的设备列表。如果 媒体元素的 sinkId 属性的值 不再作为返回的 MediaDeviceInfos 列表中的 deviceId 属性存在, 则该设备不再可用,应用程序可以选择作出相应反应。

2.1.2 新的接收端可用

新的音频设备可能对用户代理可用,或者 先前变得不可用的音频设备(由媒体元素的 sinkId 属性标识) 可能再次变得可用, 例如,它被拔出后又重新插入。

在此场景下,用户代理必须运行以下步骤:

  1. sinkId 为新可用 设备的标识符。

  2. 对于每个其 sinkId 属性等于 sinkId 的媒体元素:

    1. 如果该媒体元素的 paused 属性为 false,则开始从 sinkId 属性所表示的设备呈现 此对象的音频输出。

以下段落是非规范性的。

如果应用程序希望对设备 变化作出反应,则应用程序可以监听 devicechange 事件并查询 enumerateDevices() 以获得更新后的 设备列表。

3. MediaDevices 扩展

当支持音频输出设备 API 时,本节规定对 MediaDevices 的补充。

WebIDLpartial interface MediaDevices {
  Promise<MediaDeviceInfo> selectAudioOutput(optional AudioOutputOptions options = {});
};

方法

selectAudioOutput

提示用户选择特定的音频输出设备。

当调用 selectAudioOutput 方法时, 用户代理 MUST 运行 以下步骤:

  1. 如果 相关 全局对象(属于 this)没有 瞬态 激活,则返回一个以 DOMException 对象拒绝的 promise, 该对象的 name 属性 具有 InvalidStateError 值。

  2. options 为该方法的第一个参数。

  3. deviceIdoptions.deviceId

  4. mediaDevicesthis

  5. p 为一个新的 promise。

  6. 并行运行以下步骤:

    1. descriptor 为一个 PermissionDescriptor, 其 name 设为 "speaker-selection"

    2. 如果 descriptor权限 状态为 "denied", 则用新的 DOMException 拒绝 p, 其 name 属性具有 NotAllowedError 值, 并中止这些步骤。

    3. 探测 用户代理中 可用的音频输出设备。

    4. 如果没有音频输出设备,则用新的 DOMException 拒绝 p, 其 name 属性具有 NotFoundError 值,并中止 这些步骤。

    5. 如果 deviceId 不是 "", 则运行以下子步骤:

      1. 如果 deviceId 匹配 先前由 selectAudioOutput 在此浏览会话或更早浏览会话中暴露的设备 ID, 或匹配某个音频输出设备的设备 ID,且该设备与先前由 getUserMedia() 在此浏览会话或更早浏览会话中暴露的音频输入设备 具有相同的 groupId, 则用户代理 MAY 根据其先前 是否为此组来源持久保存此 ID 的决定, 决定运行以下子步骤:

        1. device 为由 deviceId 标识的设备(如果可用)。

        2. 如果 device 可用,则用 deviceId 或该 device 的新轮换设备 ID 解决 p,并中止并行步骤。

    6. 使用 descriptor 提示 用户选择一个音频输出设备。

    7. 如果请求结果为 "denied", 则用新的 DOMException 拒绝 p, 其 name 属性 具有 NotAllowedError 值,并中止这些步骤。

    8. selectedDevice 为用户选择的音频输出设备。

    9. deviceInfo创建 设备信息对象的结果,该对象用 mediaDevices 表示 selectedDevice

    10. deviceInfo.deviceId 添加到 [[explicitlyGrantedAudioOutputDevices]]

    11. deviceInfo 解决 p

  7. 返回 p

一旦设备在调用 selectAudioOutput 后被暴露,它 MUSTenumerateDevices() 为当前浏览上下文列出。

如果 selectAudioOutput 返回的 promise 被解决, 则用户代理 MUST 确保文档无需任何额外用户手势, 即刻既被允许播放 HTMLMediaElement 中的媒体, 又即刻被 允许启动 AudioContext

由于当前浏览器中自动播放缺乏标准化, 这并不精确。

AudioOutputOptions 字典

此字典描述可用于获取音频输出设备 访问权限的选项。

WebIDLdictionary AudioOutputOptions {
  DOMString deviceId = "";
};

字典 AudioOutputOptions 成员

deviceId,类型为 DOMString, 默认为 ""

当此字典成员的值 不是 "",并且匹配先前由 selectAudioOutput 暴露的 ID,或者匹配某个音频输出设备的设备 ID, 且该设备与先前由 getUserMedia() 在此会话或更早会话中暴露的音频输入设备 具有相同的 groupId 时,用户 代理 MAY 选择跳过提示用户,改为 用此 ID 或同一设备的新轮换 ID 解决, 前提是该设备当前可用。

希望依赖支持持久设备 ID 的用户代理的应用程序, 必须先将这些 ID 成功传给 selectAudioOutput, 然后它们才能与 setSinkId 一起工作。原因是这会 暴露指纹识别信息,但如果设备不可用,或用户代理 决定不接受该设备 ID,则可能会提示用户。

4. 隐私考量

4.3 权限集成

音频输出设备 API 是一个强大功能,由 名称 "speaker-selection" 标识。

它定义以下类型和算法:

权限描述符 类型

权限涵盖对至少一个非默认扬声器输出设备的访问。

描述符的语义是它查询对任何非默认扬声器 输出设备的访问。因此,如果对 "speaker-selection" 强大功能 的查询返回 "granted", 则客户端知道先前与其共享的 deviceIds 中至少有一个 可以传给 selectAudioOutput 而不会产生权限提示; 如果返回 "denied", 则它知道任何针对音频输出设备的 selectAudioOutput 请求 都不会成功。

如果用户代理认为已授予对某些(但不是全部)音频输出设备的权限, 查询将返回 "granted"。

如果用户代理认为已拒绝对所有音频输出设备的权限, 查询将返回 "denied"。

4.4 权限策略集成

本规范定义一个 策略控制 特性,由字符串 "speaker-selection" 标识。 它具有 "self"默认 允许列表

document权限 策略 决定该 document 中的任何内容是否 被允许 使用 selectAudioOutput 来提示用户选择 音频输出设备,或者是否 被允许 使用 setSinkId 来将音频输出应通过其呈现的设备 更改为非系统默认的、用户允许的设备。对于 selectAudioOutput,这 由提示用户 选择算法强制执行。

5. 一致性

除标记为非规范性的各节外,本规范中的所有创作指南、图表、示例和注均为非规范性的。 本规范中的其他所有内容均为规范性的。

本文档中的关键词 MAYMUST 应按 BCP 14 [RFC2119] [RFC8174] 中的描述解释,且仅当它们如这里所示 以全大写形式出现时才如此。

本规范定义了适用于单个产品的一致性准则: 实现其所包含接口的 用户 代理

以算法或具体步骤表述的一致性要求,可以 以任何方式实现,只要最终结果等效即可。(特别是, 本规范中定义的算法旨在 易于理解,而非旨在具备高性能。)

使用 ECMAScript 来实现本规范中定义的 API 的实现, 必须以与 Web IDL 规范 [WEBIDL] 中定义的 ECMAScript 绑定一致的方式实现它们,因为 本规范使用该规范及其术语。

6. 致谢

以下人员直接为本规范的开发做出了贡献: Harald Alvestrand、Rick Byers、Dominique Hazael-Massieux(通过 HTML5Apps 项目)、Philip Jägenstedt、Victoria Kirst、Shijun Sun、Martin Thomson、Chris Wilson。

A. 参考文献

A.1 规范性参考文献

[GETUSERMEDIA]
媒体捕获与流. Cullen Jennings; Jan-Ivar Bruaroey; Henrik Boström; youenn fablet. W3C. 2025 年 10 月 2 日。CRD。URL: https://www.w3.org/TR/mediacapture-streams/
[HTML]
HTML 标准. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 现行标准。 URL: https://html.spec.whatwg.org/multipage/
[permissions]
权限. Marcos Caceres; Mike Taylor. W3C. 2025 年 10 月 6 日。W3C 工作草案。URL: https://www.w3.org/TR/permissions/
[permissions-policy]
权限策略. Ian Clelland. W3C. 2025 年 10 月 6 日。W3C 工作草案。URL: https://www.w3.org/TR/permissions-policy-1/
[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
[WEBAUDIO]
Web Audio API. Paul Adenot; Hongchan Choi. W3C. 2021 年 6 月 17 日。W3C 推荐。URL: https://www.w3.org/TR/webaudio-1.0/
[WEBIDL]
Web IDL 标准. Edgar Chen; Timothy Gu. WHATWG. 现行标准。URL: https://webidl.spec.whatwg.org/

A.2 资料性参考文献

[dom]
DOM 标准. Anne van Kesteren. WHATWG. 现行标准。URL: https://dom.spec.whatwg.org/