【问题标题】:Play full HTML5 video and then loop a section of it播放完整的 HTML5 视频,然后循环播放其中的一部分
【发布时间】:2014-01-21 07:37:47
【问题描述】:

我尝试完整播放一次 8.6 秒的视频,然后无限循环播放一小部分视频,以保持视频永无止境的错觉。到目前为止,我已经查看了视频的media fragments URIended 事件。在结束的事件监听器中设置 currentTime 属性是可行的,但它会使视频“闪烁”。

目前,我正在使用 timeupdate 事件侦听器来更改视频接近结束的时间[如下所示]

elem.addEventListener('timeupdate', function () {
if (elem.currentTime >= 8.5) {
    elem.currentTime = 5;
    elem.play();
}
}, false);

JSFiddle here

这也有效,但视频在 5 秒重新开始之前明显暂停。有没有更流畅的方式来播放视频,然后循环播放一段视频?

【问题讨论】:

    标签: javascript html video


    【解决方案1】:

    您的代码没问题,问题出在您的 MP4 文件上!尝试使用像这样的小得多的视频 (http://www.w3schools.com/tags/movie.mp4) 来确认问题不在于您的代码。

    那么,如何才能在视频文件较大的情况下获得相同的结果? 您将需要两个视频文件:

    • video1 为主视频
    • video2 是循环播放的视频

    记住:HTML5视频播放和循环播放大视频文件没有问题,所以我们将使用这种方法来播放视频。

    在下面的示例中,我们将播放第一个视频,当它结束时,我们将执行一个函数来隐藏 video1,然后显示/播放 video2。 (视频 2 已设置为循环播放)

    不要忘记在脑海中加载 JQuery,否则这将不起作用。

    <video id="video1" width="1080" height="568" poster="movie.png" autoplay onended="run()">
      <source src="movie.webm" type="video/webm">
      <source src="movie.ogg" type="video/ogg">
      <source src="movie.mp4" type="video/mp4">
      <object data="movie.mp4" width="1080" height="568">
        <embed width="1080" height="568" src="movie.swf">
      </object>
    Optional test to be displayed if the browser doesn't support the video tag (HTML 5)
    </video>
    
    
    <video id="video2" width="1080" height="568" poster="loop.png" loop>
      <source src="loop.webm" type="video/webm">
      <source src="loop.ogg" type="video/ogg">
      <source src="loop.mp4" type="video/mp4">
      <object data="loop.mp4" width="1080" height="568">
        <embed width="1080" height="568" src="loop.swf">
      </object>
    Optional test to be displayed if the browser doesn't support the video tag (HTML 5)
    </video>
    
    
    <script> 
    $( "#video2" ).hide();
    function run(){
       $( "#video1" ).hide();
        $( "#video2" ).show();
        document.getElementById("video2").play();
       };
    </script> 
    

    【讨论】:

      【解决方案2】:

      尝试以下操作,以便在结束后立即“倒带”:

      vidElem.addEventListener("ended", function () {
              vidElem.currentTime = 2.5;
              vidElem.play();
      }, false);
      

      更新小提琴:http://jsfiddle.net/Lt4n7/1/

      【讨论】:

      • 谢谢,但我已经尝试过使用结束的事件监听器。也许那是使用错误的示例视频(它有自己的暂停),但在视频移动到 2.5 秒之前有一个明显的暂停。我希望使循环无缝。
      • 试着把它分成两个视频
      • 你的意思是一个完整的视频和一个我想循环播放的视频?好像很浪费! got 是一种 HTML5+JS 方式! :)
      • 只是视频到您要循环播放的部分。如果您可以使用可循环的示例创建一个小提琴,那也会有很大帮助
      • 仅供参考,这不适用于某些视频,因为有时浏览器无法更改 currentTime 并立即播放,因此每个循环之间会有延迟。 Using two videos(可悲的是)更可靠。
      【解决方案3】:

      我只需要处理同样的问题,并注意到闪烁的同样问题。这是我的解决方案:

      • 获取 2 个视频(或视频集) - 一个用于非循环部分,另一个用于循环部分
      • 创建 2 个视频元素
      • 将循环元素设置为“display:none”

      然后只捕获结束的事件并交换显示状态(示例使用 jquery,但您可以很容易地使用 'style.display="none/block"':

      VideoPlayer1 = document.getElementById('video1');
      VideoPlayer2 = document.getElementById('video2');
      VideoPlayer1.addEventListener('ended', videoLooper, false);
      
      function videoLooper()
      {
          VideoPlayer2.play();
          $(VideoPlayer2).show();
          $(VideoPlayer1).hide();
      }
      

      【讨论】:

        【解决方案4】:

        您无法在 javascript 中解决此问题。您看到的延迟取决于视频压缩和硬件。

        要在非 0 的时间开始播放,视频解码器必须返回并找到 key frame,然后通过读取最后一个关键帧和您选择的时间之间的所有内容来构建当前帧。

        我不是视频压缩方面的专家,但也许有一种方法可以挑选这些关键帧并将它们准确地放置在您需要的位置。不过,我认为这不会轻松顺利。


        如果您正在寻找更简单的解决方案,请使用 @Random's,但它使用两个 &lt;video&gt; 标签来解决此限制。

        【讨论】:

          【解决方案5】:

          var iterations = 1;
          var flag = false;
          document.getElementById('iteration').innerText = iterations;
          var myVideo = document.getElementById('video-background');
          myVideo.addEventListener('ended', function() {
            alert('end');
            if (iterations < 2) {
              this.currentTime = 0;
              this.play();
              iterations++;
              document.getElementById('iteration').innerText = iterations;
            } else {
              flag = true;
              this.play();
            }
          }, false);
          myVideo.addEventListener('timeupdate', function() {
            if (flag == true) {
              console.log(this.currentTime);
              if (this.currentTime > 5.5) {
                console.log(this.currentTime);
                this.pause();
              }
            }
          }, false);
          <div>Iteration: <span id="iteration"></span></div>
          
          <video id="video-background" autoplay="" muted="" controls>
                      <source src="https://res.cloudinary.com/video/upload/ac_none,q_60/bgvid.mp4" type="video/mp4">
              </video>
          <div>Iteration: <span id="iteration"></span></div>

          // 请注意,loop 属性不应该存在于 video 元素中,以便 'ended' 事件在 ie 和 firefox 中起作用

          【讨论】:

          • 请在此处查看参考jsfiddle.net/dxpkumar/fuqmfde8
          • 虽然此代码 sn-p 可能是正确的解决方案,但 including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议背后的原因。另外,请添加答案本身的链接,而不是作为评论。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-16
          • 2016-03-18
          • 1970-01-01
          • 2012-05-30
          • 2013-03-03
          • 1970-01-01
          • 2017-09-21
          相关资源
          最近更新 更多