Jason
Jason

Reputation: 462

HTML5 audio DOM Exception 11 error with currentTime=0

EDIT: I posted this in the Wordpress side but some admin thinks it goes here because they say it's a client side problem but I don't think it is because he script works as is (in a non-wordpress site) but only throws the DOM Exception 11 error when the script is used on a Wordpress site and only on certain browsers. The very same script works under Wordpress but only on Chrome.


I have taken a script that plays an audio clip when an anchor link is hovered and turned it into a Wordpress plugin.

It works fine but only on Chrome (Mac). On Firefox or Safari (current versions) the script is throwing a DOM error.

Here is the error:

INVALID_STATE_ERR: DOM Exception 11: An attempt was made to use an object that is not, or is no longer, usable.

The line that is producing the error is: html5audio.currentTime=0

The below script works fine on the browsers I am having a problem with in a non-Wordpress site. http://www.javascriptkit.com/script/script2/soundlink.shtml#current

I have tried researching the problem and using some fixes but I can not get to work.

var html5_audiotypes={ 
    "mp3": "audio/mpeg",
    "mp4": "audio/mp4",
    "ogg": "audio/ogg",
    "wav": "audio/wav"
}

function audio(sound){
    var html5audio=document.createElement('audio')
    if (html5audio.canPlayType){ //check support for HTML5 audio
        for (var i=0; i<arguments.length; i++){
            var sourceel=document.createElement('source')
            sourceel.setAttribute('src', arguments[i])
            if (arguments[i].match(/\.(\w+)$/i))
                sourceel.setAttribute('type', html5_audiotypes[RegExp.$1])
            html5audio.appendChild(sourceel)
        }
        html5audio.load()
        html5audio.playclip=function(){
            html5audio.pause()
            html5audio.currentTime=0
            html5audio.play()
        }
        return html5audio
    }
}

Upvotes: 6

Views: 3514

Answers (3)

Randy
Randy

Reputation: 311

I'm sure this way too late for the OP, but I do my best to support old browsers and this may help someone else. On the stock browser of a very old Android device (android v 4.0.4) this was not really working, because the audio Object's currentTime returned non zero when it shouldn't have, and zero-ing it still caused the exception. Its a browser/DOM bug for sure, and very hard to trace EXACTLY what is happening. The only solution seems to be to put that property settingng into a try/catch block.

So the reason I had to try this is because immediately after making the audio load() and play(), the music wasn't playing, because the song pointer (on the browser provided player ) showed the song point to be at the end. So what harm, I thought, to just set the audio currentTime to 0? Well it worked sort of, but then I realized nothing beyond that point in the code block was working, because this exception was being thrown!

So following the advice in this post, I only set the currentTime property to 0 if it was NOT zero. But in my case the currentTime was pointing to the end of the song even when first loaded, so of course it was NOT zero. But setting it still caused the exception to be thrown.

So I next tried putting the currentTime setting into a try/catch block.

...
 // assume a is the audio element, and the audio source has already been supplied...

    a.load();
    try {if (!a.currentTime) a.currentTime=0;}  
    catch(err) {alert(err);}    
    a.play(); 

Interestingly despite the exception, it DID seem to move the song pointer to the start position! Eureka? Well no... as soon as I removed the alert(), the problem was back.

So this made me suspect that the audio load() method was NOT a 'blocking' method, and was returning before the audio was really ready to have its song pointer altered. This still doesn't explain WHY the loaded song would not start at zero, but what I did was added a forced delay between the load() and the subsequent setting of CurrenTime to 0 and playing.

So, I already had this kludgy "sleep()" simulation from another stack exchange post... (JavaScript sleep/wait before continuing)

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

Of course that is not a javascript timer! It will actually halt execution until it returns. so using that, I altered my code to play a song like so... again, remember the 'a' is the actual element...

a.load();
sleep(1000);
try {if (a.currentTime != 0) a.currentTime=0;}  // DOM bug
catch(err) {;}  // old android sometimes starts at end :-(
a.play(); 

This is ugly and awful, but it did work, and it did work reliably! Further, if I put an alert(err); back into the catch block, it never displayed (meaning the exception was no longer happening).

So the next step was to keep shortening the sleep() to see how much time was really needed for reliability. I shortened it to 100mS, then 10mS with complete success (meaning song pointer did go to 0 on the problem Android browser). But at less than 2mS the problem returned.

So obviously there is a timing problem in this early implementation of HTML5 audio. Forcing a simulated sleep() is certainly ugly, but it works, and a small delay won't matter in my situation. I'm leaving my forced "sleep()" at 100mS, a time that should hopefully be good for any length audio clip.

Upvotes: 0

Thailandian
Thailandian

Reputation: 585

I guess it's too late for the original poster, but in case anyone else comes looking...

I had a similar problem - in my case the code worked on Chrome, but nothing else as far as I could tell, but it's not a Wordpress site. After some experimenting, I realised that the error only happened if currentTime was already 0. So the solution was quite simple:

html5audio.pause(); 
if (html5audio.currentTime != 0) {
   html5audio.currentTime=0;
}  
html5audio.play();

I hope that helps someone.

Upvotes: 7

etual
etual

Reputation: 561

I've tested on Win7/Chrome,IE,FF - latest versions. They all work. This could be a browser compatibility issue. Unfortunately, the HTML5 Audio API is still not very mature. Try this:

audio.pause();
audio.src = audio.src;

If it doesn't help, probably, send a bug report to HTML5 issue tracker if they don't have the one already.

Related post: html5 audio currentTime doesn't work

Upvotes: 0

Related Questions