HTML5 Видео буферная зона атрибут
Я разрабатываю пользовательский HTML5
видео-плеером. Таким образом, у него будет свой собственный слайдер для имитации прогресса видео, поэтому мне нужно понять всю буферизацию shebang HTML5
видео.
я наткнулся на эту статью:Буферизация Видео. Он говорит, что буферизованный объект состоит из нескольких временных диапазонов в линейном порядке времени начала. Но я не смог выяснить следующее:--5-->
говорят, что видео начинается. Он продолжается до 1:45 сам по себе (иногда, возможно, тянет время, ожидая дальнейших данных), после чего я внезапно перескакиваю на 32:45. Теперь через некоторое время, если я вернусь к 1:27 (в диапазоне времени, первоначально загруженном и воспроизведенном до того, как я сделал прыжок), он начнет играть сразу, как он был уже загружен раньше? Или это потому, что с тех пор, как я сделал прыжок, эта часть потеряна и ее нужно будет снова принести? В любом случае, является ли поведение последовательным для всех таких сценариев?
Сказать, Что Я сделайте 5 или 6 таких прыжков, каждый раз ожидая несколько секунд загрузки некоторых данных после прыжка. Означает ли это
buffered
объект будет иметь все эти временные диапазоны? Или некоторые могут потеряться? Это что-то вроде стека, где более ранние диапазоны будут выскакивать, когда больше диапазонов загружаются из-за дальнейших прыжков?будет ли проверка
buffered
объект имеет один временной диапазон, начинающийся с 0 (забудьте прямую трансляцию) и заканчивающийся на длине продолжительности видео что весь видео ресурс полностью загружен? Если нет, есть ли способ узнать, что все видео было загружено, и любая часть доступна для поиска, из которой видео может воспроизводиться непрерывно до конца без задержки?
спецификации W3C не очень ясны в этом, и я также не могу найти подходящий большой (скажем, более часа) удаленный видеоресурс для тестирования.
4 ответов
как видео буферизуется, зависит от реализации браузера, и поэтому может варьироваться от браузера к браузеру.
различные браузеры могут использовать различные факторы, чтобы определить, чтобы сохранить или отбросить часть буфера. Типичными факторами являются старые сегменты, дисковое пространство, память и производительность.
единственный способ действительно узнать - "увидеть", что браузер имеет или загружается.
для этого я сделал buffer-viewer, который показывает, какая часть находится в буфере. Зритель покажет текущий и все части всего буфера:
например-в Chrome я играл несколько секунд, затем я пропустил около 30 секунд, и вы можете видеть, что он начинает загружать другую часть, начиная с этой позиции.
(буфер также, похоже, ограничен ключевыми кадрами, поэтому можно декодировать n-кадры в этом буфере. Это означает, что буфер может начать загружать данные немного раньше фактическое положение.)
Я предоставил демо-видео длиной около 1 минуты-однако этого недостаточно для надлежащего тестирования. Бесплатно бесплатно предоставлять ссылки на видео, содержащие более длинное видео (или, пожалуйста, поделитесь, если вы хотите, чтобы я обновил демо с этим).
основная функция будет проходить через buffered
объект на элементе video. Он отобразит все части, которые существуют на холсте прямо под видео, показанным красным цветом.
Вы можете нажмите (бит не перетащить) на этом средстве просмотра, чтобы переместить видео в разные позиции.
/// buffer viewer loop (updates about every 2nd frame)
function loop() {
var b = vid.buffered, /// get buffer object
i = b.length, /// counter for loop
w = canvas.width, /// cache canvas width and height
h = canvas.height,
vl = vid.duration, /// total video duration in seconds
x1, x2; /// buffer segment mark positions
/// clear canvas with black
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, w, h);
/// red color for loaded buffer(s)
ctx.fillStyle = '#d00';
/// iterate through buffers
while (i--) {
x1 = b.start(i) / vl * w;
x2 = b.end(i) / vl * w;
ctx.fillRect(x1, 0, x2 - x1, h);
}
/// draw info
ctx.fillStyle = '#fff';
ctx.textBaseline = 'top';
ctx.textAlign = 'left';
ctx.fillText(vid.currentTime.toFixed(1), 4, 4);
ctx.textAlign = 'right';
ctx.fillText(vl.toFixed(1), w - 4, 4);
/// draw cursor for position
x1 = vid.currentTime / vl * w;
ctx.beginPath();
ctx.arc(x1, h * 0.5, 7, 0, 2 * Math.PI);
ctx.fill();
setTimeout(loop, 29);
}
по данным
- https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
- https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
- https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges.start
на buffered
атрибут содержит информацию обо всех текущих буферизованных диапазонах времени. Насколько я понимаю, если буферизованная часть потеряна, она удаляется от объекта (в случае, если это когда-либо произойдет).
Esepcially последняя ссылка кажется очень полезной для понимания этого вопроса (поскольку она предлагает образец кода), но имейте в виду, что это документы mozilla, и поддержка может отличаться в других браузерах.
ответить
говорят, что видео начинается. Он продолжается до 1:45 самостоятельно (иногда, возможно, тянет время, ожидая дальнейших данных), после чего я внезапно перескакиваю на 32:45. Сейчас через некоторое время, если я вернусь к 1:27 (в диапазоне времени, первоначально загруженном и воспроизведенном до того, как я сделал прыжок), он начнет играть сразу, как он был уже загружен раньше?
Это должны играть сразу при прыжке назад, если буфер этой части не был выгружен. Я думаю, что очень разумно предположить, что буферы или диапазоны буферов выгружаются в какой-то момент, если общий размер буфера превышает определенный объем.
скажем, я делаю 5 или 6 таких прыжков, каждый раз ожидая несколько секунд для загрузки некоторых данных после прыжка. Означает ли это, что буферизованный объект будет иметь все эти диапазоны времени?
Да, все буферизованные диапазоны должны быть читаемы через атрибут.
будет проверять, имеет ли буферизованный объект один временной диапазон, начинающийся с 0 (забудьте прямую трансляцию) и заканчивающийся на длине продолжительности видео, убедитесь, что весь видеоресурс был полностью заряжен?
Да, это пример кода в последней ссылке. По-видимому, это применимый метод определения того, было ли загружено все видео.
if (buf.start(0) == 0 && buf.end(0) == v.duration)
почти каждый браузер сохраняет буферизованные данные в кэше для этого сеанса. Кэш истекает после того, как пользователь уходит с этой страницы. Я не думаю, что пользователю придется загрузить страницу каждый раз, когда он загружает видео, когда видео было загружено. Пользователь столкнется с этой проблемой только тогда, когда сервер очищает все данные кэша. HTML5 video tag будет поддерживать это и сохранит видео до точки, где оно было нагруженный.
это не означает, что сеанс был потерян, это означает, что либо объект (если вы используете flash player) ищет некоторые данные из этой конкретной точки или видео тег html5 имеет некоторые проблемы либо из-за сбоя подключения к интернету, или некоторые другие ошибки сервера.
метаданные автоматически загружаются, пока вы не используете это
<audio preload="none"...
Это заставит браузер ничего не загружать с сервера, вы может использовать его как:<audio preload="auto|metadata|none"...
Если вы используете none, ничего не загружается, если пользователь не нажмет кнопку воспроизведения, и метаданные будут загружать имя, время и другие метаданные с сервера, но не файл каким-то образом, auto начнет загрузку, как только страница загрузится.
Я всегда буду направлять вас, чтобы прочитать некоторые документы jQuery. Поскольку jQuery позволит вам изменять и обновлять контент с помощью ajax API, он также будет полезен. Надеюсь, вам это удастся! Овации.
хотя описание принятого ответа отличное, я решил обновить его образец кода по нескольким причинам:
- задача визуализации прогресса действительно должна быть запущена только на
progress
событие. - задача визуализации прогресса смешивается с некоторыми другими задачами, такими как рисование метки времени и позиции playhead.
- код ссылается на несколько элементов DOM по их идентификаторам без использования
document.getElementById()
. - имена переменных были все затемненный.
- Я думал вперед
for()
петля была более элегантной, чем обратнаяwhile()
петли.
обратите внимание, что я удалил playhead и отметку времени, чтобы сохранить код чистым, так как этот ответ фокусируется исключительно на визуализации видеобуфера.
ССЫЛКА НА ОНЛАЙН ВИДЕО БУФЕР ВИЗУАЛИЗАТОР
переписать принятый ответ loop()
функция:
function drawProgress(canvas, buffered, duration){
// I've turned off anti-aliasing since we're just drawing rectangles.
var context = canvas.getContext('2d', { antialias: false });
context.fillStyle = 'blue';
var width = canvas.width;
var height = canvas.height;
if(!width || !height) throw "Canvas's width or height weren't set!";
context.clearRect(0, 0, width, height); // clear canvas
for(var i = 0; i < buffered.length; i++){
var leadingEdge = buffered.start(i) / duration * width;
var trailingEdge = buffered.end(i) / duration * width;
context.fillRect(leadingEdge, 0, trailingEdge - leadingEdge, height);
}
}