【问题标题】:Best way to capture paused video frame to canvas将暂停的视频帧捕获到画布的最佳方法
【发布时间】:2018-10-04 04:04:48
【问题描述】:

我知道如何使用 2D 上下文逐帧从正在播放的 HTML5 视频复制到画布。

但我想处理暂停的视频,动态更改其currentTime 并将当前视频帧复制到画布。

我的猜测是,当使用 currentTime 属性设置视频位置时,尚未调用某些过程,尽管视频本身确实会更新它显示的图像(但不会更新到画布)。

我发现可以通过设置 setTimeout 在下一步中执行画布“drawImage”来克服这个问题。

You can see here a jsfiddle that proves the point.

正如您在小提琴中看到的,您可以播放视频和画布更新,但如果您暂停视频,鼠标滚动会移动视频的currentTime。在那里,需要一个“seTimeout”来更新画布,如果我直接调用drawImage 方法,画布不会更新。

简而言之,我的问题是:

有没有更好的方法来做到这一点?是否可以在没有 setTimeout 和内部循环本身的情况下执行此操作?利弊?

非常感谢您阅读这里!

【问题讨论】:

    标签: javascript scroll html5-canvas html5-video pause


    【解决方案1】:

    每次更改 VideoElement 的 currentTime 时,都会在视频实际更改其位置时触发 seeked 事件。

    var vid = document.getElementById("v");
    var canvas = document.getElementById("c");
    var context = canvas.getContext('2d');
    var targetFrame = document.getElementById('t');
    var cw = canvas.width = 200;
    var ch = canvas.height = Math.round(cw / 1.7777);
    var targetOffset = 0;
    
    window.addEventListener('wheel', function(e) {
      e.preventDefault();
      targetOffset = targetOffset + (e.deltaY / 1000);
      targetFrame.value = targetOffset;
      seek(); // for demo purpose, we only listen to wheel
      return false;
    });
    // that's all is needed
    vid.addEventListener('seeked', function() {
      context.drawImage(vid, 0, 0, cw, ch);
    });
    // for demo
    // removed the rendering loop
    // now it only changes the video's currentTime property
    function seek() {
      targetOffset = targetOffset * 0.9;
      targetFrame.value = Math.round(targetOffset * 100) / 100;
      var vct = vid.currentTime - targetOffset;
      if (vct < 0) {
        vct = vid.duration + vct;
      } else if (vct > vid.duration) {
        vct = vct - vid.duration;
      }
      vid.currentTime = vct;
    }
    .column {
      float: left;
      width: 50%;
    }
    .row:after {
      content: "";
      display: table;
      clear: both;
    }
    #c {
      border: 1px solid black;
    }
    <h3>
      scroll up is forward
    </h3>
    <div class="row">
      <div class="column">
        <div>
          Video element:
        </div>
        <video controls height="120" id="v" tabindex="-1" autobuffer="auto" preload="auto">
        <source type="video/webm" src="https://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.webm"/>
    </video>
      </div>
      <div class="column">
        <div>
          Canvas element:
        </div>
        <canvas id="c"></canvas>
        <div>
          Momentum: <input type=text id="t">
        </div>
      </div>
    </div>

    【讨论】:

    • 非常感谢!这刚刚解决了我的问题!我只添加了vid.addEventListener('seeked', function() { context.drawImage(vid, 0, 0, cw, ch); }); 并将其他所有内容都保留在循环中,如this fiddle 所示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 2011-08-05
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多