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

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

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

提前致谢。

【问题讨论】:

    标签: javascript html video buffer preload


    【解决方案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

        【讨论】:

          猜你喜欢
          • 2015-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-13
          • 2012-11-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多