使用JQueryUI作为音频搜索控件,并在更改歌曲时将新滑块重新绑定到相同的<audio>控件

时间:2016-05-28 17:08:03

标签: javascript jquery html5 jquery-ui html5-audio

感谢您查看我的问题。小提琴是HERE

我正在尝试为页面上的许多歌曲实现音频播放器。这是使用JQueryUI Slider和HTML5 Audio,带有一个Audio元素和多个滑块。

现在的问题是:

  1. 滑块不会为音频设置动画。
  2. 滑块不会寻找音频。
  3. 之前,当上述两个WERE都工作时,一旦你选择了歌曲中的一个位置,滑块将不再有动画效果。
  4. 点击新歌后,我已为rebindSlider()创建了功能。在这个函数中,发生了两件事:a)创建了新的滑块,定义了幻灯片和停止侦听器,以及b)新滑块绑定到新歌曲的音频元素上的timeupdate事件。我觉得这应该是我需要的所有东西,但是滑块没有绑定,当你试图拖动滑块时会看到undefined错误。

    使用单个滑块和单个音频元素,我已经获得了90%的方式;一旦我为滑块引入了多个div,就会出现问题。

    以下是rebindSlider的代码:

    function rebindSlider(sliderDiv) {
      var createSeek = function() {
        sliderDiv.slider({
          value: 0,
          step: 1,
          orientation: "horizontal",
          range: "min",
          max: audioPlayer.duration,
          animate: true,
    
          slide: function() {
            manualSeek = true;
          },
    
          stop: function(e, ui) {
            manualSeek = false;
            audioPlayer.currentTime = ui.value;
          }
        });
      };
    
      createSeek();
    
      $(audioPlayer).bind('timeupdate', function() {
        if (!manualSeek) {
          sliderDiv.slider('value', audioPlayer.currentTime);
        }
      });
    } 
    

    进一步说明如下。

    页面上包含一系列歌曲。每首歌都有一个包含div,其中包含元数据(小提琴中不存在)的<a>,以及为音频搜索滑块指定的div。页面上有一个音频元素,当您点击歌曲时会重新加载它。

    当点击一首歌时,我想销毁绑定到播放音频的滑块(如果需要),并将点击的歌曲的新滑块绑定到音频播放器。

    我最接近的是让滑块1)在歌曲播放时开始动画2)拖动滑块移动到歌曲中的不同位置。滑块移动后,它不再动画。在重构之后,滑块不再起作用,虽然我可以转到之前的提交来获取工作代码,但是重构是如此激烈以至于我更愿意呈现当前的非工作代码,因为它更能代表我的内容我想结束。

    推理和其他信息。

    我正在制作一个网络应用程序,我有一个音频播放器的概念,我宁愿自己构建,而不是修改我遇到过的任何东西。话虽这么说,如果你知道我可以实施的东西,我会喜欢建议。

    这个想法听起来很简单,而且大部分内容已经完成,但其中有一个非常关键的部分我遇到了麻烦,即设置滑块以使其动画,并寻找到所需的位置。音轨,并且能够在单击歌曲时将新滑块重新绑定到音频。

1 个答案:

答案 0 :(得分:0)

要使滑块正常工作,需要进行一些更改。我将各自覆盖它们,以便它们适用。

无效的滑块最大值

第一个问题是滑块的最大值设置为audioPlayer.duration,除了HTML5音频播放器异步加载音频资源外,它通常都很好。这意味着即使您可能在设置滑块之前加载了音频,但音频资源可能尚未加载,audioPlayer.duration可能无效(可能为NaN)。

只需从滑块初始化中删除max键(和值),这样就可以了。中提琴!滑块移动了!

一个警告:滑块默认为100单位的最大值,音频的持续时间略长于25秒,因此当滑块为1/4时,歌曲将完成播放。我们可以将max键设置为25(秒),但这有点不合适,如果我们更改音频以使用其他来源,则无法使用。

设置滑块最大值

一旦异步加载完成,捕获audioPlayer.duration必须完成处理事件。 Javascript提供了这样的活动:onloadedmetadata。让我们安装一个事件处理程序,并使其工作:

audioPlayer.onloadedmetadata = function() {
    $(".slider").slider("option", { max: Math.floor(audioPlayer.duration) });
};

现在,这样做是在音频素材加载后将滑块的max设置为audioPlayer.duration。实际上,这是当前设置所有滑块的最大值,但这不应该是一个问题,因为它们都是隐藏的。如果你有很多歌曲,可能会有一些延迟,你可能想找到要更新的特定滑块。

平滑滑动

现在,您可能会注意到这些更改后滑块有些跳跃。它会暂停一秒,然后跳转,然后暂停,等等。通过在滑块初始化中将step键更改为0.1,可以非常轻松地修复此问题,如下所示:

sliderDiv.slider({
  value: 0,
  step: 0.1,
  orientation: "horizontal",

时间更新每50到250毫秒发生一次,但滑块只能以1秒为增量移动。现在,以1/10秒的增量,滑块将更平滑地移动。如果你愿意,你可以略微减少,但不要使数字太小; 0.01是实际下限。

更新播放结束状态

当歌曲结束时,&#34;播放&#34;按钮处于播放状态,即使没有播放任何内容。还有一个事件:onended。我们会使用该事件来更新用户界面,这样用户就不会感到困惑:

audioPlayer.onended = function() {
  playButton.removeClass('fa-pause-circle-o');
  playButton.addClass('fa-play-circle-o');
};

现在,当歌曲结束时,播放按钮将返回播放&#34;状态,用户将知道点击它将播放歌曲。

重构播放按钮状态

由于现在有3个地方更新了播放按钮的状态,这涉及重复,我们可以重构状态处理。此功能将最终设置播放按钮的状态:

function setUIState() {
  if (audioPlayer.paused || audioPlayer.ended) {
    playButton.removeClass('fa-pause-circle-o');
    playButton.addClass('fa-play-circle-o');
  } else {
    playButton.removeClass('fa-play-circle-o');
    playButton.addClass('fa-pause-circle-o');
  }
}

现在,从其他函数调用它,最终得到onended事件处理程序:

audioPlayer.onended = function() {
  setUIState();
};

changeUI功能:

function changeUI(selectedSong) {
  setUIState();

  var sliderDiv = selectedSong.parent().find('.slider');
  rebindSlider(sliderDiv);//Bind the desired slider
  $('.slider').hide(); //Hide all sliders
  sliderDiv.show();//Show only the desired slider
} 

然后,播放按钮点击处理程序:

$(".playButton").click(function() {    
  if (audioLoaded === true) {
    if (!audioPlayer.paused) {
      audioPlayer.pause();
    } else {
      audioPlayer.play();
    }
    setUIState();
  } else {
    alert("Please click a song");
  }
  return false;
});

这使得按钮的UI状态管理易于处理,并防止状态通过应用程序爬出。您已经可以看到重构代码如何更清晰,更易于维护。另外,作为奖励,我们必须使用酷audioPlayer.ended属性,您不会使用它。

但等等,还有更多!

通过上述更改,您可以很好地使用非常实用的音频播放器。但这肯定不是功能功能的终点。总有成长空间!

我创建了一个包含所有这些更改的jsFiddle,以及原始代码的一些其他mod。您可以在https://jsfiddle.net/mgaskill/mp087adp/找到最新版本。其他功能可能会不断出现,但jsFiddle已经包含了这些附加功能:

  • 音量控制(滑块)
  • 时间显示
  • 为音频控件动态生成HTML(使HTML更简单)