Tell HN: Legacy WebAudio content will break in Chrome 70

Heads up: Chrome 70 (due in October) will restore a content policy that breaks most/all WebAudio content that hasn't been fixed to follow the policy.

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.

88 points | by fenomas 2033 days ago

9 comments

  • jeroenhd 2033 days ago
    From the WebAudio spec (https://webaudio.github.io/web-audio-api/#allowed-to-start):

    > 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...).

    • fenomas 2033 days ago
      > I can't think of an example where auto playing audio without user interaction is a good idea anyway

      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...

    • sp332 2033 days ago
      The implementation is bad for developers and bad for users. Check out the comments from the last time it was implemented https://news.ycombinator.com/item?id=17036803 and removed https://news.ycombinator.com/item?id=17079724
    • _Tev 2032 days ago
      > I can't think of an example where auto playing audio without user interaction is a good idea anyway.

      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)

  • rcfox 2033 days ago
    While this sounds like a good change in theory, it doesn't really help against people who really, really want to play their sounds.

    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?

    • tinus_hn 2032 days ago
      I presume you never used the web right before popup blockers became a thing, it was terrible. Really not the same as the few shady sites that use tricks to show one popup these days.
  • amluto 2033 days ago
    I can think of a far better browser policy: no sound until the user explicitly allows sounds for the page. Just like location services.

    Because, damn it, I generally don’t want sound. And I definitely don’t want sound unless I explicitly ask for it.

    • uglycoyote 2032 days ago
      Yes, I agree completely. Reading the discussions, it seems that the chrome team had sidestepped doing this as it would involve a "non trivial UI" but I am scratching my head wondering how a dialog box that says "do you want to allow websites from the domain xyz.com to play sounds?" constitutes a non trivial amount of UI work.
  • nfriedly 2033 days ago
    I believe that this restriction has been in effect on mobile for quite some time (in fact, I don't think mobile Safari ever had WebAudio without this limitation.)

    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.

    • fenomas 2033 days ago
      > But as a user, I appreciate the fact that websites won't be able to just start playing audio without some interaction from me.

      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.

    • asplake 2033 days ago
      I don’t know if this contradicts your belief about mobile Safari, but it continues to bug me that browsing to CNN often (always?) stops whatever audio I already have running. I look forward to the day when all browsers prevent this kind of unwanted behaviour.
      • jernoble 2033 days ago
        That should have stopped happening in iOS 11.4. If you’ve upgraded to-or-past that and you’re still seeing that happen, please let me know: email in profile or @jernoble on Twitter.
        • asplake 2031 days ago
          Noticed it only a week ago, but since upgrading to 12.0 I can no longer reproduce. Awesome!
      • favorited 2033 days ago
        The iOS Twitter app does this all the time for me. I'll be listening to an audiobook and scrolling my Twitter feed, and the audiobook will pause as soon as a (muted!) video appears in my timeline. It's infuriating.
  • zorpner 2033 days ago
    As predicted by this comment (and others) on the bug: https://bugs.chromium.org/p/chromium/issues/detail?id=840866...

    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.

    • tinus_hn 2032 days ago
      Who would have known? Unmaintained software eventually breaks! Cue the tiny violins.
  • michaelmrose 2033 days ago
    So obviously do whatever is required for content to work and if you don't enjoy being jerked around put a little badge somewhere "Best viewed in firefox" with a icon and a link to the download page for the users platform.
  • chaz6 2033 days ago
    I presume that they do not gift the user with a preference to change this behaviour (either globally or per-sitei), or allow an extension to override it?
  • larkeith 2033 days ago
    Does this follow the relevant standards, which I presume exist? Or is Google making a breaking change and requiring the web change to accommodate?
    • gsnedders 2033 days ago
      > Does this follow the relevant standards, which I presume exist?

      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.

      • sp332 2033 days ago
        ^ Could someone who downvoted this comment explain why? Is it wrong or what?
    • nfriedly 2033 days ago
      This is part of the standard. It basically leaves the choice up to the browser:

      > 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.

    • fenomas 2033 days ago
      I'm no expert but I believe it follows standards. Quoting the spec:

      > 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".

      • gsnedders 2033 days ago
        That's a non-normative note, the normative statement that allows the behaviour is the paragraph before that.
    • jamesgeck0 2033 days ago
      It does follow standards, and it does break a lot of old browser games, some of which aren't maintained or can't be easily updated.
    • kakarot 2033 days ago
      WebAudio is caught in standards limbo. I learned to just stay away from it a while back until it's fully standardized.

      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.

  • jimmaswell 2033 days ago
    This whole thing is atrocious. We had a brief period of HTML5 stuff being cool and fun, and now Google is doing their best to completely ruin it on Chrome, which has such an undeservedly big market share that web apps have to work around all these asinine restrictions and gotchas. They already ruined some of my one-off pages that play sound because now the user has to click them to start them. Do notification noises even work in Chrome now?