Search code examples
node.jsperformanceelectronimage-capturemediastream

Faster MediaStream ImageCapture (read media stream as buffer in nodejs)


Edit: I need to do this live. I can't wait until the stream ends.

I get MediaStream object from electron's desktopCapturer:

navigator.mediaDevices.getUserMedia({
  audio: false,
  video: {
    mandatory: {
      chromeMediaSource: 'desktop',
      chromeMediaSourceId: source.id,
      minWidth: 800,
      maxWidth: 800,
      minHeight: 800,
      maxHeight: 800,
    },
  },
})
.then((stream) => {

I am trying to get node Buffer of a still frame using ImageCapture:

  const track = stream.getVideoTracks()[0];
  const capturedImage = new ImageCapture(track);

  capturedImage // This takes 200ms for 1000x1000
    .takePhoto()
    .then(blob => {
      toBuffer(blob, function (err, buffer) { // 1.5 ms
        if (err) throw err;
          // TODO: Do some opencv magic with node buffer
      });
    })
    .catch(error => console.error('takePhoto() error:', error));

But it takes awfully long to takePhoto. Is it possible to make the process faster? Can I somehow access the MediaStream directly in nodejs?


Solution

  • This is what I ended up doing. It is actually really performant.

    }).then((stream) => {
      const video = document.createElement('video');
      video.srcObject = stream;
      video.onloadedmetadata = () => {
      video.play();
      setInterval(() => {
        const canvas = document.createElement('canvas');
        canvas.getContext('2d').drawImage(video, 0, 0, 800, 800);
        canvas.toBlob(blob => {
          toBuffer(blob, function (err, buffer) {
            if (err) throw err;
            // do some magic with buffer
          });
        });
      }, 40);
    };