简体   繁体   English

播放第二首曲目后,Ajax HTML5 音频播放器无法加载下一首曲目

[英]Ajax HTML5 Audio Player can't load next track after second track plays

This is a follow-up question to this post...这是这篇文章的后续问题......

Auto load new song into HTML 5 audio player when track ends using php/jquery 使用 php/jquery 在曲目结束时自动将新歌曲加载到 HTML 5 音频播放器中

Thanks to contributions by @Roko C. Buljan I was able to use the following script to load a new track into the div#player.感谢@Roko C. Buljan 的贡献,我能够使用以下脚本将新曲目加载到 div#player 中。 When track ends, I simulated a click using the ajax function loadurl which then loads a new track into div#player.当曲目结束时,我使用 ajax 函数 loadurl 模拟了一次点击,然后将新曲目加载到 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.我认为 addEventListener 无法识别通过 ajax 加载的 player.php 文件。

Looking at the code you were using, I can see many errors:查看您使用的代码,我可以看到很多错误:

  • the <source> tag should self close; <source>标签应该自动关闭;
  • the <source> tag should be a child of <audio> tag <source>标签应该是<audio>标签的子标签
  • tha <audio> tag must not have the loop attribute, or the ended event is never called; tha <audio>标签不得具有loop属性,否则永远不会调用已ended事件; you have to remove this attribute even from the player.php script.您甚至必须从 player.php 脚本中删除此属性。

I think you have already removed the loop attribute from the actual code, otherwise it shall not work even on the first time.我认为您已经从实际代码中删除了loop属性,否则即使第一次也无法正常工作。

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.当轨道结束时,它会在没有附加事件处理程序的新音频对象上引发ended事件。 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.正确的做法是不要替换音频对象,而只需将其src属性替换为新的轨道名称。

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:所以你可以改变你的 player.php 以返回文件名和其他没有 html 标签的数据,例如以 json 格式:

$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.其中imagedownload<img/><a>download</a>元素的 ID。

Another options is to rebind the ended event each time you replace the html, but I strongly discourage this approach.另一种选择是在每次替换 html 时重新绑定已ended事件,但我强烈反对这种方法。 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.请注意, audio符号必须是可变的,而不是常量,否则您无法将其值替换为新的音频元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM