-1

Here is the link to code pen to my project https://codepen.io/RajTheSHow/pen/vZZPqZ when you press the wrong button it is supposed to play the sequence(with audio and button press in order).however what actually happens is when you press the wrong button it plays all the audio and changes the color at once and doesn't execute what is in the sleep function.you can see the problem in the pen.

the function that runs the sequence when you press the wrong button is below cal is where the order is stored of the sequence.

   //plays the sequence
function callBut(){
  onr=0;
for(i=0;i<cal.length;i++){
   // or eval ("s"+cal[i])
   window["s"+cal[i]].play();

   // set the but# to Clicked Color Ccol# then after 1 sec go back to normal color
     $("[but="+cal[i]+"]").css("background",window["Ccol"+cal[i]])
 sleep(500).then(() => {
// set the button# to Standard color Scol#
    $("[but="+cal[i]+"]").css("background",window["Scol"+cal[i]])

});


}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • Questions seeking debugging help ("**why isn't this code working?**") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it **in the question itself**. Questions without a **clear problem statement** are not useful to other readers. See: [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Heretic Monkey Jun 22 '17 at 18:35
  • This question might help you out https://stackoverflow.com/questions/21471116/html5-video-waiting-for-video-end-waiting-for-video-ready – Hopeless Jun 22 '17 at 18:43

3 Answers3

2

What'd you expect? The loop does not wait for the audio to finish. It's better to use recursion to play the next song.

let arr = cal.map(element => window[`s${element}`]); // asuming 'cal' is something significant

let index = 0;
playAudio(arr[index]);

function playAudio(audio) {
   if (!audio || !(audio instanceof Audio)) return;

   audio.addEventListener('ended', function() {
      index++;
      playAudio(arr[index]);
   })
   audio.play();
}
Shane
  • 3,049
  • 1
  • 17
  • 18
0

This is the correct and expected behaviour. What you want to achieve requires to wait for the end event and only then invoke play on the next clip. This can be achieved by properly handling the audio events you can look up online and "chaining" them playing one at a time, much like this:

var nextSound;

function playNext()
{
  var audio;

  if (nextSound >= cal.length)
  {
    return;
  }

  audio = $(window["s"+cal[nextSound++]]);
  audio.on("ended", playNext);
  audio[0].play();
}

nextSound = 0;
playNext();
pid
  • 11,472
  • 6
  • 34
  • 63
0

$(function() {
    index = 0;
    var audios = $(".any_class audio");
    $('#jg_start_playing').on('click', function() {
        $('#jg_stop_playing').click(); //In case an audio is started manually
        var audio = audios[index];
        audio.play();
        index++
        audio.onended = function() {
            audio.currentTime = 0;
            if (index < audios.length) {
                $('#jg_start_playing').click();
            }
        }
    })
    $('#jg_stop_playing').on('click', function() {
        for(x=0; x < audios.length; x++) {
            audios[x].pause();
            audios[x].currentTime = 0;
        }
    })
})