我正在创建一个音频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),因为不再需要它。因此,每次播放一首歌曲时,您只需要启动一次计时器即可。

10-07 19:59
查看更多