This is a follow-up question to this post...
Auto load new song into HTML 5 audio player when track ends using php/jquery
Thanks to contributions by @Roko C. Buljan I was able to use the following script to load a new track into the div#player. When track ends, I simulated a click using the ajax function loadurl which then loads a new track into div#player. This plays alright and it's suppose to load a new track when it ends and on and on, but it doesn't work.
<script type="text/javascript">
const audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
</script>
I think the addEventListener isn't able to recognize the player.php file that's being loaded via ajax.
CodePudding user response:
Looking at the code you were using, I can see many errors:
- the
<source>
tag should self close; - the
<source>
tag should be a child of<audio>
tag - tha
<audio>
tag must not have theloop
attribute, or theended
event is never called; you have to remove this attribute even from the player.php script.
I think you have already removed the loop
attribute from the actual code, otherwise it shall not work even on the first time.
Now, the problem occurrs because of this line:
document.getElementById(targetID).innerHTML = XMLHttpRequestObject.responseText;
because you are deleting the current audio object and replacing it with a new one.
When the track ends it raise the ended
event on the new audio object, which has no event handler attached. The event handler you defined earlier wouldn't be called anymore.
The proper way to do things is to not replace the audio object, but simply replace its src
attribute with the new track name.
Edit
So you could change your player.php to return the file name and other data without the html tags, for example in json format:
$track = array('file'=>$file, 'image'=>$image);
echo json_encode($track);
and replace the above line with:
var track = JSON.parse(XMLHttpRequestObject.responseText);
audio.src = track.file;
document.querySelector('#image').src = track.image;
document.querySelector('#download').href = track.file;
where image
and download
are the IDs of the <img/>
and <a>download</a>
elements.
Another options is to rebind the ended
event each time you replace the html, but I strongly discourage this approach. Anyway, if you choose to follow this path, you must do it this way:
function loadurl(dest, targetID) {
...
document.getElementById(targetID).innerHTML = XMLHttpRequestObject.responseText;
var audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
...
}
var audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
Please note that the audio
symbol must be variable, not constant, otherwise you can't replace its value with the new audio element.