Я работаю над созданием проигрывателя подкастов, используя 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)); } } 

Проблема возникает, когда вы пытаетесь использовать ввод, чтобы изменить свое местоположение в подкасте. Хотя звук действительно перемещается вперед, функция шага прекращает обновление значения входного диапазона.

Странно то, что если вы проверяете элемент после использования ввода диапазона, вы действительно можете видеть, что его значение обновляется в DOM. Но точка никогда не двигается снова.

Я создал скрипку, где я воссоздал эту проблему. Ссылка на скрипку

Вот весь мой код

 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() которая постоянно обновляет значение диапазона ввода, пока аудиофайл все еще воспроизводится. Когда вы вручную выбираете место в подкасте, используя вход диапазона, оно перестает обновлять значение, даже если оно обновляется в 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() на Play, вперед и назад.

Запретите rangeInput для установки, пока мы просто пытаемся его перетащить.

Так что не requestAnimationFrame(step) если мышь находится на rangeInput

Js образец скрипки

 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", () ={amp}gt; { mousehover = true; }) rangeInput.on("mouseout", () ={amp}gt; { mousehover = false; step(); }) function step() { var seek = sound.seek() || 0; rangeInput.val(seek); //If sound is still playing, continue stepping if (!mousehover {amp}amp;{amp}amp; 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; } 
 {amp}lt;script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.2/howler.min.js"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;p id="loading"{amp}gt;Loading...{amp}lt;/p{amp}gt; {amp}lt;p id="ready"{amp}gt;Ready{amp}lt;/p{amp}gt; {amp}lt;hr /{amp}gt; {amp}lt;div id="controls"{amp}gt; {amp}lt;button id="play"{amp}gt;Play{amp}lt;/button{amp}gt; {amp}lt;button id="pause"{amp}gt;Pause{amp}lt;/button{amp}gt; {amp}lt;button id="skip-back"{amp}gt;Back 5 seconds{amp}lt;/button{amp}gt; {amp}lt;button id="skip-forward"{amp}gt;Forward 5 seconds{amp}lt;/button{amp}gt; {amp}lt;br /{amp}gt; {amp}lt;input type="range" min="0" max="" value="0" id="range"{amp}gt; {amp}lt;/div{amp}gt;