Reputation: 3531
I'm using the <audio>
tag to play audio files across a number of browsers.
var audioTag = document.createElement("audio"),
sourceTag = document.createElement("source"),
sorryTag = document.createElement("div");
sorryTag.innerHTML = "This filetype not supported";
audioTag.onerror = function() {
//some error handling code
}
sourceTag.onerror = function() {
/some error handling code
}
sourceTag.src = "myfile.mp3";
audioTag.appendChild(sourceTag);
audioTag.appendChild(sorryTag);
//add audioTag to DOM
This leads to
<audio>
<source src='myfile.mp3' />
<div>This filetype not supported</div>
</audio>
Firefox can't play MP3 files, and I'm OK with that. Mozilla also promises that an error
event will be dispatched if the <audio>
or <video>
tag can't play the media. And also it will go through the tags nested inside the media tag one by one (<source>
or others, the last presumably being an error message) till it finds one it can work with. None of these seem to work for me; the error event is never fired on the elements nor is the error message displayed. What am I doing wrong?
Upvotes: 1
Views: 897
Reputation: 3531
The workaround I found was:
var audioTag = document.createElement("audio"),
sourceTag = document.createElement("source");
//Add error event listeners for browsers other than FF
audioTag.onerror = function() {
console.log("file can't be played. error from audio tag");
}
sourceTag.onerror = function() {
console.log("file can't be played. error from source tag");
}
//The only way to tell that file failed to play on FF
//Timeout is because audioTag.networkState === audioTag.NETWORK_NO_SOURCE
//on IE till it starts downloading the file
setTimeout(function() {
if(audioTag.networkState === audioTag.NETWORK_NO_SOURCE) {
console.log("this hack is only for <audio> on FF.");
console.log("Not for <video> and on no other browsers");
}
}, 3000);
sourceTag.src = "<file_url>";
audioTag.appendChild(sourceTag);
Basically, create the media and source tags, add error handlers, then append the source tag to the media tag and if the error event fires, then you know the file is unplayable.
On FF, the error event doesn't fire and you have to rely on the networkState
flag of the <audio>
element, comparing it to NETWORK_NO_SOURCE
. You can't inspect it immediately after setting the src
attribute of the <source>
element because on IE networkState === NETWORK_NO_SOURCE
till the browser actually starts downloading the file. For this reason, set a timeout of about 3 seconds (it's not an exact science) before checking the flag value and there's a good chance that you will have given IE enough time to determine if it's capable of playing the file.
UPDATE
Wrote a test case for this: http://jogjayr.github.com/FF-Audio-Test-Case/ but the error event fires OK there. Guess I was wrong; that or it was broken on FF14 (which I was using at the time), because the error event fires OK in my application too. Thanks @BorisZbarsky
Upvotes: 1