我正在尝试为页面上的许多歌曲实现音频播放器。这是使用JQueryUI Slider和HTML5 Audio,带有一个Audio元素和多个滑块。
现在的问题是:
点击新歌后,我已为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)拖动滑块移动到歌曲中的不同位置。滑块移动后,它不再动画。在重构之后,滑块不再起作用,虽然我可以转到之前的提交来获取工作代码,但是重构是如此激烈以至于我更愿意呈现当前的非工作代码,因为它更能代表我的内容我想结束。
我正在制作一个网络应用程序,我有一个音频播放器的概念,我宁愿自己构建,而不是修改我遇到过的任何东西。话虽这么说,如果你知道我可以实施的东西,我会喜欢建议。
这个想法听起来很简单,而且大部分内容已经完成,但其中有一个非常关键的部分我遇到了麻烦,即设置滑块以使其动画,并寻找到所需的位置。音轨,并且能够在单击歌曲时将新滑块重新绑定到音频。
答案 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已经包含了这些附加功能: