Edit: Note that in general, content will break even if it follows the intent of the policy (by only playing sounds in response to user input). This is due to the nature of Chrome's implementation of the policy.
If you maintain any WebAudio code the fix is below. For any code that hasn't been fixed and isn't maintained, expect it to stop working soon in Chrome. :(
--
Background:
This is part of the "no autoplaying" policy that rolled out in Chrome 66, and was reverted for WebAudio a few days later because it broke everything (including Chrome's own webaudio demos). Chrome 70 apparently restores the same implementation, so any content that broke before will break again, unless patched.
Past HN discussion: https://news.ycombinator.com/item?id=17079724
Policy info: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio
--
Fix and tech details:
The easiest fix is to add a redundant `ctx.resume()` call to any user input event handler. Once that fires, the audioContext will work normally.
Basically Chrome's implementation of the policy doesn't look at when an audioContext plays sounds, it only cares when (a) the context is created, and (b) `context.resume()` is called. If either of those happens inside a user event handler, that context can play sounds. But if you create a context at startup and never call `resume` (like most WebAudio demos), the context will be muted regardless of whether it waits for user input.
> An AudioContext is said to be allowed to start if the user agent and the system allow audio output in the current context. In other words, if the AudioContext control thread state is allowed to transition from suspended to running.
> Note: For example, a user agent could require that an AudioContext control thread state change to running is triggered by user activation (as described in [HTML]).
This means the user agent (the browser) is allowed to choose when the AudioContext can be used. It's up to Chrome to determine when playing audio is allowed.
I can't think of an example where auto playing audio without user interaction is a good idea anyway. This was explicitly warned for in the moving standard since at least late 2016(http://web.archive.org/web/20161031141656/https://webaudio.g...).
The point of this reminder is to alert people that most preexisting content will break regardless of whether it waits for user input.
That is, even content that only plays sounds when a button is pressed will, in general, break, unless it happens to also call `context.resume` in the same event handler (which content predating this policy generally had no reason to do).
I'll add a note to the post to make this clearer...
Ringtones/notification sounds for a communication app.
User is (almost always) logged in from previous session, just opens tab and (because he was never before asked to do anything else) opens another tab with facebook/jira/news/whatever.
It's small-ish UX breakage in niche use case, but it is still valid and will cause our app problems (dev time and worse UX).
(btw NO permission system for this is available or even planned when you look at the chromium bug tracker)
The same policy exists for popups. You no longer get websites automatically popping up windows on load. Instead, they hijack all click events so that they can create popups in response to user actions.
The policy doesn't solve the problem, it just delays it slightly. Is it any less surprising to have sound play when you attempt to click a link or highlight text?
Because, damn it, I generally don’t want sound. And I definitely don’t want sound unless I explicitly ask for it.
So, if your code works on mobile right now, it should also work in Chrome 70.
As a developer, it's kind of a PITA. But as a user, I appreciate the fact that websites won't be able to just start playing audio without some interaction from me.
Also, to clarify the fix, the WebAudio context must be either created or resumed in response to a click/tap/etc. I usually just provide some "Go" button and then create the context in the click handler.
To be clear I agree with the intent of the policy. But Chrome's implementation breaks most/all legacy content even if follows the intent of the policy.
When the policy originally went live in Chrome 66 I went looking through back issues of WebAudio Weekly, and it was a wasteland - everything was broken, including the demos that followed the intent of the policy, with "Play" buttons like you describe.
None of the actual underlying issues have been addressed in the last five months. I would very much encourage people defending this change to go and read the many well-informed comments there, from people attempting to explain how many valuable things will be permanently broken by this change.
Yes.
For <video> and <audio>, the spec only says the UA "may" (RFC 2119) follow the autoplay steps, and the play() method only does anything "if the user agent and the system allow media playback in the current context".
For WebAudio, the spec says, "An AudioContext is said to be allowed to start if the user agent and the system allow audio output in the current context".
So the UA is always allowed to decide whether or not to start playing media.
> An AudioContext is said to be allowed to start if the user agent and the system allow audio output in the current context. In other words, if the AudioContext control thread state is allowed to transition from suspended to running.
https://webaudio.github.io/web-audio-api/#AudioContext
Also, I think Apple did it first, (on mobile Safari) and then Google on mobile Chrome, and now on desktop Chrome.
> Note: For example, a user agent could require that an AudioContext control thread state change to running is triggered by user activation
https://www.w3.org/TR/webaudio/#allowed-to-start
That's essentially what the Chrome policy does - it changes when the AudioContext moves from the "suspended" state to "running".
What had happened was, Mozilla and Google were working on making their implementations compliant, when Google did the thing they love doing that really makes Chrome no better than IE: implemented their own, incomplete version of WebAudio and sent it out the gate. Mozilla then felt pressure to follow suit.
Then we decided the standards needed to be improved again. So now both browsers have a slow, half-assed, broken implementation of WebAudio that isn't good for too much and that neither of them seem intent on fixing until the standards clear up.