HTML5 视频 - 文件加载完成事件?

Posted

技术标签:

【中文标题】HTML5 视频 - 文件加载完成事件?【英文标题】:HTML5 Video - File Loading Complete Event? 【发布时间】:2011-07-05 12:23:21 【问题描述】:

我需要检测视频文件何时完成加载。我在想我应该使用progress->buffer,但在我的脑海里,我记得读到这是不可靠的。有没有更好的方法,或者这样安全吗?

注意,我将保留每个用户已完全下载的视频的 localStorage 缓存,因此我会提前知道视频是否已经加载,并且可能会绕过进度->缓冲区,如果这是一个症结所在.

提前致谢。

【问题讨论】:

【参考方案1】:

这是一个带有Google's MDC-Web's mdc-linear-progress UI 组件的充实实现。

var doc = document;
var bufferLengthDetector;
var linearProgress;
var mdc = window.mdc;
mdc.autoInit();
var video = doc.querySelector('video');

if(doc.getElementById("footer-progress"))
    linearProgress = mdc.linearProgress.MDCLinearProgress.attachTo(doc.getElementById("footer-progress"));


if(video)
    
    video.addEventListener('timeupdate', function() 
        var percent = Math.floor((100 / video.duration) * video.currentTime);
        linearProgress.progress = percent/100;
    , false);
    
    video.addEventListener('progress', function() 
        var duration = video.duration;
        if (duration > 0) 
            bufferLengthDetector = setInterval(readBuffer, 500);
        
    );


function readBuffer()
    var percent = video.buffered.end(video.buffered.length - 1) / video.duration;
    if (percent >= .9) 
        linearProgress.buffer = 1;
        clearInterval(bufferLengthDetector);
    
    else 
        linearProgress.buffer = percent;
    
html 
    height:100%;

body
    margin: 0;


#footer-progress
    position: fixed;
    bottom: 0;
    width: 100%;
    visibility: visible;
    opacity: 1;    


video 
    position: fixed;
    top: 50%;
    left: 50%;
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    z-index: -100;
    transform: translateX(-50%) translateY(-50%);
    background: #212121;
    background-size: cover;
    transition: visibility 1s, opacity 1s linear;
    visibility: visible;
    opacity: 1;
<head>
<link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
<script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
</head>

<body>

    <video class="bg-video" playsinline autoplay>
        <source src="//rack.pub/media/do-not.webm" type="video/webm">
        <source src="//rack.pub/media/do-not.mp4" type="video/mp4">            
        I'm sorry your browser doesn't support HTML5 video in WebM with VP8/VP9 or MP4 with H.264.
    </video>
    
    <div role="progressbar" class="mdc-linear-progress" data-buffer="true" id="footer-progress">
        <div class="mdc-linear-progress__buffering-dots"></div>
        <div class="mdc-linear-progress__buffer"></div>
        <div class="mdc-linear-progress__bar mdc-linear-progress__primary-bar">
            <span class="mdc-linear-progress__bar-inner"></span>
        </div>
        <div class="mdc-linear-progress__bar mdc-linear-progress__secondary-bar">
            <span class="mdc-linear-progress__bar-inner"></span>
        </div>
    </div>  

</body>

【讨论】:

【参考方案2】:

您可以绑定“缓冲”事件,但是(至少在 Chrome 中)这可以正常工作,只是它不会调用最后一个“缓冲”事件(即它将检测到 90%...94%... 98%...但不会要求 100%)。

注意:最新版本的 jQuery 应该使用 .prop() 而不是 .attr()

为了解决这个问题,我使用 setInterval() 每 500 毫秒检查一次缓冲区(其中 $html5Video 是您的 &lt;video&gt; 元素:

var videoDuration = $html5Video.attr('duration');

var updateProgressBar = function()
    if ($html5Video.attr('readyState')) 
        var buffered = $html5Video.attr("buffered").end(0);
        var percent = 100 * buffered / videoDuration;

        //Your code here

        //If finished buffering buffering quit calling it
        if (buffered >= videoDuration) 
                clearInterval(this.watchBuffer);
        
    
;
var watchBuffer = setInterval(updateProgressBar, 500);

【讨论】:

【参考方案3】:

我遇到了同样的问题,我使用了一个附加到进度事件的计时器。这是一个 hack,但我还没有看到任何其他方法。 (我已经在 Chome 10 - Windows 上对此进行了测试)。

var video = document.getElementById('#example-video-element');
var timer = 0;
video.addEventListener('progress', function (e) 
    if (this.buffered.length > 0) 

        if (timer != 0) 
            clearTimeout(timer);
        

        timer = setTimeout(function ()             
            if(parseInt(video.buffered.end() / video.duration * 100) == 100) 
                // video has loaded.... 
            ;          
        , 1500);

    
, false); 

这看起来像您正在考虑采用的方法类型,但我想我会为那些可能正在寻找快速代码示例的匿名用户发布一个示例 =p GJ

【讨论】:

以上是关于HTML5 视频 - 文件加载完成事件?的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 视频加载数据事件在 IOS Safari 中不起作用

当视频更改而不重新加载页面时,HTML5 视频元素缺少 END 事件

在页面的其余部分完成加载后延迟加载 html5 视频

HTML5视频加载完成后如何使文本消失?

javascript中的HTML5视频完整预加载

HTML5 new Image() 图像需要加载后才能drawImage? 怎样保证多个Image对象都加载完成?