【问题标题】:Audio On-end Play New File音频端播放新文件
【发布时间】:2021-11-26 22:02:06
【问题描述】:

我有一个webapp,当您单击使用 ajax/jquery 的链接时,它会加载和播放音轨。一切正常,但是当轨道结束时,轨道设置为循环,这可以永远持续下去。我希望播放器从数据库中自动加载随机曲目并在曲目结束时播放。音频就是这样设置的。

<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>

当您单击它时,我正在使用 jquery 将新曲目加载到#player div 中。例如;

<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>

在我的 player.php 文件中有;

<?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">

我已经尝试了一些来自这里和在线的建议,例如添加;

<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>

还有这个……

<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>

还有这个……

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

</script>

但它们都不起作用。我做错了什么?

更新

感谢@Roko C. Buljan 的贡献,我能够使用以下脚本将新曲目加载到 div#player 中。当曲目结束时,使用 ajax 函数 loadurl 模拟点击,并将新曲目加载到#player。这会加载一个新轨道,但是当该轨道结束时,它不会加载另一个轨道。我该如何解决?

<a href="javascript:;" id="randomplay" onClick="loadurl('player.php?random=1','player')"></a>
<script type="text/javascript">

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

audio.addEventListener("ended", () => {

        $("#randomplay").click();

    }); 

</script>

【问题讨论】:

  • PS... 停止使用 on* 内联 JS 处理程序。 JS(与 STYLE 相同)应该都在各自的标签或文件中。请改用addEventListener。从 HTML5 开始,&lt;script&gt; 标记中也不需要 text/javascript
  • 另外,应该是document.querySelector('#myAudio'); 而不是document.querySelector('myAudio');
  • @RokoC.Buljan 嘿兄弟!所以我让它在一定程度上工作,但我无法让它加载下一首曲目。有任何想法吗?我正在使用 ajax 将 php 页面加载到 div 中,但在加载下一个曲目后,它无法再次加载。

标签: javascript php jquery html5-audio


【解决方案1】:

Tl;Dr: 使用:audio.addEventListener("ended", playNextFn);

有两种可能:

1。如果客户端没有完整的曲目列表:

在您的服务器上创建一个路由,该路由可以响应随机轨道并通过 AJAX 将其以 JSON 格式(如 {"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); // ♫♪♫...♪♫♪♫♪...♫♪!

希望您知道如何编写一个 PHP 代码,该代码从数据库 songs 表中获取随机条目并将其作为 JSON 返回。

2。如果客户预先知道所有曲目:

"ended"事件上使用JS切换到随机曲目。

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); // ♫♪♫...♪♫♪♫♪...♫♪!

每日提示:您可以在 JS 中直接从 songs 数组中生成 HTML。

完整示例

带有维基媒体音频文件和 HTML &lt;audio&gt; 元素:

const songs = [
  {src: "https://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
&lt;audio id="myAudio" controls&gt;&lt;/audio&gt;

【讨论】:

  • 谢谢你,但这是否意味着所有歌曲都必须排在第一位,对吗?如果 db 有超过 1000 首歌曲,所有这些都必须列出,然后随机选择一首?有没有办法只从曲目末尾的数据库中获取一首歌曲?
  • @JaySmoke 是的,在这种情况下,您需要一个像 ie: /api/getRandomSong.php 这样的 PHP 路由,它以像 {file: "bazzz.mp3", name: "", group: "", year:"", cover: ""} 这样的 JSON 响应,然后您只需将其加载到音频对象中就像在 playRandomFile 函数示例中一样。 JS怎么用fetch...嗯,希望你google一下!否则,如果你觉得太难,我可以给你一个简单的例子。
  • 我尝试了您的建议,但收到错误 Uncaught (in promise) DOMException: play() failed 因为用户没有先与文档交互。我想当我们到达那里时我需要那个快速的 JS Fetch 示例:)
  • @JaySmoke 添加了一个示例并修复了另一个。
  • 现在,既然~~(Math.random() * songs.length) 可以随便再次给出相同的索引,并重播相同的歌曲……作为工程师,您的工作就是确保您不会再次播放相同的歌曲。这是读者的任务/家庭作业。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 2011-11-26
  • 2020-02-11
  • 2017-08-27
相关资源
最近更新 更多