├── .gitattributes ├── .pr-preview.yml ├── w3c.json ├── LICENSE.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── .github └── workflows │ └── auto-publish.yml ├── security-privacy-questionnaire.md ├── README.md └── index.bs /.gitattributes: -------------------------------------------------------------------------------- 1 | *.bs linguist-language=HTML -------------------------------------------------------------------------------- /.pr-preview.yml: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.bs", 3 | "type": "bikeshed", 4 | "params": { 5 | "force": 1 6 | } 7 | } -------------------------------------------------------------------------------- /w3c.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": 115198 3 | , "contacts": ["tidoust", "chrisn", "marcoscaceres"] 4 | , "repo-type": "rec-track" 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All documents in this Repository are licensed by contributors under the [W3C 2 | Software and Document License](http://www.w3.org/Consortium/Legal/copyright-software). 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions to this repository are intended to become part of Recommendation-track documents governed by the 4 | [W3C Patent Policy](https://www.w3.org/policies/patent-policy/) and 5 | [Software and Document License](https://www.w3.org/copyright/software-license/). To make substantive contributions to specifications, you must either participate 6 | in the relevant W3C Working Group or make a non-member patent licensing commitment. 7 | 8 | If you are not the sole contributor to a contribution (pull request), please identify all 9 | contributors in the pull request comment. 10 | 11 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows: 12 | 13 | ``` 14 | +@github_username 15 | ``` 16 | 17 | If you added a contributor by mistake, you can remove them in a comment with: 18 | 19 | ``` 20 | -@github_username 21 | ``` 22 | 23 | If you are making a pull request on behalf of someone else but you had no part in designing the 24 | feature, you can remove yourself with the above syntax. 25 | -------------------------------------------------------------------------------- /.github/workflows/auto-publish.yml: -------------------------------------------------------------------------------- 1 | # Workflow based on the main w3c/spec-prod action example: 2 | # https://github.com/w3c/spec-prod/#basic-usage 3 | 4 | name: Build, Validate, Deploy and Publish 5 | 6 | on: 7 | # Workflow runs on pull requests where it makes sure that the spec can still 8 | # be generated, that markup is valid and that there are no broken links, as 9 | # well as on pushes to the default branch where it also deploys the generated 10 | # spec to the gh-pages branch and publishes the result to /TR. 11 | # The "workflow_dispatch" hook allows admins to also trigger the workflow 12 | # manually from GitHub's UI. 13 | pull_request: {} 14 | push: 15 | branches: [main] 16 | workflow_dispatch: 17 | 18 | jobs: 19 | main: 20 | runs-on: ubuntu-latest 21 | steps: 22 | # See doc at https://github.com/actions/checkout#checkout-v2 23 | - name: Checkout repository 24 | uses: actions/checkout@v4 25 | 26 | # See doc at https://github.com/w3c/spec-prod/#spec-prod 27 | # The action only deploys the generated spec to the gh-pages branch when 28 | # the workflow was triggered by a push to the default branch. 29 | - name: Build and validate index.html, push to gh-pages branch if needed 30 | uses: w3c/spec-prod@v2 31 | with: 32 | GH_PAGES_BRANCH: gh-pages 33 | W3C_ECHIDNA_TOKEN: ${{ secrets.ECHIDNA_TOKEN }} 34 | W3C_WG_DECISION_URL: https://github.com/w3c/media-wg/issues/27 35 | W3C_BUILD_OVERRIDE: | 36 | status: WD 37 | -------------------------------------------------------------------------------- /security-privacy-questionnaire.md: -------------------------------------------------------------------------------- 1 | # Autoplay Policy Detection - Security and Privacy Questionnaire 2 | 3 | This document answers the [W3C Security and Privacy 4 | Questionnaire](https://w3ctag.github.io/security-questionnaire/) for the 5 | Autoplay Policy Detection specification. 6 | 7 | Last Update: 2022-09-12 8 | 9 | **What information might this feature expose to Web sites or other parties, and 10 | for what purposes is that exposure necessary?** 11 | 12 | This API exposes information to allow websites detect if autoplaying media is 13 | allowed, which help them make actions, such as selecting alternate content or 14 | improving the user experience while media is not allowed to autoplay. 15 | 16 | Example query: 17 | Is this media element allowed to autoplay? 18 | 19 | Example answer: 20 | The queried media element is not allowed to autoplay. 21 | 22 | If the user agent does not allow any autoplay media, then websites could stop 23 | loading media resources and related tasks to save the bandwidth and CPU usage 24 | for users. 25 | 26 | **Do features in your specification expose the minimum amount of information 27 | necessary to enable their intended uses?** 28 | 29 | Yes. The API will return different results, such as `allowed`, `allowed-muted` 30 | and `disallowed`, to answer websites' question. 31 | 32 | **How do the features in your specification deal with personal information, 33 | personally-identifiable information (PII), or information derived from them?** 34 | 35 | This specification does not deal with PII. 36 | 37 | **How do the features in your specification deal with sensitive information?** 38 | 39 | This specification does not deal with sensitive information. 40 | 41 | **Do the features in your specification introduce new state for an origin that 42 | persists across browsing sessions?** 43 | 44 | No. 45 | 46 | **Do the features in your specification expose information about the underlying 47 | platform to origins?** 48 | 49 | No. The information about whether autoplay is not allowed is not platform 50 | specific. The result doesn't describe anything which can be used to deduce the 51 | underlying platform. 52 | 53 | **Do features in this specification allow an origin access to sensors on a 54 | user’s device?** 55 | 56 | No. 57 | 58 | **What data do the features in this specification expose to an origin? Please 59 | also document what data is identical to data exposed by other features, in the 60 | same or different contexts.** 61 | 62 | 3 enums, "allowed", "allowed-muted" and "disallowed", which are used to answer 63 | the question for knowing the status for autoplay. 64 | 65 | There is no other API can directly answer the status of whether autoplay is 66 | allowed. However, for media element, there is a API could answer the question 67 | indirectly. But for the audio context, there is no way to know the status. 68 | 69 | Eg. `HTMLMediaElement.play()`, will return a promise. If autoplay is not 70 | allowed, the play promise will be rejected, and the element will receive an 71 | unsupported error. 72 | 73 | **Do features in this specification enable new script execution/loading 74 | mechanisms?** 75 | 76 | No. 77 | 78 | **Do features in this specification allow an origin to access other devices?** 79 | 80 | No. 81 | 82 | **Do features in this specification allow an origin some measure of control over 83 | a user agent’s native UI?** 84 | 85 | No. 86 | 87 | **What temporary identifiers do the features in this specification create or 88 | expose to the web?** 89 | 90 | No. 91 | 92 | **How does this specification distinguish between behavior in first-party and 93 | third-party contexts?** 94 | 95 | It does not distinguish. 96 | 97 | **How do the features in this specification work in the context of a browser’s 98 | Private Browsing or Incognito mode?** 99 | 100 | This specification does not treat Private Browsing and Incognito mode in a 101 | special way. They should all work the same as normal browsing mode. 102 | 103 | Unless the user agent implements something specially which would return 104 | different answers for the same origin under the same situation. 105 | 106 | **Does this specification have both "Security Considerations" and "Privacy 107 | Considerations" sections?** 108 | 109 | Yes, this specification has a [Security and Privacy Considerations](https://w3c.github.io/autoplay/#security-and-privacy) 110 | section already. 111 | 112 | **Do features in your specification enable downgrading default security 113 | characteristics?** 114 | 115 | No. 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Autoplay Policy Detection 2 | 3 | This repository contains the Autoplay Policy Detection specification that is being worked on in the W3C [Media Working Group](https://www.w3.org/media-wg/). 4 | 5 | ## Editor 6 | 7 | - Alastor Wu 8 | 9 | ## Participate 10 | 11 | - https://github.com/w3c/autoplay/issues/ 12 | 13 | ## Introduction 14 | 15 | 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. 16 | 17 | 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). 18 | 19 | ## Goal 20 | 21 | To allow web developers detect whether they're allowed to play media via HTMLMediaElement API and Web Audio API easily without using any complicated workaround. 22 | 23 | ## API 24 | 25 | 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 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. 26 | 27 | ```js 28 | enum AutoplayPolicy { 29 | "allowed", 30 | "allowed-muted", 31 | "disallowed" 32 | }; 33 | 34 | enum AutoplayPolicyMediaType { "mediaelement", "audiocontext" }; 35 | 36 | [Exposed=Window] 37 | partial interface Navigator { 38 | AutoplayPolicy getAutoplayPolicy(AutoplayPolicyMediaType type); 39 | AutoplayPolicy getAutoplayPolicy(HTMLMediaElement element); 40 | AutoplayPolicy getAutoplayPolicy(AudioContext context); 41 | }; 42 | ``` 43 | 44 | ## Key scenarios 45 | 46 | ### Checking whether authors can autoplay any media element. 47 | 48 | ```js 49 | if (navigator.getAutoplayPolicy("mediaelement") === "allowed") { 50 | // Create and play a new media element. 51 | } else if (navigator.getAutoplayPolicy("mediaelement") === "allowed-muted") { 52 | // Create a new media element, and play it in muted. 53 | } else { 54 | // Autoplay is disallowed, maybe show a poster instead. 55 | } 56 | ``` 57 | 58 | ### Checking whether authors can start any audio context. 59 | 60 | Web Audio uses sticky activation to determine if AudioContext can be allowed to start. 61 | 62 | ```js 63 | if (navigator.getAutoplayPolicy("audiocontext") === "allowed") { 64 | let ac = new AudioContext(); 65 | ac.onstatechange = function () { 66 | if (ac.state === "running") { 67 | // Start running audio app. 68 | } 69 | }; 70 | } else { 71 | // Audio context is not allowed to start. Display a bit of UI to ask 72 | // users to start the audio app. Audio starts via calling ac.resume() 73 | // from a handler, and 'onstatechange' allows knowing when the audio 74 | // stack is ready. 75 | } 76 | ``` 77 | 78 | ### Checking whether authors can autoplay on a specific media element. 79 | 80 | ```js 81 | function handlePlaySucceeded() { 82 | // Update the control UI to playing. 83 | } 84 | function handlePlayFailed() { 85 | // Show a button to allow users to explicitly start the video and 86 | // display an image element as poster to replace the video. 87 | } 88 | 89 | let video = document.getElementById("video"); 90 | switch (navigator.getAutoplayPolicy(video)) { 91 | case "allowed": 92 | video.src = "video.webm"; 93 | video.play().then(handlePlaySucceeded, handlePlayFailed); 94 | break; 95 | case "allowed-muted": 96 | video.src = "video.webm"; 97 | video.muted = true; 98 | video.play().then(handlePlaySucceeded, handlePlayFailed); 99 | break; 100 | default: 101 | // Autoplay is not allowed, no need to download the resource. 102 | handlePlayFailed(); 103 | break; 104 | } 105 | ``` 106 | 107 | ### Checking whether authors can autoplay on a specific audio context. 108 | 109 | Web Audio uses sticky activation to determine if AudioContext can be allowed to start. 110 | 111 | ```js 112 | let ac = new AudioContext(); 113 | if (navigator.getAutoplayPolicy(ac) === "allowed") { 114 | ac.onstatechange = function () { 115 | if (ac.state === "running") { 116 | // Start running audio app. 117 | } 118 | }; 119 | } else { 120 | // Display a bit of UI to ask users to start the audio app. 121 | // Audio starts via calling ac.resume() from a handler, and 122 | // 'onstatechange' allows knowing when the audio stack is ready. 123 | } 124 | ``` 125 | 126 | ## Stakeholder Feedback / Opposition 127 | 128 | - Chrome : Positive 129 | - Edge : No public signal 130 | - Firefox : Shipping on Nightly 131 | - Safari : [Positive](https://github.com/WebKit/standards-positions/issues/113) 132 | 133 | ## References & acknowledgements 134 | 135 | Many thanks for valuable feedback and advice from 136 | 137 | - Alastor Wu 138 | - Becca Hughes 139 | - Christoph Guttandin 140 | - Chris Needham 141 | - Chris Pearce 142 | - Dale Curtis 143 | - Eric Carlson 144 | - François Daoust 145 | - Frank Liberato 146 | - Gary Katsevman 147 | - Jean-Yves Avenard 148 | - Jer Noble 149 | - Mattias Buelens 150 | - Mounir Lamouri 151 | - Paul Adenot 152 | - Tom Jenkinson 153 | -------------------------------------------------------------------------------- /index.bs: -------------------------------------------------------------------------------- 1 |
  2 | Title: Autoplay Policy Detection
  3 | Shortname: autoplay-detection
  4 | Level: None
  5 | Status: w3c/ED
  6 | Group: mediawg
  7 | Repository: https://github.com/w3c/autoplay
  8 | URL: https://w3c.github.io/autoplay/
  9 | TR: https://www.w3.org/TR/autoplay-detection/
 10 | Editor: Alastor Wu, Mozilla https://www.mozilla.org, alwu@mozilla.com, w3cid 92198
 11 | Abstract: This specification provides web developers the ability to detect if automatically starting the playback of a media file is allowed in different situations.
 12 | Markup Shorthands: markdown on
 13 | 
14 | 15 | 18 | 19 | 50 | 51 |

Introduction

52 | Most user agents have their own mechanisms to block autoplaying media, and those 53 | mechanisms are implementation-specific. Web developers need to have a way to 54 | detect if autoplaying media is allowed or not in order to make actions, such 55 | as selecting alternate content or improving the user experience while media 56 | is not allowed to autoplay. For instance, if a user agent only blocks audible 57 | autoplay, then web developers can replace audible media with inaudible media 58 | to keep media playing, instead of showing a blocked media which looks like a 59 | still image to users. If the user agent does not allow any autoplay media, 60 | then web developers could stop loading media resources and related tasks to 61 | save the bandwidth and CPU usage for users. 62 | 63 | Currently, this specification only handles {{HTMLMediaElement}} (<{video}> 64 | and <{audio}>) and [[webaudio inline]]. This specification does not handle 65 | [[speech-api inline]] and animated <{image}> (GIF animation). 66 | 67 |

The Autoplay Detection API

68 | Autoplay detection can be performed through the {{Navigator}} object. The 69 | result can either allow authors to know if media, which have the same type of 70 | the given media type and exist in the {{document}} contained in the 71 | {{Window}} object associated with the queried {{Navigator}} object, are 72 | allowed to autoplay, or to know if a specific element is allowed to autoplay. 73 | 74 |

Autoplay Policy Enum

75 |
 76 |     enum AutoplayPolicy {
 77 |       "allowed",
 78 |       "allowed-muted",
 79 |       "disallowed"
 80 |     };
 81 |     
82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 97 | 115 |
Enum ValueDescription
93 | "allowed" 94 | 95 | Media are allowed to autoplay. 96 |
98 | "allowed-muted" 99 | 100 | Inaudible media are allowed to autoplay. 101 |
102 | Note: Currently, this attribute will only be returned when the 103 | given media type or element is a type of {{HTMLMediaElement}} 104 | or its extensions, such as {{HTMLVideoElement}} or 105 | {{HTMLAudioElement}}. 106 |
107 | An inaudible media element is an {{HTMLMediaElement}} 108 | that has any of the following conditions: 109 |
    110 |
  • media's {{HTMLMediaElement/volume}} equal to 0 111 |
  • media's {{HTMLMediaElement/muted}} is true 112 |
  • media's resource does not have an audio track 113 |
114 |
116 | "disallowed" 117 | 118 | No media is allowed to autoplay. 119 |
120 |
121 | 122 |
123 | Note: The autoplay policy represents the current status of whether a 124 | user agent allows media to autoplay, which can **vary** in the future. 125 | Therefore, it is **recommended** that authors check the result every time 126 | if they want to have an up-to-date result. 127 |
128 | 129 |
130 | If a user agent uses the user activation, described in 131 | [[HTML#user-activation-data-model]], to determine if the autoplay media 132 | are allowed or not, and the default policy is to block all autoplay 133 | ({{AutoplayPolicy/disallowed}}). Then the policy could change to 134 | {{AutoplayPolicy/allowed}} or {{AutoplayPolicy/allowed-muted}} after a 135 | user performs a supported user gesture on the page or the media. 136 |
137 | 138 |

The Autoplay Detection Methods

139 |
140 |       enum AutoplayPolicyMediaType { "mediaelement", "audiocontext" };
141 | 
142 |       [Exposed=Window]
143 |       partial interface Navigator {
144 |         AutoplayPolicy getAutoplayPolicy(AutoplayPolicyMediaType type);
145 |         AutoplayPolicy getAutoplayPolicy(HTMLMediaElement element);
146 |         AutoplayPolicy getAutoplayPolicy(AudioContext context);
147 |       };
148 |     
149 | 150 |
151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 166 |
Enum ValueDescription
161 | mediaelement 162 | 163 | It's used to query a status for {{HTMLMediaElement}} and its 164 | extensions, such as {{HTMLVideoElement}} and {{HTMLAudioElement}}. 165 |
167 | audiocontext 168 | 169 | It's used to query a status for {{AudioContext}}. 170 |
171 |
172 | 173 |

Query by a Media Type

174 | The {{getAutoplayPolicy(type)}} methods return the **rough** status of 175 | whether media elements or audio context, which exist in the {{document}} 176 | contained in the {{Window}} object associated with the queried 177 | {{Navigator}} object, are allowed to autoplay or not. The rough status 178 | here means that the returned result isn't always correct for every 179 | elements which have the same type of the given media type. 180 | 181 |
182 | Note: Depending on the implementation, it's still possible for some 183 | media that exist on the same document would be allowed to autoplay when 184 | the result of querying by a media type is {{disallowed}}. In this 185 | situation, it is **recommended** that authors also query by a specific 186 | element in order to get an accurate result. 187 |
188 | 189 |
190 | Some user agents may not allow any media element to autoplay by default, 191 | but allow autoplay on those media elements which have been clicked by 192 | users. 193 | 194 | For example, at first, the result of querying by a media type and 195 | querying by an object would both be {{disallowed}}. After a user clicks 196 | on a media element, then querying by that media element would become 197 | {{allowed}} if a user agent decides to bless that element because that 198 | behavior seems intended by users, but querying by a media type and 199 | querying by other media elements, which haven't been clicked yet, would 200 | still return {{disallowed}}. 201 |
202 | 203 | When {{getAutoplayPolicy(type)}} method is called, the user agent MUST run 204 | the following steps: 205 |
    206 |
  1. 207 | If {{type}} is {{AutoplayPolicyMediaType/mediaelement}}, return a 208 | result that represents the current status for {{HTMLMediaElement}} 209 | and its extensions, such as {{HTMLVideoElement}} and 210 | {{HTMLAudioElement}}, which exist in the {{document}} contained in the 211 | {{Window}} object associated with the queried {{Navigator}} object. 212 |
  2. 213 |
  3. 214 | If {{type}} is {{AutoplayPolicyMediaType/audiocontext}}, return a 215 | result that represents the current status for {{AudioContext}}, 216 | which exist in the {{document}} contained in the {{Window}} object 217 | associated with the queried {{Navigator}} object. 218 |
  4. 219 |
220 | 221 |
222 |
If the return value is {{allowed}}
223 |
224 | All media, corresponding with the given type, are allowed to autoplay. 225 |
226 | 227 |
If the return value is {{allowed-muted}}
228 |
229 | All inaudible media, corresponding with the given type, are allowed to 230 | autoplay. 231 |
232 | Note: Currently, this attribute will only be returned when the given 233 | media type is {{AutoplayPolicyMediaType/mediaelement}}. The inaudible 234 | media means {{inaudible media element}}. 235 |
236 |
237 | 238 |
If the return value is {{disallowed}}
239 |
240 | **None** of media, corresponding with the given type, are allowed to 241 | autoplay. 242 |
243 |
244 | 245 |
246 | Note: Depending on the implementation, if a document has child 247 | documents, then the result queried from the {{Navigator}} object 248 | associated with the parent document could be different from the result 249 | queried from the {{Navigator}} object associated with the child 250 | documents. 251 |
252 | 253 |
254 | Assume that the top level document A in `foo.com` returns {{allowed}} and 255 | it has an embedded iframe, which has another document B from `bar.com`. A 256 | user agent could either make child document B return same result that is 257 | inherited from the top level document A. Or make the document B return a 258 | different result, eg. {{disallowed}}. 259 | 260 | Doing the former helps to lower the complexity and make the behavior of 261 | blocking autoplay more consistent. The latter helps providing a 262 | finer-grained autoplay control. 263 |
264 | 265 |

Query by an Element

266 | The {{getAutoplayPolicy(element)}} and {{getAutoplayPolicy(context)}} 267 | methods return the current status of whether the given element is allowed 268 | to autoplay or not. 269 | 270 |
271 |
If the return value is {{allowed}}
272 |
273 | This element is allowed to autoplay within the current execution 274 | context. 275 |
276 | 277 |
If the return value is {{allowed-muted}}
278 |
279 | This element will only be allowed to autoplay if it's inaudible. 280 | 281 |
282 | Note: Currently, this attribute will only be returned when the given 283 | element is {{HTMLMediaElement}} or its extensions, such as 284 | {{HTMLVideoElement}} or {{HTMLAudioElement}}. The inaudible media 285 | means {{inaudible media element}}. 286 | 287 | In addition, if authors make an inaudible media element audible 288 | right after it starts playing, then it is **recommended** for a 289 | user agent to pause that media element immediately because it's no 290 | longer inaudible. 291 |
292 |
293 | 294 |
If the return value is {{disallowed}}
295 |
296 | This element is not allowed to autoplay. 297 |
298 | Note: For {{HTMLMediaElement}}, if authors call its 299 | {{HTMLMediaElement/play()}}, the returned promise from 300 | {{HTMLMediaElement/play()}} will be rejected with {{NotAllowedError}} 301 | exception. 302 | 303 | For {{AudioContext}}, that means its {{AudioContextState}} would keep 304 | in {{AudioContextState/suspended}} state. 305 |
306 |
307 |
308 | 309 | If the result of querying by a media type is different from the result 310 | of querying by an element, authors should take the latter one as the correct 311 | result. Example 2 shows a possible scenario. 312 | 313 |
314 | Note: If the element which authors pass is not {{HTMLMediaElement}} (or 315 | its extension, such as {{HTMLVideoElement}} and {{HTMLAudioElement}}) or 316 | {{AudioContext}}, then these methods will throw a {{TypeError}}. 317 |
318 | 319 |

Examples

320 |
321 | An example for checking whether authors can autoplay a media element. 322 |
323 | 
324 |       if (navigator.getAutoplayPolicy("mediaelement") === "allowed") {
325 |         // Create and play a new media element.
326 |       } else if (navigator.getAutoplayPolicy("mediaelement") === "allowed-muted") {
327 |         // Create a new media element, and play it in muted.
328 |       } else {
329 |         // Autoplay is disallowed, maybe show a poster instead.
330 |       }
331 |     
332 |
333 | 334 |
335 | An example for checking whether authors can start an audio context. 336 | [Web Audio](https://webaudio.github.io/web-audio-api/#allowed-to-start) 337 | uses [=sticky activation=] to determine if {{AudioContext}} can be allowed 338 | to start. 339 |
340 |       if (navigator.getAutoplayPolicy("audiocontext") === "allowed") {
341 |         let ac = new AudioContext();
342 |         ac.onstatechange = function() {
343 |           if (ac.state === "running") {
344 |             // Start running audio app.
345 |           }
346 |         }
347 |       } else {
348 |         // Audio context is not allowed to start. Display a bit of UI to ask
349 |         // users to start the audio app. Audio starts via calling ac.resume()
350 |         // from a handler, and 'onstatechange' allows knowing when the audio
351 |         // stack is ready.
352 |       }
353 |     
354 |
355 | 356 |
357 | Example of querying by a specific media element. 358 |
359 |       function handlePlaySucceeded() {
360 |         // Update the control UI to playing.
361 |       }
362 |       function handlePlayFailed() {
363 |         // Show a button to allow users to explicitly start the video and
364 |         // display an image element as poster to replace the video.
365 |       }
366 | 
367 |       let video = document.getElementById("video");
368 |       switch (navigator.getAutoplayPolicy(video)) {
369 |         case "allowed":
370 |           video.src = "video.webm";
371 |           video.play().then(handlePlaySucceeded, handlePlayFailed);
372 |           break;
373 |         case "allowed-muted":
374 |           video.src = "video.webm";
375 |           video.muted = true;
376 |           video.play().then(handlePlaySucceeded, handlePlayFailed);
377 |           break;
378 |         default:
379 |           // Autoplay is not allowed, no need to download the resource.
380 |           handlePlayFailed();
381 |           break;
382 |       }
383 |     
384 |
385 | 386 |
387 | Example of querying by a specific audio context. 388 | [Web Audio](https://webaudio.github.io/web-audio-api/#allowed-to-start) 389 | uses [=sticky activation=] to determine if {{AudioContext}} can be allowed 390 | to start. 391 |
392 |       let ac = new AudioContext();
393 |       if (navigator.getAutoplayPolicy(ac) === "allowed") {
394 |         ac.onstatechange = function() {
395 |           if (ac.state === "running") {
396 |             // Start running audio app.
397 |           }
398 |         }
399 |       } else {
400 |         // Display a bit of UI to ask users to start the audio app.
401 |         // Audio starts via calling ac.resume() from a handler, and
402 |         // 'onstatechange' allows knowing when the audio stack is ready.
403 |       }
404 |     
405 |
406 | 407 |

Security and Privacy Considerations

408 | Per the [[security-privacy-questionnaire#questions]]. 409 | 410 | The API introduced in this specification has very low impact with regards to 411 | security and privacy. It does not expose any sensitive information that can be 412 | used to to identify users. It does not expose any ability to control sensors 413 | and any users' devices. It does not introduce any new state for an origin that 414 | will persist across browsing sessions. It does not allow an origin to send any 415 | data to the underlying platform. It does not introduce or enable new script 416 | execution and loading mechanism. It does not allow an origin to draw over a 417 | user agent's native UI. It does not allow an origin to detect if users are in 418 | the private or non-private browsing mode. 419 | 420 |

Acknowledgments

421 | This specification is the collective work of the W3C media Working Group. 422 | 423 | The editors would like to thank Alastor Wu, Becca Hughes, Christoph Guttandin, 424 | Chris Needham, Chris Pearce, Dale Curtis, Eric Carlson, François Daoust, 425 | Frank Liberato, Gary Katsevman, Jean-Yves Avenard, Jer Noble, Mattias Buelens, 426 | Mounir Lamouri, Paul Adenot and Tom Jenkinson for their contributions to this 427 | specification. 428 | --------------------------------------------------------------------------------