1

I'm using Electron Desktop Capturer https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.md to capture a screenshot of this stream at regular intervals. I'm using this code but for some reason I get an error:

function takeScr(stream) {
  const video = localStream.getVideoTracks()[0];
  console.log(video)
  const canvas = document.createElement('canvas');
  canvas.getContext("2d").drawImage(video, 0, 0, 300, 300, 0, 0, 300, 300);
}

At the moment I'm simply pressing a button to activate this take screenshot function after the stream has started playing. The console log shows the video track no problem with output:

MediaStreamTrack {kind: "video", id: "7a19a94f-6077-4e3d-b534-03d138b3f300", label: "Screen", enabled: true, muted: false, …}

but the canvas.getContext function throws the error:

Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'

There are many questions on here about this error but none seem to solve my problem and none are regarding video streams. Some solutions were that the image was not loaded when trying to draw to canvas but since I'm pressing a button several seconds after the stream has started I'm sure it must be loaded?

Maybe I'm doing this the wrong way and there is a better way to take screenshots of the video source from Desktop Capturer?

Hasen
  • 11,710
  • 23
  • 77
  • 135
  • It seems like your script is expecting given parameter within your `.drawImage()` function to be of any of the given types. Apparently `localStream.getVideoTracks()[0]` is not a supported type. Is `drawImage()` a function you designed and would you be able to show its definition? – Barrosy May 08 '19 at 09:54
  • @Barrosy drawImage() is a function built into canvas. – Hasen May 08 '19 at 09:55
  • You are trying to draw a video as image in a [canvas](https://www.w3schools.com/tags/canvas_drawimage.asp), which I do not think `.drawImage()` is supposed to be used for. Make sure whatever you are trying to pass as (video) parameter to be of given types (e.g. an image like in the example I gave found in the link). – Barrosy May 08 '19 at 09:58
  • @Barrosy I searched for how to take a screenshot from a video like this and it said to use canvas like this, it's not my own code although the code is not 100% identical to mine. How would you take a screenshot from a video like this then? – Hasen May 08 '19 at 10:01

1 Answers1

3

I found an example in the following question regarding taking snapshots from a video.

You could do something like this:

document.getElementById("snap").addEventListener("click", function() {
  snap();
});

// Get handles on the video and canvas elements
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
// Get a handle on the 2d context of the canvas element
var context = canvas.getContext('2d');
// Define some vars required later
var w, h, ratio;

// Add a listener to wait for the 'loadedmetadata' state so the video's dimensions can be read
video.addEventListener('loadedmetadata', function() {
  // Calculate the ratio of the video's width to height
  ratio = video.videoWidth / video.videoHeight;
  // Define the required width as 100 pixels smaller than the actual video's width
  w = video.videoWidth - 100;
  // Calculate the height based on the video's width and the ratio
  h = parseInt(w / ratio, 10);
  // Set the canvas width and height to the values just calculated
  canvas.width = w;
  canvas.height = h;
}, false);

// Takes a snapshot of the video
function snap() {
  // Define the size of the rectangle that will be filled (basically the entire element)
  context.fillRect(0, 0, w, h);
  // Grab the image from the video
  context.drawImage(video, 0, 0, w, h);
}
<video width="400" controls>
  <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
  <source src="https://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg">
  Your browser does not support HTML5 video.
</video>

<canvas width="364" height="204"></canvas>

<button id="snap">Take screenshot</button>

JSFiddle

Barrosy
  • 1,407
  • 2
  • 25
  • 56