<audio> .addEventListener прогресс не срабатывает, если содержимое загружается слишком быстро - PullRequest
1 голос
/ 17 марта 2012

Я никогда не думал, что быстрая загрузка контента была бы проблемой раньше, но я столкнулся с определенной проблемой.

Я сделал музыкальный проигрыватель HTML5, и панель с буферизацией работает нормально, есликонтент загружается с нормальной скоростью, но если контент загружается очень быстро, то есть по локальной сети, то слушатель не отвечает достаточно быстро, чтобы что-либо сделать.AddEventListener находится внутри функции готовности документа jQuery.Код, который я использую ниже:

audio.addEventListener('progress', function() {
    if(audio.duration && audio.buffered.end(0)) {
        if(resuming == 1) {
            resuming = 0;
            resumeplaypos = ReadCookie('resumeplaypos');
            audio.currentTime = resumeplaypos;
        }
        loaded = (audio.buffered.end(0) / audio.duration) * 100;
        $('.player-loaded').width(loaded + '%');
        console.log('Loaded: ' + loaded);
    }
}, false);

Теперь, что обычно происходит (с помощью console.log для проверки), это срабатывает только один раз, обычно между 10 и 20%.Следовательно, моя буферная полоса застряла на этом значении, несмотря на всю загруженную дорожку.В редких случаях он может срабатывать дважды, выводя:

[11:37:42.323] Loaded: 7.525227180155711 @ http://topaz:88/music.js:316
[11:37:42.605] Loaded: 59.57557430800252 @ http://topaz:88/music.js:316

Но обычно это просто что-то вроде этого:

[11:39:52.773] Loaded: 13.313090306445885 @ http://topaz:88/music.js:316

Есть ли способ сделать слушателя прогресса более надежнымили мне придется обойти это как-то иначе?(или я делаю что-то глупое).

Вы можете игнорировать код возобновления, это еще одна вещь, над которой я работаю, которая возобновляет трек, когда кто-то возвращается на страницу, он не используется в этой ситуации.

Аудиоэлемент создается сразу после загрузки файла JS через следующую строку:

var audio = document.createElement("audio");

Я переместил код за пределы функции готовности документа и добавил консольный журнал впрогресс за пределами проверки if, но поведение по-прежнему имитирует ведение журнала внутри, как и раньше:

[10:49:24.698] 31.702494 / 276.8 @ http://topaz:88/music.js:302
[10:49:24.728] 31.702494 / 276.8 @ http://topaz:88/music.js:302

При использовании:

console.log(audio.buffered.end(0) + " / " + audio.duration);

Хотя странно то, что он сообщил об одном и том жезначение дважды, когда второе значение явно должно быть «завершенным» значением.Браузер Firefox 11, сервер Apache (2.2.22).Обратите внимание, что теперь я получаю частоту отказов 50/50 (успех, когда он на самом деле сообщает о загрузке 100% в конце).

Я поместил пример кода здесь - https://xnode.org/paste/12 (Я не могу понять, как заставить jsfiddle правильно его запустить, плюс в любом случае он пропустил бы аудиофайл) - это демонстрирует то же поведение в минималистском стиле.

Только 2 из5 раз (через обновление Ctrl + F5) он срабатывал при 100% -ном результате завершения.Остальные 3 раза он срабатывал один раз между 10 и 40% (случайным образом).Тестовый аудиофайл представлял собой 6,9-мегабайтную дорожку с кодировкой 6 OGG Vorbis на другом компьютере в локальной сети, обслуживаемую из коробки Apache 2.2.22.

Стоит отметить, что если вы попытаетесь разместить аудиофайл на том же компьютерекак веб-страница, она НЕ будет работать, потому что загружается слишком быстро (сразу запускается 100% завершение).Похоже, это происходит только в том случае, если A) файл не загружается - и - B) он загружается недостаточно медленно, чтобы обработчик продолжал запускать снова и снова.

1 Ответ

0 голосов
/ 18 марта 2012

Насколько я понимаю, то, что вы пытаетесь сделать, должно работать.В соответствии с спецификацией :

Как только весь медиаресурс был извлечен (но потенциально до того, как какой-либо из них был декодирован), запускается простое событие с именем progress в медиаэлементе.

И я вижу соответствующий код в Firefox :

   // Ensure a progress event is dispatched at the end of download.

Попробуйте протоколировать duration и audio.buffered отдельно от слушателя вне любогоif s - в моем тестировании duration может быть NaN или Infinity в момент запуска последнего события прогресса.

Если это не поможет, я бы порекомендовал упомянуть браузерсервер HTTP, формат аудио, который вы используете, а также упрощающий тестовый пример.

Вот код, который я использовал для ночного тестирования на Firefox с python -m SimpleHTTPServer 8000 в качестве сервера HTTP (bunny.ogg взят из здесь ):

<audio src="bunny.ogg" controls>

</audio>

<script>
  var audio = document.getElementsByTagName("audio")[0];
  audio.addEventListener("progress", onProgress, false);

  function onProgress() {
    var loaded = (audio.buffered.end(0) / audio.duration) * 100;
    console.log(audio.buffered.end(0) + " / " + audio.duration + " * 100 = " + loaded);
  }
</script>
...