Браузер Android выгружает аудиоэлемент HTML5 после каждого воспроизведения (), вызывая задержку

У меня есть простое приложение, которое многократно воспроизводит короткий звук, вызывая метод play() для элемента audio в JavaScript. Он хорошо работает в настольных браузерах, айпадах, айфонах и т. д. На мобильном устройстве под управлением Android 2.3.3 при первом воспроизведении звука я слышу его сразу после вызова метода play(), но при последующих вызовах появляется заметная и переменная задержка.

Я провел некоторое расследование и обнаружил, что устройство извлекает аудиофайл с сервера каждый раз, когда вызывается метод play(). Я могу вызывать метод load() для аудиоэлемента, чтобы повторно загружать его после каждого воспроизведения, тем самым ставя его в очередь для следующего воспроизведения, но с этим пластырем возникает ряд проблем. Мне бы очень хотелось, чтобы браузер просто постоянно загружал аудиоэлемент, а не выгружал его, как только он заканчивает воспроизведение. Кто-нибудь знает, возможно ли это?

РЕДАКТИРОВАТЬ: я провел немного больше исследований и обнаружил, что после воспроизведения звука состояние готовности аудиоэлемента остается равным HAVE_ENOUGH_DATA, даже если браузер не будет воспроизводить этот звук снова, не выгрузив его с сервера. Я считаю, что это ошибка. Я надеялся использовать состояние готовности для обнаружения браузеров, которые выгружаются после игры и явно загружаются только при необходимости, но это не сработает.


person AlpineCarver    schedule 07.07.2011    source источник


Ответы (3)


Чем больше экспериментов я провожу, тем больше шероховатостей я нахожу в реализации тега аудио HTML5 в Android 2.3.3. Там много сломано, по крайней мере, на телефоне Droid X, который я использую для тестирования.

Лучшее, что я придумал до сих пор, - это лейкопластырь, упомянутый в моем первоначальном вопросе: как только вызов play() завершится, вызовите метод load(), чтобы подготовиться к следующему play():

if (navigator.userAgent.toLowerCase().indexOf("android") > -1)
  audElt.addEventListener('ended', function () {
    var t = setTimeout(function () { audElt.load(); }, 1000);
  }, false);

Мне пришлось ограничить обходной путь пользовательскими агентами Android, потому что простой вызов метода load() создает проблемы в Chrome и создает ненужные обращения к серверу в системах, отличных от Android.

Пришлось добавить 1-секундную задержку, потому что если я просто вызывал load() из "законченного" обработчика, это прерывало воспроизведение, которое, по-видимому, еще не "закончилось"....

Конечно, он по-прежнему постоянно получает звук с сервера, поэтому, если вы попытаетесь воспроизвести звук несколько раз в быстрой последовательности, все быстро пойдет наперекосяк.

person AlpineCarver    schedule 08.07.2011

лучшее решение, которое я нашел. Другой вариант — просто использовать тег видео, но и с этим есть некоторые проблемы. Ничто, кажется, не работает достаточно хорошо, чтобы реализовать.

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

person user914866    schedule 21.10.2011

Вы можете привязать updatetime к pause() воспроизведению за секунду до достижения конца аудио и перемотать его назад перед повторным воспроизведением. Тогда Android не будет сбрасывать звук.

person Adrian Panasiuk    schedule 21.02.2012