This document defines a set of JavaScript APIs that let a Web application manage how audio is rendered on the user audio output devices.

The WebRTC and Device and Sensors Working Group intend to publish this specification as a Candidate Recommendation soon. Consequently, this is a Request for wide review of this document.

Introduction

This proposal allows JavaScript to direct the audio output of a media element to authorized devices other than the system or user agent default. This can be helpful in a variety of real-time communication scenarios as well as general media applications. For example, an application can use this API to programmatically direct output to a device such as a Bluetooth headset or speakerphone.

HTMLMediaElement Extensions

This section specifies additions to the HTMLMediaElement [[!HTML5]] when the Audio Output Devices API is supported.

      partial interface HTMLMediaElement {
        readonly        attribute DOMString sinkId;
        Promise<void> setSinkId (DOMString sinkId);
      };
      

Attributes

sinkId of type DOMString, readonly
This attribute contains the ID of the audio device through which output is being delivered, or the empty string if output is delivered through the user-agent default device. If nonempty, this ID should be equal to the deviceId attribute of one of the MediaDeviceInfo values returned from MediaDevices.enumerateDevices() [[!GETUSERMEDIA]]. The value of this attribute is equal to the argument passed to the last successful execution of setSinkId(), or the empty string if setSinkId() has never been called.

Methods

setSinkId
Sets the ID of the audio device through which audio output should be rendered if the application is authorized to play out of a given device.

When this method is invoked, the user agent must run the following steps:

  1. If sinkId is equal to the media element's sinkId attribute, return a promise resolved with undefined.

  2. Let promise be a new promise.

  3. Run the following substeps in parallel:

    1. If sinkId does not match any audio output device identified by the result that would be provided by enumerateDevices(), reject promise with a new DOMException whose name is NotFoundError and abort these substeps.

    2. If the application is not authorized to play audio through the device identified by sinkId, reject promise with a new DOMException whose name is SecurityError and abort these substeps.

    3. Switch the underlying output device for the media element to the device identified by sinkId.

      If this substep is successful and the media element's paused attribute is false, audio will stop playing out of the device represented by the element's sinkId attribute and will start playing out of the device identified by sinkId

    4. If the preceding substep failed, reject promise with a new DOMException whose name is AbortError and abort these substeps.

    5. Update the internal state of the media element so that the value of its sinkId attribute corresponds to sinkId.

    6. Resolve promise.

  4. Return promise.

Algorithms

Sink no longer available

The audio device identified by a media element's sinkId attribute may become unavailable, for example if it is unplugged.

When the audio device identified by the sinkId attribute is no longer available, the user agent must take no action. For example, if the media element's paused attribute is false when the device identified by the sinkId is no longer available, then playback will continue as normal. In this case, audio will not be rendered because the device to which the media element is attached is unavailable.

The following paragraph is non-normative.

If the application wishes to react to the device change, the application can listen to the devicechange event and query enumerateDevices() for the list of updated devices. If the value of the media element's sinkId attribute is no longer present as the deviceId attribute in the returned list of MediaDeviceInfos, the device is no longer available and the application can choose to react accordingly.

New sink available

New audio devices may become available to the user agent, or an audio device (identified by a media element's sinkId attribute) that had previously become unavailable may become available again, for example, if it is unplugged and later plugged back in.

In this scenario, the user agent must run the following steps:

  1. Let sinkId be the identifier for the newly available device.

  2. For each media element whose sinkId attribute is equal to sinkId:

    1. If the media element's paused attribute is false, start rendering this object's audio out of the device represented by the sinkId attribute.

The following paragraph is non-normative.

If the application wishes to react to the device change, the application can listen to the devicechange event and query enumerateDevices() for the list of updated devices.

Privacy Considerations

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)

Implementations that use ECMAScript to implement the APIs defined in this specification must implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]], as this specification uses that specification and terminology.

Acknowledgments

The following people have contributed directly to the development of this specification: Harald Alvestrand, Rick Byers, Dominique Hazael-Massieux (via the HTML5Apps project), Philip Jägenstedt, Victoria Kirst, Shijun Sun, Martin Thomson, Chris Wilson.