Home > Blockchain >  JavaScript: Play each audio file in a playlist multiple times consecutively, with a pause between pl
JavaScript: Play each audio file in a playlist multiple times consecutively, with a pause between pl

Time:09-21

I have an audio playlist for language learning. Each file of playlist is supposed to be played once or more times consecutively, and so the whole playlist, with a pause between plays. Right now I can play in this mode only a single file, not the whole playlist.

The HTML part:

<div id="audio-files">
    <audio preload="auto" >
        <source src="https://example.com/audiofile0001.mp3" type="audio/mpeg">
    </audio>
    ....
    <audio preload="auto" >
        <source src="https://example.com/audiofile1001.mp3" type="audio/mpeg">
    </audio>
</div>

<button onclick="playAudio()" type="button">Play Audio</button>
<button onclick="pauseAudio()" type="button">Pause Audio</button>

The JavaScript part (from here) that works if playing only one file, not the whole list. The only problem here is the pauseAudio() function, that doesn't stop all playbacks.

const div = document.querySelectorAll( 'div#audio-files .myAudio' );
var numberOfTimes = 2;
var delay = 3000;

let audioFile = div[0];

function playAudio() { playSound( audioFile, numberOfTimes, delay ); }
function pauseAudio() { audioFile.pause(); } // works not good

function playSound( audioFile, numberOfTimes = 1, delay = 0, firstTime = true ) {
    if( firstTime ) { audioFile.play(); }

    setTimeout( () => {
        if( ! firstTime ) { audioFile.play(); }

        if( numberOfTimes > 0 ) {
            numberOfTimes--;
            playSound( audioFile, numberOfTimes, delay, firstTime = false );
        }

    }, delay );
}

I suppose that the playAudio() function must changed to get the desired result (playing the entire playlist), but I can't figure out how exactly to do it. This is what I tried:

function playAudio() {

    for( let i = 0; i < div.length; i   ) {

        let audioFile = div[i];

        if( i === 0 ) { playSound( audioFile, numberOfTimes, delay ); }

        let timeInterval = audioFile.duration * 1000 * 2   delay * 2;

        setTimeout( () => {
            if( i > 0 ) { playSound( audioFile, numberOfTimes, delay ); }
        }, timeInterval );
    }
}

Any ideas?

CodePudding user response:

You need to know the moment when the current video is finished playing. You can do that by listening to the ended event on the currently playing video.

When the video ends, check if you're at the end of the playlist. If not, start the next video. If yes, then reset the playlist and do nothing.

let currentAudio = null;
let currentAudioIndex = 0;
const pause = 2000;
const audios = document.querySelectorAll('#audio-files audio');

async function play() {
  currentAudio = audios[currentAudioIndex];
  
  try {
    await currentAudio.play();
  } catch (error) {
    console.error(error);
  }

  currentAudio.addEventListener('ended', () => {
    // Show that this video has been fully played.
    currentAudio.setAttribute('data-finished', ''); 

    if (currentAudioIndex === audios.length - 1) {
      currentAudio = null;
      currentAudioIndex = 0;
      return;
    }

    currentAudioIndex  ;

    setTimeout(play, pause);
  }, { once: true });
}

function pause() {
  if (currentAudio === null) {
    return;
  }

  currentAudio.pause();
}

CodePudding user response:

const audioElem = document.querySelector('.myAudio');
const desiredPlayCount = 2;
const desiredDelayMs = 2000;

function playAudio() {
  audioElem.play();
}

function pauseAudio() {
  audioElem.pause();
}

let playCount = 0;
audioElem.onended = function() {
  playCount  ;
  if (playCount < desiredPlayCount) {
    setTimeout(() => {
      audioElem.play();
    }, desiredDelayMs);
  } else {
    playCount = 0;
  }
};
<div id="audio-files">
  <audio preload="auto" >
    <source src="https://www.w3schools.com/html/horse.mp3" type="audio/mpeg">
  </audio>
</div>

<button onclick="playAudio()" type="button">Play Audio</button>
<button onclick="pauseAudio()" type="button">Pause Audio</button>

  • Related