Мерцание видео внутри холста HTML при цикле - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь отобразить видео внутри 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 здесь

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Это потому, что зацикливание MediaElement никогда не бывает бесшовной операцией.Это особенно слышно, когда зацикливает аудио мультимедиа .

Обычно, когда воспроизводится в , мы не видим его, потому что браузер просто приостанавливает рендеринг видео на этот короткий промежуток времени.и наш мозг просто игнорирует те несколько кадров, которые приостановлены и концентрируются скорее на всех тех, которые действительно движутся.

Тем не менее, в вашем случае он становится очень заметным, потому что вы все равно очищаете холст, но поверх него нет рамки для рисования.Таким образом, это вызывает большую белую вспышку.

Простое исправление - проверить, является ли 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; }

Более сложное решение, если вам действительно нужно выполнить цикл без шва, - это использовать MediaSource объект, но если он действительно не нужен, установить его немного громоздко.

0 голосов
/ 20 февраля 2019

Вы можете установить для 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();

thisВот почему ваше видео мерцает, оно не зацикливается, оно просто воспроизводится снова и снова.попробуй;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...