简体   繁体   中英

HTML5 audio not loading sometimes

I have a class AudioClass in javascript to play audio as below: (pseudo code)

var AudioClass = function() {
     this.audioElement;
     .
     .
     .
     this.load = function(audioSource) {
         this.audioElement = //create Audio, set source etc.
         this.audioElement.addEventListener("loadedmetadata", function(){
                //some code
         });
     }

     this.play = function(from, to) {
         if(isNaN(this.audioElement.duration)) {    return; }  //line 1
         this.audioElement.currentTime = from/1000;   //line 2   //from & to in milliseconds  
         setTimeout(function() {
               //pause audio.
         }, to-from);
     }
}

And I am using the Audio as below:

/* the below lines are executed on document load. (playing background music) */
var audioInstance = new AudioClass();
audioInstance.load(audioSrc);
audioInstance.play(20000);   //line 3  //20 seconds

/* the below line is used at other places whenever i need sound */
audioInstance.play(40000);   //40 seconds

When I am trying to play audio at "line 3", sometimes audio is not loaded by that time, so it is throwing INVALID_STATE_ERR. DOM EXCEPTION 11 at line 2 INVALID_STATE_ERR. DOM EXCEPTION 11 at line 2 . When I checked the audio duration, it was NaN . So I added "line 1" to check whether the duration isNaN() or not, so that it doesn't try to set currentTime until the audio is loaded.

The problem here is sometimes the duration of audio is always NaN. How to fix this?

You have to create a callback to play the audio when it loads. it works whenever you call audio.play in other places because the audio is loaded by then. Here is how i suggest you do it:

var Audio = function() {
     this.audioElement;
     .
     .
     .
     this.load = function(audioSource,callback) {
         this.audioElement = //create Audio, set source etc.
         this.audioElement.addEventListener("loadedmetadata", function(){
                //some code
                if(callback!=null)
                    callback();
         });
     }

     this.play = function(from, to) {
         if(isNaN(this.audioElement.duration)) {    return; }  //line 1
         this.audioElement.currentTime = from/1000;   //line 2   //from & to in milliseconds  
         setTimeout(function() {
               //pause audio.
         }, to-from);
     }
}

then use it like this:

var audio = new Audio();
audio.load(audioSrc,function()
{
audio.play(20000);  
});

an answer to a similar question shows how to preload all your audio (in the event you have others) before start using them: Proper onload for <audio>

Play the sound in a callback registered to the loadeddata or even better, canplaythrough event of the audio element. (See javascript audio onload and similar questions.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM