我正在创建一个音频Web播放器,我希望它可以连续运行,这意味着当一段音频播放完毕后,它将继续播放下一个。
但是,我遇到了一个问题,即一切正常运行,但是一旦上一个音频播放完毕,而下一个音频开始播放,则每2秒播放一次,新的音频就会暂停播放。不断地。
这是我当前的JavaScript
代码块:
function playPauseButton(button, wave, trackID){
var button = $(button); // play button
if(wave.isPlaying()){ // if the audio is playing and the user clicks play button, pause the audio
button.removeClass("playing");
wave.pause();
} else { // vice versa
button.addClass("playing");
wave.play();
}
waveDuration = wave.getDuration(); // audio duration
var nextTrack = ++trackID; // get the current audio track ID and plus 1 to get the new track ID
setInterval(function(){ // check every 2 seconds if the audio is finished playing
if(wave.getCurrentTime() >= waveDuration){ // if it has, make the play button a pause button
button.removeClass("playing");
$(nextTrack + '-ppbutton').click(); // simulate new track play button click
}
}, 2000);
}
和我非常简单的
HTML
播放按钮:<!-- onclick play audio (if paused), pause audio (if playing) !-->
<div onclick="playPauseButton(this, a2wave, 2);" id="2-ppbutton"></div>
<!-- 2 is the id !-->
我已经尝试了好几个小时了,但是,它仍然使我感到困惑(我不太擅长JavaScript)
感谢所有帮助和建议。
我试图评论一切以帮助您理解
更新:
感谢Vlaz解决了我的问题;非常感谢! :)
但是,如果人们仍然想提出建议或进行编辑,也非常欢迎您!
谢谢。
最佳答案
问题
每次按下按钮,您对setInterval
的使用都会启动一个新的代码。因此,在三按之后,您需要运行三台。另外,请记住,每个人也将运行自己的检查。所以我相信我知道您的问题在哪里,这里是概述
第一次调用setInterval
,我们将其称为intervalPrime。假设歌曲的持续时间为60秒。
歌曲每2秒检查一次,最后结束。
单击播放按钮时会调用一个新的setInterval
-这会创建一个新的间隔-我们将其称为intervalSecond。这将检查一首新歌和新的时长,但是细节无关紧要。
这首歌会播放,intervalSecond会监听这首歌是否结束。
同时,Prime仍在进行检查。而且由于wave.getCurrentTime()
可能返回60
(歌曲的结尾),因此检查通过的是60 >= 60
,因此单击该按钮。
如何避免
删除旧的间隔
您可以做的是确保一次只激活一个setInterval
。该函数返回计时器的ID,因此您可以执行与此类似的操作
var currentChecker;
function playPause() {
/* .... */
if (shouldClick) {
clearTimeout(currentChecker);
currentChecker = setInterval( /* ... */ );
}
}
(说明性的)
因此,本质上,尝试在开始新间隔之前先停止上一个间隔,以维护单个间隔。
仅间隔一个
另一种选择是仅激活一个时间间隔并保持状态,因此您可以执行以下操作
var masterLoop = setInterval(function() {
var wave = getCurrentWave(); //fetching it will depend on your application
if(wave.getCurrentTime() >= wave.getDuration()){
/* handle what happens */
}
} , 2000);
歌曲结束时使用
setInterval
。我不熟悉用于播放声音的API,但是如果可以挂接到结束事件,则可以在发生这种情况时使用简单的
setTimeout
//assuming the API allows to do something like this
wave.onFinish(function() {
setInterval(playNext, 2000);
})
其中一个以上
如果API没有提供挂钩完成比赛的方法,则更好的选择是将后两者结合起来。有一个主循环检查曲目的状态,完成后使用
setInterval
安排下一首歌曲。间隔延迟可能需要设置得较低,但这会导致音轨之间的时间更一致,因为一首歌曲可能会结束,并且0.3秒后会检查并播放该歌曲,或者一首歌可能会在歌曲播放后立即结束时间间隔结束,因此您的间隔为2秒。维护一个
setTimeout
这类似于清除旧间隔的第一个建议,但并不完全相同。
事实是您不需要继续检查歌曲是否已完成播放,因为您已经知道歌曲何时结束。因此,在播放时,您可以使用
setTimeout
将下一首歌曲排队//assuming wave returns time in milliseconds
var playNextIn = (wave.getDuration() - wave.getCurrentTime()) + 2000;
nextSongTimer = setTimeout(function() {
/* code to play next song */
}, playNextIn);
因此,这种方式您无需继续检查。
但是,唯一的问题是用户单击
pause
,在这种情况下,您将需要调用clearInterval(nextSongTimer)
,因为不再需要它。因此,每次播放一首歌曲时,您只需要启动一次计时器即可。