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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5138077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 16:06:32  来源:igfitidea点击:

HTML5 Video - File Loading Complete Event?

javascripthtmlvideobufferpreload

提问by Matrym

I need to detect when a video file has completed loading. I'm thinking I should use progress->buffer, but in the back of my mind, I remember reading that this was unreliable. Is there a better way, or is this safe?

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

Note, I will be keeping a localStorage cache of videos that have been completely downloaded by each user, so I'll know in advance if a video has already loaded, and could probably bypass progress->buffer if that's a sticking point.

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

Thanks in advance.

提前致谢。

回答by bcoughlan

You can bind the "buffered" event, but (in Chrome at least) this works fine except that it doesn't call the last "buffered" event (i.e. it will detect 90%...94%...98%... but won't call on 100%).

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

Note: recent versions of jQuery should use .prop() instead of .attr()

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

To get around this I've used setInterval() to check the buffer every 500ms (where $html5Video is your <video>element:

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

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

回答by CameraSchoolDropout

I've had the same problem and use a timer attached to the progress event. It's a hack but I haven't seen any other ways of doing this. (I've tested this on Chome 10 - Windows).

我遇到了同样的问题,并使用了附加到进度事件的计时器。这是一个黑客,但我还没有看到任何其他方法可以做到这一点。(我已经在 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); 

This looks like the type of approach you were thinking of taking, but figured I would post an example for those anonymous users who might be looking for a quick code sample =p
GJ

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

回答by Ronnie Royston

Here's a fleshed out implementation with Google's MDC-Web's mdc-linear-progressUI component.

这是Google 的 MDC-Web 的 mdc-linear-progressUI 组件的充实实现。

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>