Я пытаюсь проверить, является ли видео прерывистым. Я заметил, что событие pause
не запускается, когда видео приостанавливается для буферизации. Каков наилучший способ определить, приостановлено ли видео для буферизации?
Как определить, приостановлено ли видео в формате HTML5 для буферизации?
Ответ 1
Я сделал это, проверив ход игрока каждые х миллисекунд, например. 50. Если игрок не продвинулся так сильно, как ожидалось, мы будем буферизировать. Это довольно надежно, так как я обнаружил, что другие события, такие как waiting
или stalled
, не запускаются во всех случаях буферизации видео.
Обратите внимание, что интервал должен быть больше ожидаемой межкадровой разницы, но я уверен, что вы не захотите быть таким точным в любом случае. Оценка времени буферизации в пределах ± 300 мс будет по-прежнему прекрасной, учитывая, что люди, скорее всего, не могут воспринимать различия в этом регионе.
Важно проверить, не активировал ли пользователь приостановку воспроизведения.
var checkInterval = 50.0 // check every 50 ms (do not use lower values)
var lastPlayPos = 0
var currentPlayPos = 0
var bufferingDetected = false
var player = document.getElementById('videoPlayer')
setInterval(checkBuffering, checkInterval)
function checkBuffering() {
currentPlayPos = player.currentTime
// checking offset should be at most the check interval
// but allow for some margin
var offset = (checkInterval - 20) / 1000
// if no buffering is currently detected,
// and the position does not seem to increase
// and the player isn't manually paused...
if (
!bufferingDetected
&& currentPlayPos < (lastPlayPos + offset)
&& !player.paused
) {
console.log("buffering")
bufferingDetected = true
}
// if we were buffering but the player has advanced,
// then there is no buffering
if (
bufferingDetected
&& currentPlayPos > (lastPlayPos + offset)
&& !player.paused
) {
console.log("not buffering anymore")
bufferingDetected = false
}
lastPlayPos = currentPlayPos
}
Ответ 2
Событие, которое вы ищете, это waiting
.
Из spec:
Ожидающее событие DOM может быть запущено в результате элемента, который потенциально воспроизведение остановки воспроизведения из-за его атрибута readyState изменяя значение ниже HAVE_FUTURE_DATA.
Состояние paused
не изменяется, потому что видео по-прежнему "потенциально играет" (т.е. "пытается" воспроизвести). Таким образом происходит событие waiting
. Когда загружено достаточно данных, срабатывает playing
.
Вы также можете проверить состояние в любое время, просмотрев два свойства, networkState и readyState
if (video.networkState === video.NETWORK_LOADING) {
// The user agent is actively trying to download data.
}
if (video.readyState < video.HAVE_FUTURE_DATA) {
// There is not enough data to keep playing from this point
}
Ответ 3
Вы можете просто проверить длину буферизованного видеоконтента и, если он меньше, чем текущая часть воспроизведения, а затем просто запустить событие паузы. Используя следующий код, вы можете проверить длину буферизованного видео.
$vid = $("#video_id");
$vid.on('progress', function(e) {
percentVidLoaded = null;
// FF4+, Chrome
if ($vid[0] && $vid[0].buffered && $vid[0].buffered.length > 0 && $vid[0].buffered.end && $vid[0].duration) {
percentVidLoaded = $vid[0].buffered.end(0) / $vid[0].duration;
}
/* Some browsers (e.g., FF3.6 and Safari 5) cannot calculate target.bufferered.end()
* to be anything other than 0. If the byte count is available we use this instead.
* Browsers that support the else if do not seem to have the bufferedBytes value and
* should skip to there.
*/
else if ($vid[0] && $vid[0].bytesTotal != undefined && $vid[0].bytesTotal > 0 && $vid[0].bufferedBytes != undefined) {
percentVidLoaded = $vid[0].bufferedBytes / $vid[0].bytesTotal;
}
if (percentVidLoaded !== null) {
percentVidLoaded = 100 * Math.min(1, Math.max(0, percentVidLoaded));
}
});
Ответ 4
Вам нужно проверить, меньше ли время в буфере. Если это так, то видео буферизуется. Однако вы должны проверить это с небольшим допуском, чтобы убедиться, что вы обнаружите его, прежде чем он будет необходим для буфера.
Пример:
var video = document.getElementById("myVideo");
var prevBuffer = {
"buffer": null,
"time": null
};
var isBuffering = function(){
if(video && video.buffered && video.buffered.end && video.buffered.length > 0){
var buffer = video.buffered.end(0);
var time = video.currentTime;
// Check if the video hangs because of issues with e.g. performance
if(prevBuffer.buffer === buffer && prevBuffer.time === time && !video.paused){
return true;
}
prevBuffer = {
"buffer": buffer,
"time": time
};
// Check if video buffer is less
// than current time (tolerance 3 sec)
if((buffer - 3) < time){
return true;
}
}
return false;
};
video.addEventListener("play", function(e){
// Make sure this handler is only called once
e.target.removeEventListener(e.type, arguments.callee);
// Give browsers 3secs time to buffer
setTimeout(function(){
// As "progress", "stalled" or "waiting" aren't fired
// reliable, we need to use an interval
var interval = setInterval(function(){
if(isBuffering()){
clearInterval(interval);
console.log("Buffering");
}
}, 500);
}, 3000);
});