canvas.drawimage 的自动播放视频仅在视频元素可见时有效
canvas.drawimage of autoplayed video only works when video element is visible
我试图通过将视频绘制到 canvas 来在视频上添加一些滤镜。问题是,当视频元素不在视图中时,它会停止绘制。理想情况下,我想一起隐藏视频元素。
我认为它只影响 chrome 浏览器。
此外,似乎如果您停止并用鼠标启动它,问题就会停止。
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>
是的,当文档不在屏幕上时,他们会暂停附加到文档的静音视频。
请注意,根本不在文档中附加此视频不会暴露此行为:
(()=>{
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,并将其控件映射到该屏幕外视频。
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">
<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.
最后,他们显然只对静音视频执行此操作,因此如果您可以放弃自动播放功能,您也可以删除 muted
属性并将其音量设置为 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 来在视频上添加一些滤镜。问题是,当视频元素不在视图中时,它会停止绘制。理想情况下,我想一起隐藏视频元素。
我认为它只影响 chrome 浏览器。 此外,似乎如果您停止并用鼠标启动它,问题就会停止。
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>
是的,当文档不在屏幕上时,他们会暂停附加到文档的静音视频。
请注意,根本不在文档中附加此视频不会暴露此行为:
(()=>{
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,并将其控件映射到该屏幕外视频。
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">
<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.
最后,他们显然只对静音视频执行此操作,因此如果您可以放弃自动播放功能,您也可以删除 muted
属性并将其音量设置为 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>