I am getting this error on Android and Iphone. I am calling play based on a button click, but still get this error thrown. Any suggestions?
@goldfire I've been having this problem with various Android browsers and iOS.
The issue is that mobile devices require a gesture to be the origin for calling the play() method on a HTMLMediaElement. Howler currently wraps the triggering of play() in an anonymous function, which essentially "strips" a gesture induced JS event from its origin.
This commit introduces wrapping play() in an anonymous function: https://github.com/goldfire/howler.js/commit/18a91c5f
At one point in time, Firefox (probably version 13) had an issue solved by wrapping the node.play() in a zero-second timeout. Now, it's preventing a wide array of Android browsers and iOS of using Howler with HTML5 Audio because of this restriction in the mobile browsers.
I've tested and confirmed that removing the setTimeout() (https://github.com/goldfire/howler.js/blob/master/src/howler.core.js#L739) solves the problem on a number of phones from LG, Huawei, Nexus, HTC, and Samsung (and various iOS devices).
Can we take it out?
I will be forced to patch howler with this fix for my own use until it's resolved.
I was using this library in an Angular 2 project. I wrapped the functions such as play pause in an Angular service.
So a button click event would go to the Angular service and the service would then call the howler object play function.
When I removed this wrapper and directly called play from howler's object, it fixed the problem on Android.
Ex:
I change to this:
<button (click)="playService.howlerPlayer.play()">Play</button>
playService.howlerPlayer is the howler object.
Instead of:
<button (click)="playService.play()">Play</button>
@swaheed2 Will this work when you enforce html5 mode? (e.g. set html5: true when initializing a Howl).
Howler seems to take different paths depending on where, when and how you're using it. I'm wanting HTML5 to be enforced.
@marcusstenbeck yes I also enforced html5 mode
Note: I've only tested it on Android Nexus 6 Chrome browser and it works
I'll see if I can make a jsbin tomorrow with the error.
Here's a jsbin that will not work on my Android devices.
I am getting this error on Chrome Android. other mobile browsers not tested. It seems to match this Chrome issue : https://bugs.chromium.org/p/chromium/issues/detail?id=178297
I can understand if this behavior is Chrome's fault, but Howler should provide a way to catch/listen/detect this error in some way, so that we can know that the play() call didn't work and adjust the UI accordingly.
I've poked around with try/catch and various event handlers, it doesn't seem detectable currently.
@implicitdef Try removing the setTimeout (not the code within). E.g. make the below change to your howler.js file, and test again. Does it work?
Change this
setTimeout(function() {
node.play();
// Setup the new end timer.
if (timeout !== Infinity) {
self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout);
}
if (!internal) {
self._emit('play', sound._id);
}
}, 0);
into this
// setTimeout(function() {
node.play();
// Setup the new end timer.
if (timeout !== Infinity) {
self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout);
}
if (!internal) {
self._emit('play', sound._id);
}
// }, 0);
@marcusstenbeck No, in my case it doesn't change everything.
Note though that, unlike you I think, I _am_ trying to play something without a user gesture (I want to autoplay a sound when the user arrives on a page).
My problem is not that this is restricted, it's more that the restriction is undetectable, forcing me to tweak my code based on the user agent. Maybe I should file a separate issue ?
@implicitdef - It is in the howler documentation that a touch is required to play sounds on certain devices - https://github.com/goldfire/howler.js#mobile-playback
I'm not sure what more Howler can do? Throw a console log error each time a sound is attempted to be played but the browser still has webaudio locked?
They could wrap their play() call in a try catch, and fire a 'playerror' event, for instance, similar to the existing 'loaderror' event.
Oh, yeah. Autoplaying is a different issue than what you have @implicitdef. I'm strictly interested in playing triggered by a user gesture.
Filed a separate issue. Sorry for the noise.
I've created a pull request with the fix that solves it in my testing conditions. #694
Does anyone still having this issue? I've just upgraded to the latest version (2.0.5) but still having the same problem.
@volkan-umg yup, i got the same on canary 65
Most helpful comment
@goldfire I've been having this problem with various Android browsers and iOS.
The issue is that mobile devices require a gesture to be the origin for calling the
play()method on a HTMLMediaElement. Howler currently wraps the triggering ofplay()in an anonymous function, which essentially "strips" a gesture induced JS event from its origin.This commit introduces wrapping
play()in an anonymous function: https://github.com/goldfire/howler.js/commit/18a91c5fAt one point in time, Firefox (probably version 13) had an issue solved by wrapping the
node.play()in a zero-second timeout. Now, it's preventing a wide array of Android browsers and iOS of using Howler with HTML5 Audio because of this restriction in the mobile browsers.I've tested and confirmed that removing the
setTimeout()(https://github.com/goldfire/howler.js/blob/master/src/howler.core.js#L739) solves the problem on a number of phones from LG, Huawei, Nexus, HTC, and Samsung (and various iOS devices).Can we take it out?
I will be forced to patch howler with this fix for my own use until it's resolved.