howler.js icon indicating copy to clipboard operation
howler.js copied to clipboard

onplayerror not firing (2.1.2)

Open indexofrefraction opened this issue 6 years ago • 5 comments

using the code from the documentation i can not get onplayerror to fire

with example below / on safari and chrome desktop: audio play is denied, but onplayerror does not fire the sound then plays with the first touch/click (onplay is fired)

var sound = new Howl({
	src: ['blank.webm', 'blank.mp3'],
	onplay: function() {
		console.log('audio playing!');
	},
	onplayerror: function() {
		console.log('audio play denied!');
		sound.once('unlock', function() {
			console.log('audio play unlocked!');
		});
	}
});
sound.play();

ps. as playing limitations affect all mayor browsers now, maybe the error messages could be updated (line 898 and 917)

indexofrefraction avatar May 04 '19 21:05 indexofrefraction

this code is a bit clearer, and i also noticed :

for safari / chrome desktop and safari ios : this code is enough to unlock audioplay by a click anywhere in the document

for chrome android: this does not work, i could not get a consistent behaviour on a huawei p20, but i think the playback must be invoked inside a click/touch event !

an audio file is actually not needed, the Howl needs a format in this case, tough.

as mentioned above, at least on the destop, onplayerror does not get executed

var sound = new Howl({
	src: [''], format: ['mp3'], 
	autoplay: true,
	onplay: function() {
		console.log('audio playing!');
	},
	onplayerror: function() {
		console.log('audio play denied!');
	},
	onunlock: function() {
		console.log('audio play unlocked!');
	},
});

indexofrefraction avatar May 05 '19 11:05 indexofrefraction

Is anyone addressing this? I can't get onplayerror to fire when Chrome blocks the Audio Context.

jevinsidhu avatar Sep 25 '19 00:09 jevinsidhu

There is currently no way to detect that the audio is locked. There are some proposals in the works, but the progress seems to be moving slowly. I submitted a bug to Chromium that got marked as wontfix when the promise from a play just hangs if the audio is blocked, which seemed like it would be the logical place to catch in that scenario, rather than just doing nothing.

goldfire avatar Sep 25 '19 14:09 goldfire

Thanks for the detailed answer - appreciate your work. @goldfire

jevinsidhu avatar Sep 25 '19 14:09 jevinsidhu

It still not work. But with html5 audio, we have 2 ways: Method 1: On Suspend Event: audio.addEventListener('suspend', function(){})

Method 2: Catch play()

async audioPlay(audio) {
  var canPlay = true
  await new Promise(async (resolve) => {
    audio.onended = resolve
      audio.play().catch(error => {
        canPlay = false
        resolve()
      })
  });
  return canPlay
}

vvvhung avatar May 24 '24 13:05 vvvhung