HowlerJS step 函数不会在搜索时更新范围输入值
HowlerJS step function doesn't update range input value on seek
我正在使用 Howler.js 创建播客播放器。
我有 4 个按钮和一个用于控制播客的输入。
当您点击播放、后退和前进按钮时,在执行它们的操作后,它们会调用一个名为 step 的函数,该函数负责更新范围输入的值。
function step(){
var self = this;
var seek = sound.seek() || 0;
rangeInput.attr('value', seek);
//If sound is still playing, continue stepping
if(sound.playing()){
requestAnimationFrame(step.bind(self));
}
}
当您尝试使用输入更改您在播客中的位置时,问题就来了。虽然它确实向前移动了音频,但 step 函数停止更新范围输入的值。
奇怪的是,如果您在使用范围输入后检查元素,您确实可以看到它的值正在 DOM 中更新。但是那个点再也没有移动过。
我创建了一个 fiddle 来重现这个问题。 Link to Fiddle
这是我的全部代码
var sound = new Howl({
src: ['https://s3.amazonaws.com/ShopTalk/080_rapidfire_19.mp3'],
onplay:function(){
requestAnimationFrame(step.bind(this));
}
});
var rangeInput = $('#range');
sound.once('load', function(){
$('#loading').hide();
$('#ready').show();
$('#controls').show();
$('#range').attr('max', sound.duration());
console.log('Podcast Loaded');
});
$('#play').on('click', playPodcast);
$('#pause').on('click', pausePodcast);
$('#skip-back').on('click', skipBackward);
$('#skip-forward').on('click', skipForward);
rangeInput.change(seek);
function step(){
var self = this;
var seek = sound.seek() || 0;
rangeInput.attr('value', seek);
//If sound is still playing, continue stepping
if(sound.playing()){
requestAnimationFrame(step.bind(self));
}
}
function seek(){
var seekedTime = $('#range').val();
sound.seek([seekedTime]);
step();
}
function playPodcast(){
sound.play();
}
function pausePodcast(){
sound.pause();
}
function skipForward(){
sound.seek([sound.seek() + 5]);
step();
}
function skipBackward(){
sound.seek([sound.seek() - 5]);
step();
}
总而言之,
我正在使用一个名为 step()
的函数,只要音频文件仍在播放,它就会不断更新范围输入的值。当您使用范围输入手动 select 播客中的某个位置时,它会停止更新该值,即使它正在 DOM 中更新,并且播客会准确地寻找其新位置并继续播放。
我发现了一个错误。
错误是多重播放 mp3。
您可以防止玩多个。
添加此代码。
function playPodcast(){
if(sound.playing()) {
return;
}
sound.play();
}
这就是您问题的答案。
function seek() {
var seekedTime = $('#range').val();
sound.pause();
sound.seek([seekedTime]);
sound.play();
}
测试是https://jsfiddle.net/h6b57f4v/5/
[参考]https://github.com/goldfire/howler.js/issues/1156#issuecomment-487292193
我认为有多个错误,所以我尝试了不同的逻辑来更好地工作。
基本上阻止多个 sound.play()
播放,前进和后退。
阻止 rangeInput
在我们试图拖动它时进行设置。
所以不要绑定requestAnimationFrame(step)
如果鼠标在rangeInput
var self = this;
var mousehover = false;
var sound = new Howl({
src: ['https://s3.amazonaws.com/ShopTalk/080_rapidfire_19.mp3'],
onplay: function() {
id = requestAnimationFrame(step);
}
});
var rangeInput = $('#range');
sound.once('load', function() {
$('#loading').hide();
$('#ready').show();
$('#controls').show();
$('#range').attr('max', sound.duration());
console.log('Podcast Loaded');
});
$('#play').on('click', playPodcast);
$('#pause').on('click', pausePodcast);
$('#skip-back').on('click', skipBackward);
$('#skip-forward').on('click', skipForward);
rangeInput.change(seek);
rangeInput.on("mouseenter", () => {
mousehover = true;
})
rangeInput.on("mouseout", () => {
mousehover = false;
step();
})
function step() {
var seek = sound.seek() || 0;
rangeInput.val(seek);
//If sound is still playing, continue stepping
if (!mousehover && sound.playing()) {
id = requestAnimationFrame(step);
}
}
function seek() {
cancelAnimationFrame(id)
var seekedTime = $('#range').val();
sound.seek([seekedTime]);
sound.play()
}
function playPodcast() {
if (!sound.playing())
sound.play();
}
function pausePodcast() {
if (sound.playing())
sound.pause();
}
function skipForward() {
sound.seek([sound.seek() + 5]);
if (!sound.playing())
sound.play();
}
function skipBackward() {
sound.seek([sound.seek() - 5]);
if (!sound.playing())
sound.play()
}
body {
padding: 25px;
}
#ready {
display: none;
}
#controls {
display: none;
}
#range {
-webkit-appearance: none;
margin-top: 35px;
width: 100%;
height: 15px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
#range::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: #00AEC7;
cursor: pointer;
}
#range::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: #00AEC7;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.2/howler.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<p id="loading">Loading...</p>
<p id="ready">Ready</p>
<hr />
<div id="controls">
<button id="play">Play</button>
<button id="pause">Pause</button>
<button id="skip-back">Back 5 seconds</button>
<button id="skip-forward">Forward 5 seconds</button>
<br />
<input type="range" min="0" max="" value="0" id="range">
</div>
我正在使用 Howler.js 创建播客播放器。
我有 4 个按钮和一个用于控制播客的输入。
当您点击播放、后退和前进按钮时,在执行它们的操作后,它们会调用一个名为 step 的函数,该函数负责更新范围输入的值。
function step(){
var self = this;
var seek = sound.seek() || 0;
rangeInput.attr('value', seek);
//If sound is still playing, continue stepping
if(sound.playing()){
requestAnimationFrame(step.bind(self));
}
}
当您尝试使用输入更改您在播客中的位置时,问题就来了。虽然它确实向前移动了音频,但 step 函数停止更新范围输入的值。
奇怪的是,如果您在使用范围输入后检查元素,您确实可以看到它的值正在 DOM 中更新。但是那个点再也没有移动过。
我创建了一个 fiddle 来重现这个问题。 Link to Fiddle
这是我的全部代码
var sound = new Howl({
src: ['https://s3.amazonaws.com/ShopTalk/080_rapidfire_19.mp3'],
onplay:function(){
requestAnimationFrame(step.bind(this));
}
});
var rangeInput = $('#range');
sound.once('load', function(){
$('#loading').hide();
$('#ready').show();
$('#controls').show();
$('#range').attr('max', sound.duration());
console.log('Podcast Loaded');
});
$('#play').on('click', playPodcast);
$('#pause').on('click', pausePodcast);
$('#skip-back').on('click', skipBackward);
$('#skip-forward').on('click', skipForward);
rangeInput.change(seek);
function step(){
var self = this;
var seek = sound.seek() || 0;
rangeInput.attr('value', seek);
//If sound is still playing, continue stepping
if(sound.playing()){
requestAnimationFrame(step.bind(self));
}
}
function seek(){
var seekedTime = $('#range').val();
sound.seek([seekedTime]);
step();
}
function playPodcast(){
sound.play();
}
function pausePodcast(){
sound.pause();
}
function skipForward(){
sound.seek([sound.seek() + 5]);
step();
}
function skipBackward(){
sound.seek([sound.seek() - 5]);
step();
}
总而言之,
我正在使用一个名为 step()
的函数,只要音频文件仍在播放,它就会不断更新范围输入的值。当您使用范围输入手动 select 播客中的某个位置时,它会停止更新该值,即使它正在 DOM 中更新,并且播客会准确地寻找其新位置并继续播放。
我发现了一个错误。
错误是多重播放 mp3。
您可以防止玩多个。
添加此代码。
function playPodcast(){
if(sound.playing()) {
return;
}
sound.play();
}
这就是您问题的答案。
function seek() {
var seekedTime = $('#range').val();
sound.pause();
sound.seek([seekedTime]);
sound.play();
}
测试是https://jsfiddle.net/h6b57f4v/5/
[参考]https://github.com/goldfire/howler.js/issues/1156#issuecomment-487292193
我认为有多个错误,所以我尝试了不同的逻辑来更好地工作。
基本上阻止多个 sound.play()
播放,前进和后退。
阻止 rangeInput
在我们试图拖动它时进行设置。
所以不要绑定requestAnimationFrame(step)
如果鼠标在rangeInput
var self = this;
var mousehover = false;
var sound = new Howl({
src: ['https://s3.amazonaws.com/ShopTalk/080_rapidfire_19.mp3'],
onplay: function() {
id = requestAnimationFrame(step);
}
});
var rangeInput = $('#range');
sound.once('load', function() {
$('#loading').hide();
$('#ready').show();
$('#controls').show();
$('#range').attr('max', sound.duration());
console.log('Podcast Loaded');
});
$('#play').on('click', playPodcast);
$('#pause').on('click', pausePodcast);
$('#skip-back').on('click', skipBackward);
$('#skip-forward').on('click', skipForward);
rangeInput.change(seek);
rangeInput.on("mouseenter", () => {
mousehover = true;
})
rangeInput.on("mouseout", () => {
mousehover = false;
step();
})
function step() {
var seek = sound.seek() || 0;
rangeInput.val(seek);
//If sound is still playing, continue stepping
if (!mousehover && sound.playing()) {
id = requestAnimationFrame(step);
}
}
function seek() {
cancelAnimationFrame(id)
var seekedTime = $('#range').val();
sound.seek([seekedTime]);
sound.play()
}
function playPodcast() {
if (!sound.playing())
sound.play();
}
function pausePodcast() {
if (sound.playing())
sound.pause();
}
function skipForward() {
sound.seek([sound.seek() + 5]);
if (!sound.playing())
sound.play();
}
function skipBackward() {
sound.seek([sound.seek() - 5]);
if (!sound.playing())
sound.play()
}
body {
padding: 25px;
}
#ready {
display: none;
}
#controls {
display: none;
}
#range {
-webkit-appearance: none;
margin-top: 35px;
width: 100%;
height: 15px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
#range::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: #00AEC7;
cursor: pointer;
}
#range::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: #00AEC7;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.2/howler.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<p id="loading">Loading...</p>
<p id="ready">Ready</p>
<hr />
<div id="controls">
<button id="play">Play</button>
<button id="pause">Pause</button>
<button id="skip-back">Back 5 seconds</button>
<button id="skip-forward">Forward 5 seconds</button>
<br />
<input type="range" min="0" max="" value="0" id="range">
</div>