2
votes

I have a webapp that loads and plays audio tracks when you click on a link using ajax/jquery. Everything works fine, but when the track ends, the track is set to loop and this can go on forever. I would like the player to autoload a random track from the database and play when one track ends. The audio is setup as such.

<div id="player"><audio title="Audio title" controls loop autoplay controlsList="nodownload" preload="auto" id="myAudio" /><source src="audio.mp3" type="audio/mp3" id="audioID"></div>

Am using jquery to load a new track into the #player div when you click on it. eg;

<a href="javascript:;" onClick="loadurl('player.php?play=audioID','player')">Track One</a>

<script type="text/javascript">

<!-- ajaxified -->
function loadurl(dest, targetID) {
    
var XMLHttpRequestObject = false; 
    if (window.XMLHttpRequest) { 
            XMLHttpRequestObject = new XMLHttpRequest(); 
        } else if (window.ActiveXObject) { 
            XMLHttpRequestObject = new 
            ActiveXObject("Microsoft.XMLHttp"); 
    } 

if(XMLHttpRequestObject) { 
            XMLHttpRequestObject.open("GET", dest); 
            XMLHttpRequestObject.onreadystatechange = function() { 
            
        if (XMLHttpRequestObject.readyState == 4 && 
            XMLHttpRequestObject.status == 200) { 
            document.getElementById(targetID).innerHTML = 
            XMLHttpRequestObject.responseText; 
            delete XMLHttpRequestObject; 
            XMLHttpRequestObject = null; 
            } 
        } 
        XMLHttpRequestObject.send(null); 
    } 
} 

</script>

In my player.php file I have;

<?php  
.... fetch track from db where id = $_GET['play']; ......
?>

<audio title="Audio Title" controls loop autoplay controlsList="nodownload" preload="auto" id="myAudio" /> 
<source src="audio2.mp3" type="audio/mp3" id="audioID">

I've tried several suggestions from here and online like adding;

<script type="text/javascript">

const audio = document.querySelector('myAudio');

audio.onended = (event) => {
  console.log('Video stopped either because 1) it was over, ' +
      'or 2) no further data is available.');
};

</script>

and this...

<script type="text/javascript">
const audio = document.querySelector('myAudio');

audio.addEventListener('ended', (event) => {
  console.log('Video stopped either because 1) it was over, ' +
      'or 2) no further data is available.');
});

</script>

and this...

<script type="text/javascript">
myAudio.addEventListener("ended", function(){
     myAudio.currentTime = 0;
     console.log("ended");
     alert("ended");
});

</script>

But none of them work. What am I doing wrong?

1
PS... STOP using on* inline JS handlers. JS (same as STYLE) should be all in their respective tags or files. Use addEventListener instead. Also text/javascript isn’t required in <script> tag as of HTML5. - Roko C. Buljan
Also, should be document.querySelector('#myAudio'); not document.querySelector('myAudio'); - Roko C. Buljan

1 Answers

0
votes

There's two possibilities:

1. If the client has not a complete list of tracks:

Create a route on your server that can respond with a random track and send it back via AJAX to the client as JSON like {"src": "bazzz.mp3", "name": "", "group": "", "year": "", "cover": ""}.

const audio = new Audio(); // or: document.querySelector('#myAudio');

const playRandomFile = () => {
  fetch("/api/getRandomSong.php").then(res => res.json).then(data => {
    audio.src = data.src;
    audio.play();
  });
};

audio.addEventListener("ended", playRandomFile); // ♫♪♫...♪♫♪♫♪...♫♪!

Hopefully you know how to write a PHP code that gets a random entry from a database songs table and return it as JSON.

2. If the client knows upfront all the tracks:

Use JS to switch to a random track on "ended" Event.

const songs = [
  {src: "xyz.mp3", name: "", group: "", year:"", cover: ""},
  {src: "foo.mp3", name: "", group: "", year:"", cover: ""},
  {src: "bar.mp3", name: "", group: "", year:"", cover: ""},
];

const audio = new Audio(); // or: document.querySelector('#myAudio');

const playRandomFile = () => {
  audio.src = songs[~~(Math.random() * songs.length)].src;
  audio.play();
};

audio.addEventListener("ended", playRandomFile); // ♫♪♫...♪♫♪♫♪...♫♪!

Tip-of-the-day: you can generate your HTML in JS right out of the songs array.

Full Example

with Wikimedia audio files and a HTML <audio> Element:

const songs = [
  {src: "http://upload.wikimedia.org/wikipedia/en/4/45/ACDC_-_Back_In_Black-sample.ogg", name: "", group: "", year:"", cover: ""},
  {src: "https://upload.wikimedia.org/wikipedia/en/3/39/Metallica_-_Enter_Sandman.ogg", name: "", group: "", year:"", cover: ""},
  {src: "https://upload.wikimedia.org/wikipedia/en/5/5e/U2_One.ogg", name: "", group: "", year:"", cover: ""},
];

const audio = document.querySelector('#myAudio');
const getRandomSong = () => songs[~~(Math.random() * songs.length)];

audio.addEventListener("ended", () => {
  audio.src = getRandomSong().src
  audio.play()
}); 

audio.src = getRandomSong().src // on DOM ready
<audio id="myAudio" controls></audio>