Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Playing video on HTML Canvas

I'm trying to play a video to HTML Canvas. Am having no issues except when I attempt to hide the video source and only display canvas. In this case I just get a 'white screen'. If the video element isn't hidden everything works as expected. I don't want to display the video element and the canvas element, I only want to display the canvas element that has the video feed 'streaming' to it. Any suggestions? Code example attached...

let sourcevideo = document.getElementById("sourcevideo");
let outputcanvas = document.getElementById("outputcanvas");
let canvasctx = outputcanvas.getContext("2d");

function initCanvas() {
  outputcanvas.width = sourcevideo.videoWidth;
  outputcanvas.height = sourcevideo.videoHeight;
  console.log(outputcanvas.width, outputcanvas.height);
  drawVideo();
}

function drawVideo() {
  canvasctx.drawImage(
    sourcevideo,
    0,
    0,
    outputcanvas.width,
    outputcanvas.height
  );
  requestAnimationFrame(drawVideo);
}

sourcevideo.addEventListener("loadeddata", initCanvas);
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body>
  <div id="videocontainer">
    <video id="sourcevideo" controls src="https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c4/Physicsworks.ogv/Physicsworks.ogv.240p.vp9.webm"></video>
  </div>
  <canvas id="outputcanvas"></canvas>
</body>

</html>
like image 532
Artemis J Avatar asked Sep 15 '25 08:09

Artemis J


2 Answers

First, hide the visibility of your video container using this $('#sourcevideo').css('visibility', 'hidden'); then you will see a still image, to prevent that use autoplay="autoplay", by doing this your video element will hide also you canvas will properly run the video.

let sourcevideo = document.getElementById("sourcevideo");
let outputcanvas = document.getElementById("outputcanvas");
let canvasctx = outputcanvas.getContext("2d");

function initCanvas() {
  outputcanvas.width = sourcevideo.videoWidth;
  outputcanvas.height = sourcevideo.videoHeight;
  console.log(outputcanvas.width, outputcanvas.height);
  drawVideo();
}

function drawVideo() {
  canvasctx.drawImage(
    sourcevideo,
    0,
    0,
    outputcanvas.width,
    outputcanvas.height
  );
  requestAnimationFrame(drawVideo);
}
sourcevideo.addEventListener("loadeddata", initCanvas);
sourcevideo.style.visibility = 'hidden';
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body>
  <div>
    <canvas id="outputcanvas"></canvas>
  </div>
  <div id="videocontainer">
    <video id="sourcevideo" autoplay="autoplay" controls src="https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c4/Physicsworks.ogv/Physicsworks.ogv.240p.vp9.webm"></video>
  </div>

</body>

</html>
like image 62
TBA Avatar answered Sep 16 '25 20:09

TBA


You can set a CSS class including a style of display: none to be applied to the video element (as seen in the code below, .hidden {display:none;}). Since the video element's class is set in the HTML, it should hide the video element but still play the video with autoplay on page load.

The code below shows how you can apply either display: none or visibility: hidden in distinct classes as needed (using buttons in this example).

const sourcevideo = document.getElementById("sourcevideo");
const outputcanvas = document.getElementById("outputcanvas");
const canvasctx = outputcanvas.getContext("2d");

function initCanvas() {
  outputcanvas.width = sourcevideo.videoWidth;
  outputcanvas.height = sourcevideo.videoHeight;
  drawVideo();
}

function drawVideo() {
  canvasctx.drawImage(
    sourcevideo,
    0,
    0,
    outputcanvas.width,
    outputcanvas.height
  );
  requestAnimationFrame(drawVideo);
}

sourcevideo.addEventListener("loadeddata", initCanvas);
.hidden {
  display: none;
}
<div id="videocontainer">
  <canvas id="outputcanvas"></canvas>
  <video id="sourcevideo" class="hidden" controls autoplay src="https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c4/Physicsworks.ogv/Physicsworks.ogv.240p.vp9.webm"></video>
</div>
like image 43
phentnil Avatar answered Sep 16 '25 22:09

phentnil