HTML5 Video - File Loading Complete Event?

前端 未结 3 1820
广开言路
广开言路 2020-12-23 18:20

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 unreliabl

相关标签:
3条回答
  • 2020-12-23 18:38

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

    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>

    0 讨论(0)
  • 2020-12-23 18:44

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

    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

    0 讨论(0)
  • 2020-12-23 18:53

    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%).

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

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

    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);
    
    0 讨论(0)
提交回复
热议问题