Cc.audioEngine.playMusic won't allow playing the same file directly after the other

I need accurate timing for a background music, so I want to set precise time every time a music file is repeated. Meaning I can’t use repeat = true.

Problem is, that this doesn’t work with cocos2d-html (3.8) with the same file. I have to fill in a 40ms pause before I repeat. 20ms is never enough. 35ms sometimes. Even worse with Android.

My code in the HelloWorld example:

var preciseStartTime = null;
var time = 18504; music = res.music1_mp3;
//var time =  3456; music = res.music2_mp3;
//var time = 85140; music = res.music3_mp3;

var offset = 20;  // offset = 20 not working, 40 does
(function play() {
    preciseStartTime = new Date().getTime();

    cc.audioEngine.playMusic(music, false);
    setTimeout(play, time + offset);
    self.sprite.runAction(cc.rotateBy((time+offset)/1000,360));
})();

It plays the music every second time. If I change to 40ms, it plays it every time in html5, but not in Android.

Here is a link with a running example: http://c2064.org/musictest

What is the issue about playing the same music file again. If I change the file name, no problem.

Hi,

  1. why not trying to add the play music action inside the runAction using couple of cc.spawn(…) + cc.sequence? instead of using setTimeout ?

so things should look like var actionToRun = cc.sequence( cc.spawn( < startPlayingMusic >, < startRotation >), < stopMusic >);

by doing that you will say that the music start in // with your animation and then stop when your animation is done.

If this is not what you want to acheive please ignore my response ;).

  1. Regarding the issue of audioEngine not allowing you to play two time the same file you should check the file CCAudio.js and you will normaly see that it contains a method called rewindMusic that will replay your music from the begining (if it is what you want to acheive) or use couple stopMusic(false) and resumeMusic() (give it a try not sure if it is ok)

Please note that i only look the code from 3.7.1 and thus all have maybe changed since…

Hope this help,

@tingyen

  1. This was just for demonstration. I use it in a mor ecomplex environment where I need something like setTimeout. I’m not completly happy with it, because the timing is not reliable, but it works.

Anyway, thx for the idea with runAction.

  1. I read the CCAudio.js and also tried rewindMusic(). With the same result. Also stopMusic() doesn’t do what I would expect. I changed the example in the web, now its using rewindMusic():

c2064.org/musictest

Maybe I file a bug on github.com.

Michael

Hi,

I’ve checked your code and I found something weird:

if( !id ) id = cc.audioEngine.playMusic(music, false);
else cc.audioEngine.rewindMusic(id);

For me the else statement is never called since there is no return statement in the playMusic method. Irrespective of the playEffect method, the playMusic method doesn’t require you to store an extra variable since you will only play one music at a time (guys, correct me if I’m wrong). In this sense you can call cc.audioEngine.rewindMusic without adding any parameters.

Still, this is strange that you can’t call two times the playMusic method with the same url since nothing in the playMusic code stops you from doing that.

I’ve debugged your code and when going step by step with chrome debugger it works (maybe due to the fact that we are waiting enough time before calling the playMusic method ???)

Regards,

Tingyen

Oh yes, I mixed up playMusic with playEffect. I corrected that. But still rewindMusic doesn’t play every other time. You are probably right, that if you step through it, then it gets its pause. Currently it waits 20ms after audio file end. If you change this to 40ms then it plays every time.

if( !started ) {
started = true;
cc.audioEngine.playMusic(music, false);
} else {
cc.audioEngine.rewindMusic();
}

I guess it’s a bug.