Jump to content

Music Loading: "canplaythrough" Returns Immediately?


Recommended Posts

Music Loading: "canplaythrough" Returns Immediately?




My team and I are working on a new HTML5/JS 2D video game.

We are currently updating our HTML5 2D video game engine.


We are having problems with loading music.

Here is our source code to load music:

SoundType = "null";var audioTest = document.createElement('audio');if ( audioTest.canPlayType('audio/mpeg;') )  SoundType = "mp3";else  if ( audioTest.canPlayType('audio/ogg;') )  SoundType = "ogg";
for (var index = 0; index < NumberOfMusics; index++){    MusicArray[index] = new Audio;    MusicArray[index].src = ("./data/audio/Track-0"+(index+1)+"-BGM." + SoundType);    MusicArray[index].volume = MusicVolume;    MusicArray[index].preload = "auto";    MusicArray[index].addEventListener( "canplaythrough", MusicLoaded(index) );}

The problem is that the music in the game sometimes does not play because it was not fully loaded?

It seems like "canplaythrough" returns immediately when loading the music??

Is there some solution to the above music loading issue?

Thank you...



Link to comment
Share on other sites

You indeed call your function (you use the () operator!) This would be needed when your function returns an callback!

MusicArray[index].addEventListener( "canplaythrough", MusicLoaded );

This is the right way, but you still need to pass index in any way to the function

MusicArray[index].addEventListener( "canplaythrough", MusicLoaded.bind(window, index) } );

Well, I am quite a fan of bind, because its the easiest solution :D You can also use closures, however, keep in mind the following is wrong:

MusicArray[index].addEventListener( "canplaythrough", function(){ MusicLoaded(index) } );

This is because variables in javascript are blockscoped, so when the callback gets invoked index is equal to the NumberOfMusics, because index gets still increased

Link to comment
Share on other sites

  • 1 month later...



I also wanted to say (because I had the same problem and took me ages to figure it out):


if ( audioTest.canPlayType('audio/mpeg;') )


is bad practice, because canPlayType sometimes returns "maybe" (for example mp4 on internet explorer) which evaluates to "true". So perhaps  test that it returns the string that you want.

Link to comment
Share on other sites

  • 7 months later...

Thank's a lot for this, HTML5 audio's been a pain but this usage of event listener has sorted my pre-loader ;) 


I just have a question, should we be removing the canplaythrough event from memory once it triggers with removeEventListener?


if so and using JeZxLee's code as an example, would "MusicArray[index].removeEventListener( "canplaythrough", MusicLoaded );" do the trick?





Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...