Both latest Chrome and Firefox do pass a reason to the rejected promise, you could thus check it.
new Audio("bafile.mp3").play().catch(console.log)
But note that they didn’t always did.
Also note that the NotAllowedError will always win: even if the resource can’t be loaded, it is the reason that will get output.
So an other solution, able to distinguish between both and that will work even in prior versions that didn’t have this rejection message, would be to wait for whatever is the first to fire between the loadedmetadata
and error
events.
If one of these fires, you know it failed because of a NotAllowedError or because of a NotSupportedError respectively.
function test( url ) {
const aud = new Audio( url );
const event_prom = Promise.race( [
promisifyEvent( aud, "error" ),
promisifyEvent( aud, "loadedmetadata" )
] );
aud.play()
.then( () => {
log.textContent += "\nERROR: " + url + " was authorized to play";
} )
.catch( async (reason) => {
const evt = await event_prom;
if( evt.type === "error" ) {
log.textContent += "\n" + url + ": network error";
}
else {
log.textContent += "\n" + url + ": not authorized";
}
});
}
test( "https://upload.wikimedia.org/wikipedia/en/transcoded/d/dc/Strawberry_Fields_Forever_%28Beatles_song_-_sample%29.ogg/Strawberry_Fields_Forever_%28Beatles_song_-_sample%29.ogg.mp3" );
test( "badfile.mp3" );
function promisifyEvent( target, event_name ) {
return new Promise( (resolve) =>
target.addEventListener( event_name, resolve, { once: true } )
);
}
<pre id="log"></pre>
As a jsfiddle since it might be easier to control the authorizations.
CLICK HERE to find out more related problems solutions.