循环时HTML画布内的视频闪烁

问题描述 投票:1回答:2

我试图在canvasloop视频中显示视频。在循环播放视频时有时会出现此问题。在再次播放视频之前,视频闪烁一帧。这不会一直发生,我不知道发生了什么。

这是代码

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

javascript html5 canvas video
2个回答
2
投票

这是因为循环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对象,但如果不是真的需要,那么设置到位有点麻烦。


0
投票

您可以将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();

这就是为什么你的视频闪烁,它不循环,它只是一次又一次地重播。试试看 ;)

© www.soinside.com 2019 - 2024. All rights reserved.