goldfire / howler.js

Javascript audio library for the modern web.
https://howlerjs.com
MIT License
23.87k stars 2.23k forks source link

Chrome autoplay policy changes #939

Open robbue opened 6 years ago

robbue commented 6 years ago

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.

ellisio commented 5 years ago

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

I agree about that use case whole heartedly. It’s annoying that Howler is blocked until interaction with the page happens. Since it’s 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.

Sieabah commented 5 years ago

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.

Sieabah commented 5 years ago

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.

MaxYari commented 5 years ago

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?

MaxYari commented 5 years ago

dead silent :(

goldfire commented 5 years ago

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

MaxYari commented 5 years ago

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.

nicholashza commented 5 years ago

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.

MaxYari commented 5 years ago

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

chuski1212 commented 5 years ago

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

gevgeny commented 5 years ago

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

jjavierdguezas commented 5 years ago

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

dangrima90 commented 5 years ago

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

jjavierdguezas commented 5 years ago

@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 😕

themoonrat commented 5 years ago

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

Sieabah commented 5 years ago

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

Tectract commented 5 years ago

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.

Sieabah commented 5 years ago

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

Tectract commented 5 years ago

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

themoonrat commented 5 years ago

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.

Tectract commented 5 years ago

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.

Tectract commented 5 years ago

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

Tectract commented 5 years ago

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.

themoonrat commented 5 years ago

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.

Tectract commented 5 years ago

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.

Sieabah commented 5 years ago

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

Tectract commented 5 years ago

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.

Sieabah commented 5 years ago

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.

Tectract commented 5 years ago

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.

st-h commented 5 years ago

@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

MaxYari commented 5 years ago

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

Tectract commented 5 years ago

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

Tectract commented 5 years ago

Unsubscribed. You guys are bad software devs.

dangrima90 commented 5 years ago

@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 😄

TheBigK commented 5 years ago

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.

Sieabah commented 5 years ago

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

Tectract commented 5 years ago

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/

mike7a commented 5 years ago

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

Tectract commented 5 years ago

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!

jjavierdguezas commented 5 years ago

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

mike7a commented 5 years ago

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?

Tectract commented 5 years ago

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.

Sieabah commented 5 years ago

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.

Tectract commented 5 years ago

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.

Tectract commented 5 years ago

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.

Sieabah commented 5 years ago

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.

Tectract commented 5 years ago

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.

RichardGale commented 5 years ago

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

st-h commented 5 years ago

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

Tectract commented 5 years ago

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.