diff --git a/index.bs b/index.bs index 6926d4b..a36e60d 100644 --- a/index.bs +++ b/index.bs @@ -4,9 +4,8 @@ Shortname: autoplay-detection Level: 1 Status: w3c/ED Group: mediawg -URL: http://example.com/url-this-spec-will-live-at +URL: https://w3c.github.io/autoplay/ Editor: Alastor Wu, Mozilla https://www.mozilla.org, alwu@mozilla.com -Editor: Paul Adenot, Mozilla https://www.mozilla.org, padenot@mozilla.com Abstract: This specification provides web developers the ability to detect if automatically starting the playback of a media file is allowed in different situations. Markup Shorthands: markdown on @@ -56,18 +55,15 @@ div.enum-description > table > thead > tr > th { save the bandwidth and CPU usage for users. Currently, this specification only handles {{HTMLMediaElement}} (<{video}> - and <{audio}>) and does not handle [[webaudio inline]], [[speech-api inline]] - and animated <{image}> (GIF animation). Although the result from the document's - {{Document/autoplayPolicy}} can be used to detect whether web audio can be - started if user-agents block web audio from autoplaying. + and <{audio}>) and [[webaudio inline]]. This specification does not handle + [[speech-api inline]] and animated <{image}> (GIF animation).

The Autoplay Detection API

- Autoplay detection can be performed on either the {{Document}} element or on - the {{HTMLMediaElement}}. The former provides a general idea to authors to - know if autoplay media is allowed on this document element. If the page - contains multiple documents, an implementation can decide to return different - results for each of them. The latter provides more accurate result for whether - the autoplay is allowed on a specific media element. + Autoplay detection can be performed through the {{Navigator}} object. The + result can either allow authors to know if media, which have the same type of + the queried constructor and exist in the {{document}} contained in the + {{Window}} object asscociated with the queried {{Navigator}} object, are + allowed to autoplay, or to know if a specific element is allowed to autoplay.

Autoplay Policy Enum

@@ -93,13 +89,17 @@ div.enum-description > table > thead > tr > th {
           
             "allowed-muted"
           
-            Inaudible media element are allowed to autoplay. An
-            inaudible media element is an {{HTMLMediaElement}}
+            Inaudible media are allowed to autoplay.
+            
+ Note: Currently, this attribute will only be returned when a queried + object or a constructor is a type of {{HTMLMediaElement}}. +
+ An inaudible media element is an {{HTMLMediaElement}} that has any of the following conditions: @@ -113,186 +113,207 @@ div.enum-description > table > thead > tr > th { Note: The autoplay policy represents the current status of whether a user-agent allows media to autoplay, which can **vary** in the future. Therefore, it is **recommended** that authors check the result every time - they want to have an up-to-date result. + if they want to have an up-to-date result.
If a user-agent uses the user activation, described in [[HTML#user-activation-data-model]], to determine if the autoplay media - are allowed or not, and it blocks all autoplay by default - ({{AutoplayPolicy/disallowed}}). Then the policy can change to + are allowed or not, and the default policy is to block all autoplay + ({{AutoplayPolicy/disallowed}}). Then the policy could change to {{AutoplayPolicy/allowed}} or {{AutoplayPolicy/allowed-muted}} after a user performs a supported user gesture on the page or the media.
-

The Document API

-
-    partial interface Document {
-      readonly attribute AutoplayPolicy autoplayPolicy;
-    };
-    
- This represents a rough status of whether media that belong to this - {{Document}} are allowed to autoplay or not. +

The Autoplay Detection Methods

+

Query by a Constructor

+
+        callback HTMLMediaElementConstructor = HTMLMediaElement ();
+        callback AudioContextConstructor = AudioContext ();
+
+        [Exposed=Window]
+        partial interface Navigator {
+          AutoplayPolicy getAutoplayPolicy(HTMLMediaElementConstructor ctor);
+
+          AutoplayPolicy getAutoplayPolicy(AudioContextConstructor ctor);
+        };
+      
+ + This represents a rough status of whether media, which have the same type + of the queried constructor and exist in the {{document}} contained in the + {{Window}} object asscociated with the queried {{Navigator}} object, are + allowed to autoplay or not. The media terms appearing in the next + following if-statement have the same definition as above description.
If the value is {{allowed}}
- All media that belong to this document are allowed to autoplay. + All media are allowed to autoplay.
If the value is {{allowed-muted}}
- All {{inaudible media element}} that belong to this document are allowed + All inaudible media are allowed to autoplay. to autoplay. +
+ Note: Currently, this attribute will only be returned when the queried + constructor is {{HTMLMediaElement}}. The inaudible media means + {{inaudible media element}}. +
If the value is {{disallowed}}
- **None** of media belongs to this document are allowed to autoplay. + **None** of media are allowed to autoplay.
Note: Depending on the implementation, it's still possible for some media - that exist on the same document to be allowed to autoplay when the - document {{Document/autoplayPolicy}} returns {{disallowed}}. It is - **recommended** that authors check each media element’s autoplayPolicy - in order to get a complete result when document’s autoplayPolicy is - disallowed, if authors want to use that as a result to determine whether - media can be started playing. + that exist on the same document would be allowed to autoplay when the + result of querying by a contructor is {{disallowed}}. In this situation, + it is **recommended** that authors also query by a specific element in + order to get an accurate result.
- Some user-agents may not allow any media to autoplay by default, but allow - autoplay on those media elements which have been clicked by users. In this - case, at first, both the document's {{Document/autoplayPolicy}} and the - media element's {{HTMLMediaElement/autoplayPolicy}} will be {{disallowed}}. - - However, after a user clicks on a media element, then this media element's - {{HTMLMediaElement/autoplayPolicy}} might become {{allowed}} if a - user-agent decides to bless this element because that seems intended by - users. In this case, the document's {{Document/autoplayPolicy}} and other - media elements' {{HTMLMediaElement/autoplayPolicy}} (if any), which - haven't been clicked yet and are on the same document, will still be - {{disallowed}}. + Some user-agents may not allow any media element to autoplay by default, + but allow autoplay on those media elements which have been clicked by + users. + + For example, at first, the result of querying by a contructor and + querying by a 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 contructor and querying + by other media elements, which haven't been clicked yet, would still + return {{disallowed}}.
- Note: If the document has child documents, then the result from child - documents could be different from the result of their parent documents - depending on the implementation. + Note: Depending on the implementation, if a document has child + documents, then the result queried from the {{Navigator}} object + asscociated with the parent document could be different from the result + queried from the {{Navigator}} object asscociated with the child + documents.
Assume that the top level document A in `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 the same result that - is inherited from the top level document A. Or make the document B return - a different result, eg. {{disallowed}}. + 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.
-
- Note: In addition, document's {{Document/autoplayPolicy}} can also be - used to know whether [[webaudio inline]] can be allowed to start if a - user-agent blocks web audio by default. -
- -
- [Web Audio](https://webaudio.github.io/web-audio-api/#allowed-to-start) - uses [=sticky activation=] to determine if {{AudioContext}} can be allowed - to start. If the document is allowed to autoplay, then {{AudioContext}} - should also be allowed to start. - -
-        var ac = new AudioContext;
-        if (document.autoplayPolicy === "allowed") {
-          ac.onstatechange = function() {
-            if (ac.state === "running") {
-              // Start running audio app
-            } else {
-              // Display a bit of UI to ask the user to start the audio app.
-              // Audio starts via calling ac.resume() from a handler, and
-              // 'onstatechange' allows knowing when the audio stack is ready.
-            }
-          }
-        }
-      
-
- -

The HTMLMediaElement API

+

Query by an Element

-    partial interface HTMLMediaElement {
-      readonly attribute AutoplayPolicy autoplayPolicy;
-    };
+      [Exposed=Window]
+      partial interface Navigator {
+        AutoplayPolicy getAutoplayPolicy(HTMLMediaElement element);
+
+        AutoplayPolicy getAutoplayPolicy(AudioContext context);
+      };
     
- This represents the current status of whether this {{HTMLMediaElement}} is + This represents the current status of whether the queried element is allowed to autoplay or not.
If the value is {{allowed}}
- This media element is allowed to autoplay within the current execution + This element is allowed to autoplay within the current execution context.
If the value is {{allowed-muted}}
- This media element will only be allowed to autoplay if it's an - {{inaudible media element}}. If authors make this media element audible - right after the media element started playing, then the user-agent - **MUST** pause this media element immediately because it's no longer - inaudible. + This element will only be allowed to autoplay if it's inaudible. + +
+ Note: Currently, this attribute will only be returned when a queried + constructor is the type of {{HTMLMediaElement}}. The inaudible media + means {{inaudible 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 value is {{disallowed}}
- This media element is not allowed to autoplay. If authors call its - {{HTMLMediaElement/play()}}, the returned promise from - {{HTMLMediaElement/play()}} will be rejected with {{NotAllowedError}} - exception. + This element is not allowed to autoplay. +
+ Note: For {{HTMLMediaElement}}, if authors call its + {{HTMLMediaElement/play()}}, the returned promise from + {{HTMLMediaElement/play()}} will be rejected with {{NotAllowedError}} + exception. + + For {{AudioContext}}, that means its {{AudioContextState}} would keep + in {{AudioContextState/suspended}} state. +
- If the media element's {{HTMLMediaElement/autoplayPolicy}} is different from - the document's {{Document/autoplayPolicy}}, the media element's - {{HTMLMediaElement/autoplayPolicy}} overrides the document's - {{Document/autoplayPolicy}}. + If the result of querying by a constructor is different from the result + of querying by an element, authors should take the latter one as a correct + result. Example 2 shows a possible scenario.

Examples

- Example of using Document's {{Document/autoplayPolicy}} + An example for checking whether authors can autoplay a media element.
-      switch (document.autoplayPolicy) {
-        case "allowed":
-          loadUnmutedVideos();
-          break;
-        case "allowed-muted":
-          loadMutedVideos();
-          break;
-        default:
-          loadPosterImages();
-          break;
+
+      if (navigator.getAutoplayPolicy(HTMLMediaElement) === "allowed") {
+        // Create and play a new media element.
+      } else if (navigator.getAutoplayPolicy(HTMLMediaElement) === "allowed-muted") {
+        // Create a new media element, and play it in muted.
+      } else {
+        // Autoplay is disallowed, maybe show a poster instead.
+      }
+    
+
+ +
+ An example for checking whether authors can start an audio context. + [Web Audio](https://webaudio.github.io/web-audio-api/#allowed-to-start) + uses [=sticky activation=] to determine if {{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.
       }
     
- Example of using HTMLMediaElement's {{HTMLMediaElement/autoplayPolicy}} + Example of querying by a specific media element.
       function handlePlaySucceeded() {
-        // Update the control UI to playing
+        // Update the control UI to playing.
       }
       function handlePlayFailed() {
         // Show a button to allow users to explicitly start the video and
-        // display a image element as poster to replace the video
+        // display an image element as poster to replace the video.
       }
 
       let video = document.getElementById("video");
-      switch (video.autoplayPolicy) {
+      switch (navigator.getAutoplayPolicy(video)) {
         case "allowed":
           video.src = "video.webm";
           video.play().then(handlePlaySucceeded, handlePlayFailed);
@@ -310,6 +331,27 @@ div.enum-description > table > thead > tr > th {
     
+
+ Example of querying by a specific audio context. + [Web Audio](https://webaudio.github.io/web-audio-api/#allowed-to-start) + uses [=sticky activation=] to determine if {{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.
+      }
+    
+
+

Security and Privacy Considerations

Per the [[security-privacy-questionnaire#questions]]. @@ -326,7 +368,7 @@ div.enum-description > table > thead > tr > th {

Acknowledgments

This specification is the collective work of the W3C media Working Group. - The editors would like to thank Alastor Wu, Becca Hughes, Chris Needham, - Chris Pearce, Dale Curtis, Eric Carlson, Gary Katsevman, Jer Noble, Mattias Buelens, - Mounir Lamouri, Paul Adenot and Tom Jenkinson for their contributions to this - specification. + 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, Jer Noble, Mattias Buelens, Mounir Lamouri, + Paul Adenot and Tom Jenkinson for their contributions to this specification. diff --git a/index.html b/index.html index 8632874..f4fbedc 100644 --- a/index.html +++ b/index.html @@ -5,8 +5,8 @@ Autoplay Policy Detection - - + +