Home > Enterprise >  Wait till sound is finished and then play another sound
Wait till sound is finished and then play another sound

Time:02-28

I'm working on a morse code audio player. I play each sound with this function:

function playSound(n: number): void{
if(n === 0){
    let sound = new Audio("../audio/short.mp3");
    sound.play();
}
else if(n === 1){
    let sound = new Audio("../audio/long.mp3");
    sound.play();
}
else{
    let sound = new Audio("../audio/break.mp3");
    sound.play();
}

I call it here:

for (let j = 0; j < nummers.length; j  ){
       playSound(nummers[j]);
    }

But when I call this function multiple times the sound are playing in parallel. Who can I play one after another?

CodePudding user response:

Have you looked at setTimeout? This can give you the ability to wait before calling another function. At which point, the next function could play the next sound.

For example:

function playSound1() {
    let sound = new Audio("../audio/short.mp3");
    sound.play();

    setTimeout(playSound2, 1000); /* This is in milliseconds (so 1 second) -- you should change this to correspond with how long short.mp3 is */
}

function playSound2() {
    let sound = new Audio("../audio/long.mp3");
    sound.play();

    setTimeout(playSound3, 2000);
}

function playSound3() {
    let sound = new Audio("../audio/break.mp3");
    sound.play();
}

playSound1();

You could then add many more if you wanted, but this does imply that you know the precise length, which you should be able to access with sound.duration. So instead of setTimeout(playeSound2, 1000);, you could say setTimeout(playSound2, sound.duration * 1000);

You could also make this into a single function like you have by just calling to the function on different intervals (using setTimeout again). To give it your parameter n, you just add a third value into the setTimeout function:

playSound(1);
setTimeout(playSound, 1000, 2); /* will play the second sound after 1 second */
setTimeout(playSound, 2000, 3); /* plays the third sound 2 seconds after the second sound is played */

This is pretty much the same concept but uses your function instead.

OP's Question Edit: "Is there a way to do this without knowing how many sounds I have?"

Yes! This would be a good time to use an array of sounds where you preload all the audios and then can play one at a time using the same concept but with an array instead.

In my following example I use a sum variable prevSoundDurationSum that counts how long the duration for each song is, so when you get to the next song you know how long you should wait before playing it.

Example:

playSound(sound) {
    sound.play();
}

let allSounds = [new Audio("../audio/short.mp3"), new Audio("../audio/long.mp3"), new Audio("../audio/break.mp3")];

let prevSoundDurationSum = 0;

for (let playsound = 0; playsound < allSounds.length; playsound  ) {
    setTimeout(playSound, prevSoundDurationSum, allSounds[playsound]);

    /* Add to the sum */
    prevSoundDurationSum  = allSounds[playsound].duration * 1000;
}

Note an error from the previous version: .duration functionality returns in seconds, so multiply by 1000 to get the milliseconds for the setTimeout() function.

  • Related