我试图在canvas
和loop
视频中显示视频。在循环播放视频时有时会出现此问题。在再次播放视频之前,视频闪烁一帧。这不会一直发生,我不知道发生了什么。
这是代码
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let src = "https://i.imgur.com/5ZiAeSX.mp4";
let video = document.createElement("video");
video.src = src;
video.muted = true;
video.play();
video.onended = () => {
video.play();
};
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(video, 0, 0);
requestAnimationFrame(render);
}
render();
您也可以尝试fiddle
here
这是因为循环MediaElement永远不是一个无缝操作。当looping audio media时,这尤其可听见。
通常情况下,当我在<video>中播放时,我们看不到它,因为浏览器只是暂停了这段时间的视频渲染,而我们的大脑只是忽略了暂停的几帧,而是集中精力于所有那些移动。
但是,在你的情况下,它变得非常明显,因为你无论如何都要清除画布,但是没有可以在它上面绘制的视频帧。所以它会导致大的白色闪光。
一个简单的解决方法是检查currentTime
是否是0
并且在此期间不重绘:
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let src = "https://i.imgur.com/5ZiAeSX.mp4";
let video = document.createElement("video");
video.src = src;
video.muted = true;
video.play();
let missed_frames = 0; // only for demo
video.onended = () => {
video.play();
// only for demo
setTimeout(() => {
_log.textContent = 'missed ' + missed_frames +' frames while looping';
missed_frames = 0;
}, 200);
};
function render() {
if(video.currentTime) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
}
// only for demo
else {
missed_frames++;
}
requestAnimationFrame(render);
}
render();
#_log { color: white; position: absolute; }
<pre id="_log"></pre>
<canvas></canvas>
如果你真的需要无缝循环,那么更难修复就是使用MediaSource对象,但如果不是真的需要,那么设置到位有点麻烦。
您可以将viedo.loop设置为true,并在您要求视频继续播放时避开该部分。
我这样做了伎俩:
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let src = "https://i.imgur.com/5ZiAeSX.mp4";
let video = document.createElement("video");
video.src = src;
video.muted = true;
video.videoHeight = '500px'; // returns the intrinsic height of the video
video.videoWidth = '100px'; // returns the intrinsic width of the video
video.play();
video.loop = true
/* video.onended = () => {
video.play();
}; */
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(video, 0, 0);
requestAnimationFrame(render);
}
render();
这就是为什么你的视频闪烁,它不循环,它只是一次又一次地重播。试试看 ;)