如何检测HTML5视频是否暂停缓冲?

时间:2014-01-28 07:56:55

标签: javascript html5 html5-video

我正在尝试测试视频是否不稳定。我注意到,当视频暂停缓冲时,不会触发pause事件。检测视频是否暂停缓冲的最佳方法是什么?

5 个答案:

答案 0 :(得分:43)

我通过每隔 x 毫秒检查玩家进度来做到这一点,例如50.如果玩家没有达到预期的那么高,那么我们就是在缓冲。这非常可靠,因为我发现在视频缓冲的所有情况下都不会触发waitingstalled等其他事件。

请注意,间隔必须大于预期的帧间差异,但我确信你不会想要那么精确。考虑到人类很可能无法察觉该区域的差异,估计在±300ms内的缓冲时间仍然可以。

重要的是检查用户是否还没有主动暂停播放。

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
}

答案 1 :(得分:18)

您正在寻找的事件是waiting

来自spec

  

由于元素的原因,可以触发等待的DOM事件   由于其readyState属性,可能会播放停止播放   更改为低于HAVE_FUTURE_DATA的值。

paused状态不会改变,因为视频仍然“正在播放”(即“尝试”播放)。所以waiting事件会触发。加载了足够的数据后,playing将会触发。

您还可以通过查看两个属性networkStatereadyState

随时查看状态
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
}

答案 2 :(得分:1)

您可以检查缓冲的视频内容长度,如果它小于当前播放部分,则只需触发暂停事件。使用以下代码可以检查缓冲的视频长度。

$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));
    }
});

答案 3 :(得分:0)

您需要检查缓冲区是否小于当前视频时间。如果是这样,那么视频就是缓冲。但是,您应该以较小的容差检查它,以确保在需要缓冲之前检测它。

示例:

repo

答案 4 :(得分:0)

根据MDN文档的“正在等待”事件-

  

当请求的操作(例如播放)被延迟以等待另一个操作(例如搜寻)完成时发送。

因此,搜索或网络请求将触发“等待”。迈克尔在评论中确实指出,``等待''到2019年为止是可靠的,所以我尝试了一下,它奏效了!

"