HTML5 видео: принудительное прекращение буферизации

Как заставить событие отмены в видео HTML5? У меня есть оверлей, где, когда я закрываю его, видео должно приостановить воспроизведение, а затем прекратить буферизацию. Тем не менее, мое интернет-соединение продолжает сходить с ума. О, я использую Chrome 7.0.5 на Mac OS X 10.6.

Я попробовал пару вещей - ни одна из них не сработала:

(Для тех, кто не знаком с XUI, x$ походит на функцию обтекания jQuery)

Во-первых, отправка прерванного события HTML:

var videoEl = x$('#video_el')[0];
videoEl.pause();
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent('abort', false, false);
videoEl.dispatchEvent(evObj);

Затем, изменив src, а затем принудительно загрузив:

var videoEl = x$('#video_el')[0];
videoEl.pause();
videoEl.src = "";
videoEl.load(); //tried with and without this step

РЕДАКТИРОВАТЬ: мой элемент видео выглядит примерно так:

<video id="video_el" src="<video_url>" preload="none" controls="controls" />

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

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

Спасибо!

5 ответов

Решение

Итак, в течение последних нескольких дней я действительно боролся с этой проблемой.
Вот мой анализ и решение:

Короче проблема, которую я пытался решить:
Я заметил, что проигрыватель HTML5 не прекращает загрузку, когда проигрыватель находится в режиме паузы (вообще, даже через разумное количество времени). Работая с аудиопотоком в режиме 24/7 и разрабатывая мобильный веб-сайт, я понял, что это далеко не оптимально для моих посетителей, учитывая интенсивное использование данных, если они оставляют сайт открытым - хотя я думаю, что некоторые операторы будут очень довольны, "пропустив" " Эта проблема...
Просто чтобы прояснить, мне не очень важны файлы с фиксированной длиной. Загрузка полного файла - это в большинстве случаев функциональность, необходимая для просмотра онлайн-ресурсов (например, медленное соединение), поэтому я не пытался это предотвратить.

Анализ:
Аудиоэлемент HTML5 не имеет функции stop() и не имеет опции, в которой вы можете указать объем данных, которые ему разрешено буферизовать, или способ сказать, что вы хотите, чтобы элемент прекратил буферизацию - не путайте это с функцией 'preload', это относится только к элементу до нажатия кнопки воспроизведения.
Я понятия не имею, почему это так и почему эта функциональность недоступна. Если кто-нибудь может объяснить мне, почему эти важные функции не реализованы в стандарте, который должен сделать веб-разработку для мобильных телефонов лучше и стандартизированнее, я бы хотел знать.

Решение:
Единственное рабочее решение, которое я нашел для реализации (вроде) функции остановки в вашем аудиоэлементе, заключается в следующем:
1. Пауза текущего плеера - вы можете подключить событие паузы к плееру через audio.addEventListener ('pause', yourFunction);
2. Установите источник пустым - audio.src = "";
3. Загрузите src - audio.load ();
4. Удалить весь аудио элемент
5. Вставьте новый аудиоэлемент HTML5, не указав источник
6. Установите источник (источник, который был там в первую очередь) - audio.src = "старый источник URL
7. Перезапустите событие паузы - audio.addEventListener('пауза', текущая функция);

Для iOS необходим полный впрыск нового аудиоплеера HTML5. Просто сбросив src и затем загрузив его, в моем случае проигрыватель автоматически запускается...

Для ленивых людей (включая jQuery):

var audio = $("audio").get(0);
audio.pause(0);
var tmp = audio.src;
audio.src = "";
audio.load();
$("audio").remove();

$("#audio-player").html("<audio controls preload='none'></audio>");<br>
audio = $("audio").get(0);
audio.src = tmp;
audio.addEventListener('pause', current-function);

Нажатие паузы приведет к тому, что ваш посетитель потеряет текущее местоположение в аудио / видео файле, и он начнется снова. У меня нет решения этой проблемы. Опять же, если вы имеете дело с прямой трансляцией, это решение должно подойти.

Надеюсь это поможет.

С preload="none", это то, как я принудительно прервал буферизацию после приостановки видео, а затем возобновил воспроизведение в приостановленном месте, используя jQuery.

<video id="video_el" src="<video_url>" preload="none" controls="controls" />    

<script>
jQuery(function() {

  var video = jQuery('video').get(0);

  video.addEventListener('pause',function(){
     var tmp_src = video.src;
     var playtime = video.currentTime;
     video.src = '';
     video.load();
     video.src = tmp_src;
     video.currentTime = playtime;
  });

});
</script>

Ключевой шаг, кажется, не установлен src пустое значение перед вызовом load(), Я имел успех, делая это так:

var wasPlaying = !audioPlayer.paused;
audioPlayer.currentTime = 0.0; // Optional -- can be left out for pause
audioPlayer.pause();

if (wasPlaying) { // This prevents the browser from trying to load the entire source
    audioPlayer.load();
}

Как в Chrome, так и в Firefox на Win10 это вызывает событие прерывания. В моем конкретном случае это было необходимо для закрытия сокетов, которые в противном случае оставались бы открытыми на неопределенный срок, что привело к достижению ограничения в шесть подключений на сервер при использовании нескольких игроков на одной странице.

Смотрите здесь: http://dev.w3.org/html5/spec/video.html

Может быть, вы могли бы установить preload в none?

Если это не сработает: не могли бы вы извлечь его атрибуты, удалить его, вставить новый элемент видео и присвоить этому элементу сохраненные атрибуты?

Вы также можете изменить src на mp3, содержащий одну секунду тишины. Затем вызовите функцию воспроизведения с новым src. По мере загрузки нового mp3 буферизация потока прекращается.

var audio = document.getElementById("audioradio");
audio.src = "/sound/pause.mp3";
audio.play();
<audio style="display: none;" id="audioradio" src="/sound/pause.mp3" preload="none"></audio>

Тестируйте только в Firefox!

На самом деле вы можете сделать то же самое, установив атрибут src как файл php/aspx с некоторыми параметрами для чтения содержимого файла и извлечения данных как эквивалентного типа (например, Content-Type: video/mp4). НО это не работает в IE 11 (какой сюрприз:D), тогда вам нужно будет сделать трюк выше только для этого великолепного браузера.

Использовать этот...

<video id="v1" preload="none">
  <source src="video.php?id=24" type="video/mp4">
</video>

Вместо этого...

<video id="v2" preload="none">
  <source src="video-24.mp4" type="video/mp4">
</video>

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

Я протестировал с помощью Chrome 32, Firefox 26, Opera 18 и IE 11 следующий скрипт

setInterval(function() {
    var r = [];

    try {
        r.push(v1.buffered.end(0));
    } catch(e) {
        r.push('nahh');
    };

    try {
        r.push(v2.buffered.end(0));
    } catch(e) {
        r.push('second nahh');
    };

    console.log(r.join(', '));
}, 500);

В моих локальных тестах...

Firefox 26 После того, как вы нажали кнопку воспроизведения, он ВСЕГДА буферизировал полный файл.

IE 11 (учитывая src="video-24.mp4", потому что другие не работают) После того, как вы нажали кнопку воспроизведения, он ВСЕГДА буферизировал файловый чанк, даже если он был приостановлен, и полностью игнорирует preload="none" приписывать.

Chrome 32 работает отлично (то же самое для Opera 18).

Другие вопросы по тегам