1. Introduction
Most user agents have their own mechanisms to block autoplaying media, and those mechanisms are implementation-specific. Web developers need to have a way to detect if autoplaying media is allowed or not in order to make actions, such as selecting alternate content or improving the user experience while media is not allowed to autoplay. For instance, if a user agent only blocks audible autoplay, then web developers can replace audible media with inaudible media to keep media playing, instead of showing a blocked media which looks like a still image to users. If the user agent does not allow any autoplay media, then web developers could stop loading media resources and related tasks to save the bandwidth and CPU usage for users.Currently, this specification only handles HTMLMediaElement
(video
and audio
) and Web Audio API. This specification does not handle Web Speech API and animated image
(GIF animation).
2. The Autoplay Detection API
Autoplay detection can be performed through theNavigator
object. The
result can either allow authors to know if media, which have the same type of
the given media type and exist in the document
contained in the Window
object associated with the queried Navigator
object, are
allowed to autoplay, or to know if a specific element is allowed to autoplay.
2.1. Autoplay Policy Enum
enum {
AutoplayPolicy "allowed" ,"allowed-muted" ,"disallowed" };
Enum Value | Description |
---|---|
"allowed "
| Media are allowed to autoplay. |
"allowed-muted "
|
Inaudible media are allowed to autoplay.
Note: Currently, this attribute will only be returned when the
given media type or element is a type of
An HTMLMediaElement or its extensions, such as HTMLVideoElement or HTMLAudioElement . inaudible media element is an HTMLMediaElement that has any of the following conditions:
|
"disallowed "
| No media is allowed to autoplay. |
disallowed
). Then the policy could change to allowed
or allowed-muted
after a
user performs a supported user gesture on the page or the media. 2.2. The Autoplay Detection Methods
enum {
AutoplayPolicyMediaType "mediaelement" ,"audiocontext" }; [Exposed =Window ]partial interface Navigator {AutoplayPolicy (
getAutoplayPolicy AutoplayPolicyMediaType );
type AutoplayPolicy (
getAutoplayPolicy HTMLMediaElement );
element AutoplayPolicy (
getAutoplayPolicy AudioContext ); };
context
Enum Value | Description |
---|---|
mediaelement
| It’s used to query a status for HTMLMediaElement and its
extensions, such as HTMLVideoElement and HTMLAudioElement .
|
audiocontext
| It’s used to query a status for AudioContext .
|
2.2.1. Query by a Media Type
ThegetAutoplayPolicy(type)
methods return the rough status of
whether media elements or audio context, which exist in the document
contained in the Window
object associated with the queried Navigator
object, are allowed to autoplay or not. The rough status
here means that the returned result isn’t always correct for every
elements which have the same type of the given media type.
disallowed
. In this
situation, it is recommended that authors also query by a specific
element in order to get an accurate result. For example, at first, the result of querying by a media type and
querying by an object would both be disallowed
. After a user clicks
on a media element, then querying by that media element would become allowed
if a user agent decides to bless that element because that
behavior seems intended by users, but querying by a media type and
querying by other media elements, which haven’t been clicked yet, would
still return disallowed
.
When getAutoplayPolicy(type)
method is called, the user agent MUST run
the following steps:
- If
type
ismediaelement
, return a result that represents the current status forHTMLMediaElement
and its extensions, such asHTMLVideoElement
andHTMLAudioElement
, which exist in thedocument
contained in theWindow
object associated with the queriedNavigator
object. - If
type
isaudiocontext
, return a result that represents the current status forAudioContext
, which exist in thedocument
contained in theWindow
object associated with the queriedNavigator
object.
- If the return value is
allowed
- All media, corresponding with the given type, are allowed to autoplay.
- If the return value is
allowed-muted
-
All inaudible media, corresponding with the given type, are allowed to
autoplay.
Note: Currently, this attribute will only be returned when the given media type is
mediaelement
. The inaudible media meansinaudible media element
. - If the return value is
disallowed
- None of media, corresponding with the given type, are allowed to autoplay.
Navigator
object
associated with the parent document could be different from the result
queried from the Navigator
object associated with the child
documents. foo.com
returns allowed
and
it has an embedded iframe, which has another document B from bar.com
. A
user agent could either make child document B return same result that is
inherited from the top level document A. Or make the document B return a
different result, eg. disallowed
.
Doing the former helps to lower the complexity and make the behavior of blocking autoplay more consistent. The latter helps providing a finer-grained autoplay control.
2.2.2. Query by an Element
ThegetAutoplayPolicy(element)
and getAutoplayPolicy(context)
methods return the current status of whether the given element is allowed
to autoplay or not.
- If the return value is
allowed
- This element is allowed to autoplay within the current execution context.
- If the return value is
allowed-muted
-
This element will only be allowed to autoplay if it’s inaudible.
Note: Currently, this attribute will only be returned when the given element is
HTMLMediaElement
or its extensions, such asHTMLVideoElement
orHTMLAudioElement
. The inaudible media meansinaudible media element
.In addition, if authors make an inaudible media element audible right after it starts playing, then it is recommended for a user agent to pause that media element immediately because it’s no longer inaudible.
- If the return value is
disallowed
-
This element is not allowed to autoplay.
Note: For
HTMLMediaElement
, if authors call itsplay()
, the returned promise fromplay()
will be rejected withNotAllowedError
exception.For
AudioContext
, that means itsAudioContextState
would keep insuspended
state.
If the result of querying by a media type is different from the result of querying by an element, authors should take the latter one as the correct result. Example 2 shows a possible scenario.
HTMLMediaElement
(or
its extension, such as HTMLVideoElement
and HTMLAudioElement
) or AudioContext
, then these methods will throw a TypeError
. 3. Examples
if ( navigator. getAutoplayPolicy( "mediaelement" ) === "allowed" ) { // Create and play a new media element. } else if ( navigator. getAutoplayPolicy( "mediaelement" ) === "allowed-muted" ) { // Create a new media element, and play it in muted. } else { // Autoplay is disallowed, maybe show a poster instead. }
AudioContext
can be allowed
to start.
if ( navigator. getAutoplayPolicy( "audiocontext" ) === "allowed" ) { let ac= new AudioContext(); ac. onstatechange= function () { if ( ac. state=== "running" ) { // Start running audio app. } } } else { // Audio context is not allowed to start. Display a bit of UI to ask // users to start the audio app. Audio starts via calling ac.resume() // from a handler, and 'onstatechange' allows knowing when the audio // stack is ready. }
function handlePlaySucceeded() { // Update the control UI to playing. } function handlePlayFailed() { // Show a button to allow users to explicitly start the video and // display an image element as poster to replace the video. } let video= document. getElementById( "video" ); switch ( navigator. getAutoplayPolicy( video)) { case "allowed" : video. src= "video.webm" ; video. play(). then( handlePlaySucceeded, handlePlayFailed); break ; case "allowed-muted" : video. src= "video.webm" ; video. muted= true ; video. play(). then( handlePlaySucceeded, handlePlayFailed); break ; default : // Autoplay is not allowed, no need to download the resource. handlePlayFailed(); break ; }
AudioContext
can be allowed
to start.
let ac= new AudioContext(); if ( navigator. getAutoplayPolicy( ac) === "allowed" ) { ac. onstatechange= function () { if ( ac. state=== "running" ) { // Start running audio app. } } } else { // Display a bit of UI to ask users to start the audio app. // Audio starts via calling ac.resume() from a handler, and // 'onstatechange' allows knowing when the audio stack is ready. }
4. Security and Privacy Considerations
Per the Self-Review Questionnaire: Security and Privacy § questions.The API introduced in this specification has very low impact with regards to security and privacy. It does not expose any sensitive information that can be used to to identify users. It does not expose any ability to control sensors and any users' devices. It does not introduce any new state for an origin that will persist across browsing sessions. It does not allow an origin to send any data to the underlying platform. It does not introduce or enable new script execution and loading mechanism. It does not allow an origin to draw over a user agent’s native UI. It does not allow an origin to detect if users are in the private or non-private browsing mode.
5. Acknowledgments
This specification is the collective work of the W3C media Working Group.The editors would like to thank Alastor Wu, Becca Hughes, Christoph Guttandin, Chris Needham, Chris Pearce, Dale Curtis, Eric Carlson, François Daoust, Frank Liberato, Gary Katsevman, Jean-Yves Avenard, Jer Noble, Mattias Buelens, Mounir Lamouri, Paul Adenot and Tom Jenkinson for their contributions to this specification.