Howler.js: Chrome autoplay policy changes

Created on 19 Apr 2018  路  112Comments  路  Source: goldfire/howler.js

Chrome 66 have changed its autoplay policy:

An AudioContext must be created or resumed after the document received a user gesture to enable audio playback.
https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio

mobileAutoEnable could be updated to adjust for Chrome (desktop and mobile) as well.

Most helpful comment

Unsubscribed. You guys are bad software devs.

All 112 comments

Maybe a subject of its own, but could we somehow register the start time of a play call and use that to seek to the offset position when the AudioContext is resumed? This to avoid having all created instances fire of at the same time when resumed. Sounds are very often timed to visual events which is so frustrating with the new policy. This would be a very good reason for more devs to use this library.

Maybe we could organize to unbreak the internet? I cannot even imagine the economic cost of everyone--most working for free--spending time to hack around these content restrictions.

Hoping for a fix in 2.1.0 ! Gosh darn it chrome you broke my little toy app!

FYI, the mobileAutoEnable system should still be working on desktop Chrome as well. I just marked it for 2.1.0 as it now makes sense to update the API naming since this isn't a mobile-only issue anymore. If anyone is seeing issues with this not working with Chrome desktop then that would be a more urgent matter.

@goldfire I'm having issues due to this Chrome update. In the application I'm working on every time a sound is loaded I'm seeing the warning mentioned above, which results in the sounds not playing.

Since in Google's autoplay policy (https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio) it is mentioned that muted autoplay is allowed I've tried to load the application sounds with the mute setting set to true - but so far I didn't see any difference. I don't know if there's any workaround at the moment, or maybe I'm doing something wrong.

Since you mentioned mobileAutoEnable, am I correct in assuming that the mobileAutoEnable is enabled by default? And if so, sounds are played once there's the first user interaction?

There is currently an open Chromium report about this that is picking up a lot of support. If we can at least get them to add a way to detect this it would make it much easier to handle within the library: https://bugs.chromium.org/p/chromium/issues/detail?id=840866.

Thank you for your reply, let's hope we'll have a way forward soon. I'm a bit disappointed with this change but that's the life of a developer I guess haha.

It's not just the problem with resuming the AudioContext, it's also about what should happen when it does. Right now all the sounds that I've tried playing before it's resumed (showing the warning) is played in the same time when resumed.

Everybody go to the bug report and vote for it. https://bugs.chromium.org/p/chromium/issues/detail?id=840866

@goldfire I believe there is a way to test it by checking the state of the AudioContext.

From their docs there is this:

To detect whether browser will require user interaction to play audio, you can check the state of the AudioContext after you've created it. If you are allowed to play, it should immediately switch to running. Otherwise it will be _suspended_. If you listen to the statechange event, you can detect changes asynchronously.

At least that way people using Howler will be able to inspect the state. I've been looking through how howl.state() works and if we had access to the raw state value from the audio context it'd allow us to check if interaction is required.

Edit: As it currently stands, state() only returns if it's loaded essentially and playing() will be true despite it not _actually_ playing.

Somewhat related

@Sieabah Unfortunately, this behavior is not consistent across browsers, which is why howler tries to resume the audio context on play. However, if the audio is still locked, the promise on resume neither resolves nor rejects, essentially leaving the state in limbo. I'm sure we can find a way to work around this, but I'm hoping we hear something soon on what/if anything is going to be changed.

@goldfire Right, but you could detect this issue by detecting (for chrome) whether the state is suspended or not immediately after play? I'm all for the universal solution, but currently there is no way to use howler is a reactive way.

I'm against google making this huge change just because they're a huge browser, but I don't believe they're going to back down on this. Is there any reason why you use resume() and not play() to check if audio is locked?

Off the wall solution, would it be possible to play a tiny sound file that is dead silent at init to see if audio is locked?

I just added this Chromium bug relating to the issue with AudioContext.resume: https://bugs.chromium.org/p/chromium/issues/detail?id=842921

Chrome has reverted this change on Web Audio (not on HTML5 Audio) and has said it will come back in Chrome 70, due for release in October. The AudioContext issue is also fixed in Chrome 68.

@goldfire Great news!

Good news, but only delays the massive side-effects of this change until October. But at least we (and Chrome) have some time to smooth things out.

Commit https://github.com/goldfire/howler.js/commit/310736b33da50bb8f075eab2eb8a34f66fbc857b updates mobileAutoEnable to work on Chrome as well. I'm going to keep this open though as the naming really needs to updated as a breaking change since this will no longer only apply to mobile.

@goldfire Where does howler stand in supporting the new chrome autoplay api changes?

I'm using react-howler, but I had some luck detecting instances when autoplay is blocked by checking if window.Howler.state == 'suspended'

@abelsonlive Seems messy to check the window object directly.

Any way forward on this? At the moment the following warning is being shown in the console:

The Web Audio autoplay policy will be re-enabled in Chrome 70 (October 2018). Please check that your website is compatible with it. https://goo.gl/7K7WLu

I'm not understanding what I should do, will this be handled by howler or must the application find a solution for this?

Hi,

I was able to catch this error and handle it using the onplayerror handler. There is not much you can do to stop this from happening, but handling it and showing a play button (instead of a pause) and stuff like that is easy.

Sorry about the delay, I've been swamped lately. I'm working on some changes to address this though.

Okay, so I'm considering two different approaches here:

  1. If the audio is locked, howler just throws a playerror and discards the playback.
  2. As suggested above by @inear, the time the playback was started is tracked and then when audio is unlocked, howler either seeks to the position the sound would have been at or discards the playback if it would have already concluded.

Option 2 I think would be the most beneficial for most applications, but does anyone have any scenarios where this might be best left to the application to handle (and thus going with option 1)?

The issue with Option 2 is you wouldn't know that the play failed unless you kept checking either after playing or in a loop elsewhere. Which creates an awkward loop of logic whereas if you errored on play you could create some popup asking for user input.

@Sieabah The library would still be detecting that the audio is locked either way, that would be able to be checked at a global level.

Option 2 sounds like the best option but please keep emitting the playerror event described in Option 1. The only thing I can think of that would be a problem with Option 2 is if it adds too much code to the library.

I would appreciate the functionality in option 2 to be available if possible, but could live with using a option-parameter to activate sync to intended global time for sounds that is part of a visual timeline. And use option 1 as default. With that per-sound-parameter we could use it in places where we don't know of context is created, like in cinematic intros, or after the first load. Also, we then don't magically solve the issue, but encourage devs to think twice about their solution and learn to design for the autoplay policy, because it seems like it will stick around. The option 2 is a way out for existing sites where we don't have control over the flow. Or if we just can't have an interaction point at the beginning of the experience.

@goldfire So the intended solution is to have code which checks every x seconds or so to see if it's locked and provide a prompt? How would you trigger all the sounds to play again or would Howler automatically do that?

It just seems messy to have check at the global scope.

As I've played around with this more, I've started leaning towards option 1. I'm seeing the potential for a lot of edge cases and I'm also starting to think option 2 makes more sense as a possible plugin rather than in the core library. I'm working on putting this together in a way that will be easy to detect and handle in advance of Chrome 70 dropping (I was hoping to already have this done, but I've been out of town a lot over the last month).

@goldfire I think throwing something like a playerror or something specific to chrome autoplay would be good enough for most cases. How have you been reliably testing the autoplay? Whenever I modify the chrome config to restrict 100% of the autoplay it still just plays.

Since my previous bug report was closed, I had assumed the issue with AudioContext.resume not rejecting when audio was locked was fixed. Not surprisingly, that is not the case, so I've created a new issue: https://bugs.chromium.org/p/chromium/issues/detail?id=884337.

That was the plan to detect if the audio was locked, so now I'm trying to find an alternate solution. I'm all ears if anyone has any ideas.

I'm quite new to the howler library, so I don't have any suggestions for you on how best to work around the autoplay policy changes, but I just wanted to provide my encouragement for your efforts. You have a great library that is doing a big service to a lot of developers and if you are able to provide a sensible way of handling the Chrome audio restrictions it would be hugely valuable. Thanks for your efforts @goldfire!

Safari 12, which was released today, has a similar issue where if "Auto-Play" is not allowed in settings for the website (which seems to be the default), web audio will not play (tested with latest version of Howler.js). I'm also noticing that in Safari 12 the AudioContext.resume promise does not resolve or reject similar to the chromium issue. The "Spatial Audio" demo on the https://howlerjs.com homepage does not work on Safari 12 unless Auto-Play is allowed, but it does work on Safari 11 even without Auto-Play being allowed (I tested both).

Google is poorly handling this clusterfuck

I just pushed a155a1933b99dfb7be3e8ce553ece850f231a2e5 to master, which fixes playing() not showing the correct value when audio is locked.

Thanks for coding a workaround into the new version of Howler, Gold!

FYI, the autoplay change has again been pushed back to Chrome 71 in December.

Does it mean that we can't enable autoplay on Chrome until Chrome 71 version ?

Commit https://github.com/goldfire/howler.js/commit/8cfb3978ec5aa5f2a4028424f5aab9c24a8be9b0 has changed the name of this to autoUnlock since it applies to more than just mobile. There is still no way to directly test for the audio being locked, though there are some proposals in the works. Chrome is going ahead with the change anyway, which means you need to make sure your first audio happens in a user interaction for it to work. I'll leave this open as this continues to evolve.

Hey goldfire, thanks for the update. Any chance you could provide a high level summary of the recommended usage pattern given the changes, I've been following along. but not super closely.

Any chance of a small example code illustrating how to ensure that the first audio playback is triggered by a "user interaction" and how using the autoUnlock flag would factor in?

I can probably figure this out through some trial and error plus searching about, but if there's any existing documentation or example code which explains how to comply with the policy changes I know it would help me out and I suspect others as well who may be discovering this issue.

Either way, thanks for your work to continue improving your great library!

@aaclayton The general rule is do not play audio unless it's after a direct user gesture, only then can you play.

Essentially this change makes "autoplay" unreliable until your site has a high usage score, of which you still can't rely on.

Hey @Sieabah, thanks for your clarification, but I'm afraid this was the portion of the change that I did already understand.

What isn't clear to me (and I likely need to just spend some time googling about) is what the best practices are to associate the audio playback with a user gesture. For example, my app has a click listener, when the button is pressed I get Howl to begin playback of some audio. Does Howler expose a convenient API to determine whether or not the audio context is available to be used?

EDIT: Nevermind, my example usage does in fact work properly. So I was mixing something up which caused confusion on the root cause of the error.

For example.... simple usage:

$("#mybutton").click(ev => {
   new Howl({src: "path", autoplay: true});
});

Currently exposes a Chrome warning for me, although clearly this audio is played as the result of a user gesture. What's the right way to do this?

@aaclayton Create the new Howl outside of the click listener and then call play() inside the click.

@aaclayton You never explicitly _played_ it inside. It was an audio tag created async from the click event handler but it's "autoplaying" which is unreliable.

It should work if you create the howler instance and call play in the same click handler. Alternatively the approach of having the howler created outside and playing it inside also works. I wouldn't create howler instances unless they self destruct after sometime.

Thanks for the feedback, both of you. Appreciate the follow-up!

Hey all. Sorry for the long winded buildup just giving context. I have an interactive comic book for a client that I started well over a year ago (before all of the autoplay stuff). The comic is spread out across 17 chapters (which are on 17 individual html pages) and contains multiple sound objects starting/playing/stopping in sync to animations on a page and soon even a surround sound version. Basically, there's a lot going on once you enter each chapter of the comic. Unfortunately, It's too late to try and combine all of this work into a single page experience with a single enter button. Because of all the autoplay issues across the various browsers & mobile I currently preload all of the imagery/audio and after the preloading is complete I animate in an "ENTER" button for ALL pages regardless of browser/desktop/mobile. That is not a great experience but it works. I would like to see if I can reduce the need for the ENTER button on every page if possible.

I've read about the autoplay policies like Media Engagement Index (MEI) and I'm seeing that working on the dev version of the comic site. On chrome 71 the audio now plays when I change up the code on the pages to bypass the enter button after the preloader. Audio now plays even if I have have not interacted with the page. I am assuming this is because I've refreshed these pages hundreds of times the past year and or just in the last couple of hours tonight and Chrome knows it. This is great for me but it makes me nervous because it's now a little harder to test the site under typical user situations of a first time or unfrequent visitor.

Given my above situation, I'm looking for current best practices to try and know whether or not the audio has been unlocked. What I'm reading here is that my only strategies with howler is to try and play a small mp3 file (without any loud audio) when any page in the site is preloading and then listen for the "onplayerror". Then based upon if there's an error show the button? Does that sound like a safe solution? Or am I missing some variable that I can check that would give me this? Thanks in advance for any help and taking the time to read this.

@shanemielke So unfortunately because it's based on metrics you can't get around the autoplay per-page. That's the entire point of why they did it this way I assume. You're going to have to make it a SPA app if you don't want to have to have an enter page per page.

The only reason why it's playing while you're developing because you're engaging with the url enough times (I've experienced this locally). You have to start chrome from the CLI with some extra flags to be able to test from the perspective of a user first coming to the page. I haven't found a better way to do this.

I think the best approach, is to have an enter per page, it's not a great experience but it's the _experience_ chrome wants for the future. For some stupid reason.

We use Howler to play pops when our chat application receives a new message to be read, using Vue. Below is a solution to eliminate the warning, and to only play pops on unreads once our users actually engage with the page (by activating a conversation, for example).

mixins/popper.js:

import { Howl } from 'howler';

let Howler = null;
let canPlayPop = true;

export default {
    methods: {
        pusherMessageReceived() {
            // This is called by our pusher.listen() config elsewhere in the app.
            this.playPop();
        },

        playPop() {
            // This will bail out until Howler has been initialized, or if we're currently playing a pop sound.
            if (!Howler || !canPlayPop) {
                return;
            }

            canPlayPop = false;
            Howler.play();
        },

        waitForClickForHowler() {
            // Remove the event listener right away so we don't call this more than once for a click happy user.
            document.removeEventListener('click', this.waitForClickForHowler);

            // Initialize our Howl instance.
            Howler = new Howl({
                volume: 0.4,
                src: ['/sounds/notification.mp3'],
                preload: true,
                onend: () => {
                    canPlayPop = true;
                },
            });
       },
    },

    mounted() {
        document.addEventListener('click', this.waitForClickForHowler);
    },
};

This mixin is imported into our primary App.vue. Once a user clicks anywhere on the document, we initialize Howler, and then when a new message comes in we can play a pop. No warning, functional, and adheres to the Chrome reasoning for this behavior.

@ellisio I'm curious what your Howler global variable is set to after the click event occurs.

I still think from a usability point where you load the page (and are logged in) that page should be able to play the pops. What about the use case where they don't click anything but just load the page and switch tabs, waiting for a chat?

When I鈥檓 back at the computer I can post a JSON string of my Howler global variable.

I agree about that use case whole heartedly. It鈥檚 annoying that Howler is blocked until interaction with the page happens. Since it鈥檚 blocked, this way just eliminates the annoying console warning.

We can initialize the Howler variable in mounted(), which causes the console warning, and will still play the pop _after_ a user clicks on the page at least once. Until a click happens, no pops play.

No need to paste the whole output, I was just wondering from your code if you may have overwritten the global variable. I guess it'd just overwritten in your scope which _could_ be fine.

Seems the issues are still intermittent... If you start with a click event and call load(), playing from the on('loaded') event does not allow you to play.

Hey everyone, having a problem recently with the fact that all audio plays simultaneously after a user action, I was wondering is there a cross-browser way to detect that chrome "locked" the audio context? any property on a Howler obj? I have a wrapper already so would rather just check for the possibility to play and not play audio at all instead of queuing it to destroy user's eardrums.

I would've poked around myself but I'm not sure how do I force chrome to lock my audio context as if I'm entering the page for the first time, incognito mode doesn't help... any tips?

dead silent :(

@MaxYari There is currently no way to detect this, though there are some proposal currently being evaluated at the standards level. Once those make their way into browsers then we'll get them into howler. Google's documentation tells you how to force the audio to be locked: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes.

Hm, so the fact that all sounds then play simultaneously after user action - is this a default chrome behaviour or something that howler does? There are sites that don't have this problem of all audio blowing your speakers upon user actions.

Having the same issue with sprites all playing at once. Based on a Howler internal investigation, it seems Howler cancels the end timer if audio is suspended (removing the clear timer does not fix this), and when it unlocks triggers the playWebAudio function. The function then essentially triggers a play on all sprites/contexts even if the sprites duration has already passed since the call to play. Calling stop in the locked state at least causes it to not play. But even if you play a bunch of 1 second sprites, tapping the screen 5 minutes later causes every single one to play at once.

@goldfire maybe I've put it wrong while asking about it, but https://developers.google.com/web/updates/2017/09/autoplay-policy-changes that you've linked does describe (or at least gives some idea) how to detect that audio is locked by browser/can't be played, so it's possible to omit any playback attempts in such case. Thanks for the link.
For anyone interested: In essence, I check for Howler.state right after I attempt to construct any Howls (after all of my new Howl(...) initialisations). If Howler.state == "suspended" I create a bool signalling that audio is locked and page interaction is required. Whenever I want to play a sound (I have a wrapper function) I check for that bool and don't play anything if true. I also listen on window for click events and as soon as such arrives - set the aforementioned bool to false.

So right now there is a way to detect Howler audio blocked by chrome policy?

@cmbuckley You can. Just play test sound and check onerror: https://github.com/goldfire/howler.js/#mobilechrome-playback

Hi, I am developing a react app and I want to use howler, but I'm getting this error on Chrome Version 73.0.3683.103 (Official Build) (64-bit)

The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu

In this issue there is some hints about this but I can not find the right patch or the solution
Can someone help me please

@jjavierdguezas I'm assuming that you have some sound that's autoplaying when the application starts. The best solution I've found to cater for this is that the application doesn't play sound or load any sounds automatically on application start. If it is possible have some kind of "sound on/off" button that by default is always off.

With this approach the first time sound is enabled (after a user click) you will then trigger the loading and playing of sound. This is the approach must online games are using nowadays. I find this approach the safest as you always know that there is a user gesture prior to playing the sound.

@dangrima90 thanks for you reply. My app does not play a sound when the app starts, but when external events arrive (I'm using signalR). The sounds are sometimes reproduced and sometimes not. I will try to introduce the button to activate / deactivate sounds, but I do not know if it will fulfill the client's requirements 馃槙

As long as you play one sound under a touch event, others can later play without one.

@jjavierdguezas I have a similar application pipeline where audio is played from events, similar to a chat notification. My experience has been the audio element has to be created via a gesture. You cannot create new sound elements unless you have bypassed the MEI score to be able to autoplay.

I believe the workaround is to create a lot of them on the first gesture and reuse them as necessary.

Angry dev here because of Chrome idiocy. Has anyone figured out an exploit to bypass the autoplay restriction yet? It breaks my financial application which makes a "ding" sound to let people know a trade has occured.

@Tectract the only way to bypass it is to have the audio play blank files off of any button press and play the beep at a later point using the original audio element.

@Sieabah I don't really understand your answer. I have a "ding.mp3" that needs to be played, periodically, possibly as little as once per day or even less, that alerts my users to a trade which has occured on their account. Clicking buttons is rarely used in my application, and it is not expected that a button will be clicked on most page loads, so I cannot just wait for a button click to play my sound. The intended use is for the page to sit in the background until it "dings" and alerts the user to go look at it. This is truly a case where I CANNOT wait for a user interaction because the sound is designed to TRIGGER a user interaction.

I'm explicitly asking you guys to help me design an EXPLOIT to get around this BUG which Chrome has introduced into their browser that has broken my financial trading application.

There isn't one. You may not like it (I don't either), but this isn't a bug, this is how Chrome is designed to work. You need a user interaction to unlock audio capabilities. Doesn't have to be on a button; it can be on a transparent div overlay or something so the user is oblivious.

I'm sorry but it's a bug. It broke my application. My app is DESIGNED to play sounds after long periods of inactivity without user interaction and my users WANT that. The chrome devs have removed a valid feature in order to try to kill autoplay videos, which could have been done in a THOUSAND more graceful ways.

I GAURANTEE there is a work-around. Let's work together to find it.

What about if we just try simulating button clicks programmatically, through jquery, periodically? There must be some way to "fool" the browser into thinking a user has "interacted".

There's a list of companies whose pages were broken by this bug, and about a hundred devs screaming "PLEASE DON'T DO THIS" at the chrome devs before they implemented it, here:

https://bugs.chromium.org/p/chromium/issues/detail?id=840866

This bug has affected many company's bottom lines, adversely. I'm considering contacting these companies to form a class-action lawsuit against Chrome, now.

Chrome can detect whether an event is simulated or not.

This policy was a way to stop advertisers auto playing annoying sounds. It's been a requirement on mobile for years, but is recent to desktop. No one likes how they've implemented it, but good luck suing them.

I won't help you further, and I doubt you'll get help from anyone else in this thread, because your attitude to recieving help and advice hasn't been great. I'm sorry you're not getting the answer you were hoping for, but it's not our fault.

To you it's a feature, to all the companies whose pages got broken and valid use-cases broken, it's a bug. You, as a developer, have a responsibility to ADD features, not BREAK EXISTING applications designed on your platform and LIMIT use-cases. This was a sloppy, horrible patch that was done badly. It was a business decision by Google that negatively impacted the bottom lines of many other business, and they are liable for those losses, imho.

@Tectract We all got screwed by this, my application is entirely socket event driven which is 0 interaction for many events. Google doesn't really care about you or your application so I suggest you get used to dealing with this Chrome _feature_. As most people see autoplaying audio as a negative experience overall.

If they added a way for users to whitelist certain websites that'd be great, but alas they don't have that functionality. As I told you if your application design is meant to play when they're not paying attention then on first page load you must require _some_ user interaction. Chrome doesn't care _what_ does it as long as it's a user clicking. We don't need your unhelpful comments that provide no real value towards a fix. If you feel that strongly then go and sue Google, or post on their message boards relating the autoplay issue.

The way around this is literally as I said. On first page load you can require users to click a button to _activate_ your application, from that click you instantiate your Howl object with a silent file (silent.mp3). From then on you have access to that playable audio instance, you cannot create another without another user interaction. So if you have to play multiple sounds or you want a buffer then on that first click spawn a few Howler instances and keep them in a global pool to play other sounds.

Just be glad we have what we have now, before it just plain didn't work and there wasn't a reliable way to start audio.

I'm a hacker. There's an exploit, and I'll find it. Clicking on the page to enable sound, over and over, is not a part of my application flow, and it never will be.

Well if you never have any user interaction ever on any part of the page then it sounds like a kiosk, just use a different browser.

Good luck, we gave you the solution. I spent months trying to find any flag/combination/hack with any events, they really locked it down because (surprise, surprise) the ad companies are faster and smarter than you.

Requiring clicks is not a solution. That is the BUG. Maybe you can go tell all the people who work for those companies whose applications were broken that their site is just a "kiosk", and they shouldn't use the most popular browser anymore either. I mean, that's patently absurd, if you ask me.

@Tectract part of the reason why such a feature exists these days is that there are some people who find it annoying if they open a website and that website either immediately or at a later occasion all by itself starts to make use of the speakers to play some stuff some developer found funny, interesting or maybe even helpful (having then to go through open tabs to find which website is the cause). As it has proven to be quite ineffective to ask all the devs out there to be good citizens and let the user decide if they actually want to hear sounds from that website, a few other devs have decided to build such feature into browsers so that devs no longer have the power to annoy users by making unwanted use of the speakers. From that day on websites would start in a muted state and when the user wanted that page to play some sound they would press a speaker icon to enable sound or hit play to start a song or whatever other reasonable means there are.

As of chrome, all you have to do is make use of a single audiocontext (apple has already recommended that a long time ago) for all playback and on a user interaction (as mentioned above) call the resume() method on that context. From now on you are able to play back any sound at any time you want without going through hacks, that usually break one way or another once another browser version is released. I can see that this can cause some pain and headaches with long running sessions and server side rendered pages as you could end up with a new locked context on every page load. However I hope this provides some helpful context on todays browser behaviour and some inspiration on how to work around your issues. Afaik howler already incorporates known workarounds to automatically unlock the audio context and I am sure some people will appreciate if you can find and add more ways to achieve just that.

Google also published some information on how you can still make use of autoplay with current browser versions without having to resort to hacks

@Tectract "bug" is not a feature that you don't like, neither the feature inducing the bug in your app is a bug in itself. As per wiki: "A software bug is an error, flaw, failure or fault in a computer program or system that causes it to produce an incorrect or unexpected result, or to behave in unintended ways".
This feature and its behaviour clearly weren't unintentional.

On a side note: does context actually gets locked after some time of inactivity on long sessions (without page reloads)? I was under the impression that only a single action per loaded page is required, after which you can playback as much as you want, which works pre good for SPA.

Just because it was the intention of Chrome devs to introduce this bug doesn't magically make it a feature. It's a BUG.

All I hear is "blah blah blah, we can't imagine any reason any site should be able to use background sound and we want to impose our idiocy on everyone".

on a user interaction

BUG

Unsubscribed. You guys are bad software devs.

@Tectract I think you need to accept the update to the policy and deal with it. All that's needed is a simple user interaction - it won't break your application.

I understand that the change did break your application, but it's not the end of the world. As been mentioned by others there are plenty of reasons why this policy has been put into place. Speaking from my experience - yes it was annoying as it did break the applications I've built but at the end of the day it's not just Chrome that's implementing this policy. This policy has been in place on Apple for a while and also there's been a discrepancy between desktop and mobile devices with regards to this policy.

Like it or not at least now we have consistency with different devices and browsers - it's not difficult to handle. The way I have solved it is to simply have a sound off/on button on your site which is always off by default. Therefore for a user to switch on the sound they have to click and you're done.

I'd call that a simple solution with a small compromise - whether you like the implementation is another matter 馃槃

I'm running into the same issue. Chrome won't let me play music without having user click on something. Also; audio stops abruptly when playing and I've no clue if it's a related issue.

@TheBigK Did you read the thread? It's a feature of chrome not a bug.

As for it stops abruptly, are you sure you're not triggering a stop event or your audio file isn't corrupted? Think that may be a separate issue (new issue on this repo).

It's a feature of chrome not a bug

That's laughable, it's a huge bug. This is one of the biggest engineering screw-ups I've seen in a long time. In order to "disable autoplay video", Chrome devs instead decided to disabled autoplay audio, thereby breaking thousands of gaming and financial applications over the SCREAMING OBJECTION OF DEVELOPERS, while failing to actually BLOCK AUTOPLAY VIDEO, and doing it in a way that there's no easy way to permanently whitelist any site.

Oh yeah, if that wasn't bad enough, then they rubbed salt in the wound by excluding their own web properties from this bug:

https://arstechnica.com/gaming/2018/05/chromes-autoplay-video-blocker-is-accidentally-killing-web-based-games/

There's a million ways to workaround this. Why are you so bent outta shape?

Not really. It broke my application that's why. Chrome devs are idiots who introduce new bugs instead of properly fixing old ones, then they dust off their hands, "Job well done! Oh wait, just exclude our own sites, because that breaks everything hahaha!". It's insulting to developers and their users whose time gets wasted, and it degrades the web experience of millions of people and makes the internet less useful, that's why.

How can I make my application play notification sounds to alert them about trades on their accounts after long periods of inactivity, @fallingC0de? They have to come and click on the page again. They can't whitelist my site. It's a BUG, not a feature. I still have TONS of autoplay video popups modal spam about newsletters on EVERY SITE, they can't fix that, but they can break my bespoke trading platform. THANKS CHROME, MORE BUGS PLEASE!

please, I and I'm sure a lot of colleagues are subscribed to this issue to be up to date with any change on the subject, do not spam this with personal opinions or discussions that do not contribute anything, just please

So, after long periods of inactivity the sound is muted like it was when they first come to the page? How long does the inactivity have to be for that?

So, after long periods of inactivity the sound is muted like it was when they first come to the page?

Yes, Chrome auto-mutes your page again if a certain activity indicator score goes too low. Or if they just didn't click on the page initially. I could make a button that is MUTED at the beginning that they would have to un-mute with a click, I think, but it would only be temporary.

How long does the inactivity have to be for that?

Could be periods of unknown length, days or even weeks potentially. The sound is supposed to alert them to come and look because a trade has occured, or to notify you while you are around the house not at the computer. This is a feature my customers WANT and LOVE, but chrome broke it. What I want to do is specifically what they disabled, instead of actually disabling autoplay video.

Yes, Chrome auto-mutes your page again if a certain activity indicator score goes too low. Or if they just didn't click on the page initially. I could make a button that is MUTED at the beginning that they would have to un-mute with a click, I think, but it would only be temporary.

You sure about that? I've accidentally left my site playing for a very long time and it was still playing >24 hours later. Would greatly appreciate a link to the source to prove your point. Otherwise you're making claims which are false.

This is a feature my customers WANT and LOVE, but chrome broke it. What I want to do is specifically what they disabled, instead of actually disabling autoplay video.

Grow up and deal with it. Stop bickering about it here when we already agree with you it's a dumb feature. You're being a broken record with your immature approach to this topic. We all get it, your precious application is broken, so did ours. How did we fix it? We worked around their dumb user engagement. If you want your app to be fixed you have to do it that way. You can't refuse on principle to do it and complain that it doesn't work, at least not here of all places. Go complain on the google forums like you do here and see how that works out for you.

I've given you multiple ways to fix the problem for yourself and it's your own fault at this point to not adjust to their dumb policy. Literally having a toggle for notifications sounds is all you need, and if you even read the spec once a user approves your site for sound enough times you don't need to ask for permission! So if your users come back to your page daily and enable notifications at a point you don't need to ask them anymore. So do that or just be quiet, I personally don't care anymore about how your trading platform doesn't notify your users.

Just keep your repetitious opinion to yourself at this point, it's clearly not forwarding any useful discussion besides giving you a platform to vent.

Grow up and deal with it. Stop bickering

What a shitty dev you are. God I'm glad I don't use any software that you administer. If my employees said that to someone in a support ticket on my repos, I'd fire their asses so fast their head would spin.

If you guys really want to end this thread, tell us all the best ways around this bug, in detail, use references if you have to. Tell us how to re-enable sound once it gets turned off by Chrome, and all the hacks for preventing that, or seemlessly making the problem go away. Tell people it's a bug, not a feature. They set out to stop autoplay video and instead they broke background sound, even after tons of devs told them "this is the wrong way to fix this, you're gonna break all our sites". That's a bug not a feature.

When you're able to convince the goliath that is Google that they're _wrong_, be my guest. So far they haven't ever backed down _even after all games on the internet broke_. Calling me a shitty dev for working around the playground Google has made for all of us is one who isn't wasting time fighting a battle that literally cannot be beaten. Have you not seen the autoplaying audio/video proposal that would ban it entirely by law?

All I know is my applications work again within the dumb constraints put out ahead of me, does yours?

What a shitty dev you are. God I'm glad I don't use any software that you administer. If my employees said that to someone in a support ticket on my repos, I'd fire their asses so fast their head would spin.

I'm being realistic instead of complaining on an issue that Google doesn't even look at. I've agreed with you about this policy but that goes out the window when you want to huff and puff and act like you're the golden standard of what's right. What you're doing is not productive in the slightest and insulting your way to a solution shows that you'd be a pretty awful manager. Maybe your employees tell you otherwise so you don't lash out and fire them? Regardless this isn't the place to _bicker_, _insult_, and _argue_. It's a place to come up with solutions for people running into this issue. The discussion you're looking for is on google's own issue tracker with regards to this issue. I've participated there more than you have so I'm glad you're making an enemy out of, hope you feel good about yourself.

Cool story bro. Fact remains that they didn't disable autoplay, they only broke games and financial apps. It's a bug not a feature. People who call it a feature are useless yes-men. Like you.

Can we close, mute or stop comments on this issue, I'm getting tired of this discussion that isn't helping progress the issue.

@RichardGale at the top of this thread there is a button which should be labeled something like unsubscribe. That might be the easiest/fastest option to resolve unwanted notifications from a single issue. Granted that does not change the fact that most comments here are totally unrelated to howler itself...

I'm tired of people saying "That's not a bug, it's a feature!". And then brushing off the fact that thousands and thousands of people's websites are now broken, with no possible solution, ON PURPOSE BY THE BROWSER DEVS.

You're probably also tired that Microsoft stopped supporting MS DOS ON PURPOSE and broke THOUSANDS and THOUSANDS of MS DOS games. I guess those devs either stopped writing for MS DOS or moved with the times and switched to Windows.

DOS still works.

If my employees said that to someone in a support ticket on my repos, I'd fire their asses so fast their head would spin.

Howler is not commercial software, and GitHub Issues is not a support ticket system.

I'm still angry about this MAJOR BUG that they introduced into Chrome. I'm just an end-user here to say "shit is broken, because of a major upstream bug". Anyone who calls breaking sound on pretty much every site out there, for all use-cases, a "feature", is a tool.

Can someone show some code to detect this situation, or help me fix below, thank you.

I added listening for onplayerror which seems to fire/emit and I am able to show a pause button. However when the user presses the button and the code attempts audio.play no sound plays out, I run into a loop?

Even though intellisense in VSCode does not show it I am treating Howler.play to return a promise.

What did I miss?

There is apparently a couple of parameters with onplayerror accord to the documentation, how do I retrieve those?

  // 20160820
    PlayOne(Media: string) {
        Log.Called(this, "PlayOne", "Media is", Media)
        return new Promise((resolve, reject) => { // return a promise
            this.audio = new Howl({ src: [Media] });                     // create audio wo/ src
            //
            // https://github.com/goldfire/howler.js#onloaderror-function
            this.audio.on('loaderror', () => {
                Log.Event(this, "AudioPlayList", "loaderror")
                reject(Media);
                // reject;
            });
            this.audio.on('onplayerror ', () => {
                Log.Event(this, "AudioPlayList", "onplayerror")
                resolve(Media);
                // reject;
            });
            this.audio.on('end', () => {
                Log.Event(this, "AudioPlayList", "audio ENDED")
                resolve(Media);
                return resolve;
            });

            return this.audio.play()
        });
    }

from the View controller of the application I catch the failed promise like so to tell the view to handle and react by displaying the pause button.

                // -) Invoke the Sound playing
                let Sound = this.Slides.Audio(this.Slides.Index)
                this.AudioPlayList.Play(Sound).then(data => {
                    Log.Promise(this, "PlayIndex", "AudioPlayList.Play", "Done Playing")
                })
                    .catch(error => {
                        Log.X(this, "PlayIndex", "AudioPlayList.Play", error)
                        // https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#best-practices
                        this.UQSView.RequireUserGestureToPlay()
                    })

image

Feel free to fix my "promise" handling and coding I am just hacking my way to JS via TS. One minute I think I understand Promises and then the next minute it's like I never heard of them before.

@goldfire thank you for providing a component that works.

I think you mean by "The library would still be detecting that the audio is locked either way, that would be able to be checked at a global level." that option 1 would be available as well?

IOW, there is a simple mean for the app to detect the situation (a user interaction is required by chrome) and the app retry or create a new howler.play() upon the user click some play/pause/resume button?

Thank you for clarifying, that's the behavior I am trying to fix/code the above reply/request.

So kindly tell me, is there still any way to reliably play a notification sound in a Chrome background tab?

I have to chime in with the Chrome critics in saying that Google should at least have given us an option to declare a website "trusted" so it can play sound at any time.

hi, so I was trying to resurrect the venerable hypnotoad site, which is basically an animated frog and a background sound that needs to play as soon as the page loads, with zero user interaction. How can I make a page play a sound as soon as it is the active page, without having to design an onerous UI forcing the user to click? this site was literally a gif & an mp3 before the Chrome developers removed the feature. can I use an onHover event instead of an onClick?

@Gavitron No, user needs to click.

@stefan-reich did you find a solution? I'm trying to achieve an issue like you said. It works after clicking, but when user refresh page, browser asks again for interaction/gesture.

@ltakato I don't think there is a solution... user needs to click first. You can try to never actually switch pages, for example by using a frame set or by converting the website into a single page with JavaScript reloads (hard but possible). That you keep a page loaded and thus Chrome remembers that the user has clicked.

If user presses F5... you're just lost.

Is anyone having success unlocking with the example given in the docs here? https://github.com/goldfire/howler.js#mobilechrome-playback

I can play the audio after the unlock event but Chrome is muted!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kamkha picture kamkha  路  3Comments

joshbruce picture joshbruce  路  4Comments

tvbird picture tvbird  路  4Comments

bestander picture bestander  路  4Comments

brancusi picture brancusi  路  4Comments