自动播放的视频的canvas.drawimage仅在可见视频元素时有效 [英] canvas.drawimage of autoplayed video only works when video element is visible

查看:125
本文介绍了自动播放的视频的canvas.drawimage仅在可见视频元素时有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过将视频绘制到画布上来在视频上放置一些滤镜.问题在于,当视频元素不在视图中时,它将停止绘制.理想情况下,我想一起隐藏视频元素.

I am trying to put some filters on a video by drawing it to a canvas. The problem is that when the video element is not in view it stops drawing. Ideally I would like to hide the video element all together.

我认为这只会影响chrome浏览器. 此外,似乎如果您停止并使用鼠标启动它,问题就会停止.

I think it only affects chrome browsers. Also, It seems like if you stop and start it with the mouse the problem stops.

function drawToCanvas() {
  let vid = document.getElementById('vid1')
  let can = document.getElementById('can1')
  let ctx = can.getContext('2d')
  ctx.drawImage(vid, 0, 0, 400, 224)
  setTimeout(drawToCanvas, 30)
}

document.body.addEventListener("load", drawToCanvas(), false);

html {
  padding: 20px 0;
  background-color: #efefef;
}

body {
  width: 400px;
  padding: 40px;
  margin: 0 auto;
  background: #fff;
  box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.5);
}

video {
  width: 400px;
  display: block;
}

#can1 {
  position: absolute;
  top: calc( 100vh + 100px);
}

<canvas id='can1' height=224px width=400px></canvas>


<video autobuffer controls autoplay muted=true id='vid1'>
  <source id="mp4" src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>
<br> Above is the Video element. 
<br> Below is the Canvas

<br><br><br> Why does the canvas below stop when the video is scrolled out of view
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

推荐答案

是的,当文档不在屏幕中时,它们会暂停附加到文档的静音视频.

Yes, they do pause muted video appended to the document when it's not in screen.

请注意,完全不在文档内部附加此视频不会暴露此现象:

Note that not appending this video at all inside the document will not expose this behavior:

(()=>{
  const vid = document.createElement('video');
  const ctx = document.getElementById('can1')
    .getContext('2d');
    
  ctx.filter = 'sepia(100%)';
  vid.muted = true;
  vid.src = "http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4";
  vid.play().then(anim);

  function anim() {
    requestAnimationFrame(anim);
    ctx.drawImage(vid, 0, 0, 400, 224)
  }
})();

<canvas id='can1' height=224px width=400px></canvas>

因此,如果您确实也需要该视频元素,则可以向原始视频元素提供从屏幕外视频捕获的MediaStream,并将其控件映射到该屏幕外视频.

So if you really need that video element to be there too, you could feed the original video element with a MediaStream captured from an offscreen video and map its controls to this offscreen video.

visibleVid.srcObject = offscreenVid.captureStream();
visibleVid.onpause = e => offscreenVid.pause();
// ...

function begin() {
  const visibleVid = document.getElementById('vid1');
  const offscreenVid = visibleVid.cloneNode(true);
  const can = document.getElementById('can1');
  const ctx = can.getContext('2d');
  ctx.filter = 'sepia(100%)';

  visibleVid.onpause = e => offscreenVid.pause();
  visibleVid.onplaying = e => offscreenVid.play();

  offscreenVid.play().then(() => {
    visibleVid.srcObject = offscreenVid.captureStream ?
      offscreenVid.captureStream() :
      offscreenVid.mozCaptureStream();
    visibleVid.play();
    anim();
  });

  function anim() {
    requestAnimationFrame(anim);
    ctx.drawImage(offscreenVid, 0, 0, 400, 224)
  }
}

onload = begin;

html {
  padding: 20px 0;
  background-color: #efefef;
}

body {
  width: 400px;
  padding: 40px;
  margin: 0 auto;
  background: #fff;
  box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.5);
}

video {
  width: 400px;
  display: block;
}

#can1 {
  position: absolute;
  top: calc( 100vh + 100px);
}

<canvas id='can1' height=224px width=400px></canvas>


<video autobuffer controls autoplay muted=true id='vid1' crossorigin="anonymous">
  <!-- we need a crossorigin safe media -->
  <source id="mp4" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" type="video/mp4">
https://stackoverflow.com/questions/55484353/canvas-drawimage-of-autoplayed-video-only-works-when-video-element-is-visible#</video>
<br> Above is the Video element.
<br> Below is the Canvas

<br><br><br> Why does the canvas below stop when the video is scrolled out of view
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

但这对于浏览器来说是很大的开销,并且您将失去从该元素中进行搜索的可能性(因为它现在提供了流).
因此,如果您确实需要此功能,则还可以考虑在其他画布上进行自己的控件.

But that's a lot of overhead for the browser, and you will loose the possibility to seek from this element (since it now presents a stream).
So if you really need this, you may also consider doing your own controls, over an other canvas.

最后,他们显然只对静音视频执行此操作,因此,如果您可以松开自动播放功能,还可以删除该muted属性并将其音量设置为0:

And finally, they obviously only do this for muted videos, so if you're ok with loosing the autoplay feature, you can also just go with removing that muted attribute and just set its volume to 0:

(() => {
  let vid = document.getElementById('vid1');
  let can = document.getElementById('can1');
  let ctx = can.getContext('2d');

  vid.volume = 0;  // replace muted
  vid.play()
    .catch(() => {
      // in case we're not allowed to play, wait for user approval
      console.log('click anywhere to start playback');
      addEventListener('click',
        e => {console.clear();vid.play()},
        {once:true}
      )
    });
   anim();
   
   function anim() {
    requestAnimationFrame(anim);
    ctx.drawImage(vid, 0, 0, 400, 224)
   }
})();

html {
  padding: 20px 0;
  background-color: #efefef;
}

body {
  width: 400px;
  padding: 40px;
  margin: 0 auto;
  background: #fff;
  box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.5);
}

video {
  width: 400px;
  display: block;
}

#can1 {
  position: absolute;
  top: calc( 100vh + 100px);
}

<canvas id='can1' height=224px width=400px></canvas>


<video autobuffer controls autoplay id='vid1'>
  <source id="mp4" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" type="video/mp4">
</video>
<br> Above is the Video element. 
<br> Below is the Canvas

<br><br><br> Why does the canvas below stop when the video is scrolled out of view
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

这篇关于自动播放的视频的canvas.drawimage仅在可见视频元素时有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆