javascriptcanvasmediarecorderblobs

MediaRecorder No blobs are defined


I created a script that allows me to record a video from the canvas with the id "imacanvas". But the problem is that no blobs were created. I think the problem is that the function handleDataAvailable isn't executed. But I don't know why??

Thanks for your help :)

var recordedBlobs;
var recorder;
var stream;

function handleDataAvailable(event) {
  console.log("0");
  if (event.data && event.data.size > 0) {
    recordedBlobs.push(event.data);
    console.log("1");
  }
}

function startRecord(){
    recordedBlobs = [];

  var canvas = document.getElementById('imacanvas');
  stream = canvas.captureStream(60);

  try {
    recorder = new MediaRecorder(stream);
  } catch (e) {
    console.error('Exception while creating MediaRecorder: ' + e);
    alert('Exception while creating MediaRecorder: '
      + e + '. mimeType: ' + options.mimeType);
    return;
  }

  recorder.ondataavailable = handleDataAvailable;
  recorder.start(10);
}

function stopRecord() {
  recorder.stop();
  console.log('Recorded Blobs: ', recordedBlobs);
}

function download() {
  var blob = new Blob(recordedBlobs, {type: 'video/webm'});
  var url = window.URL.createObjectURL(blob);
  var a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  a.download = 'test.webm';
  document.body.appendChild(a);
  a.click();
  setTimeout(function() {
    document.body.removeChild(a);
    window.URL.revokeObjectURL(url);
  }, 100);
}

Solution

  • In order to be able to activate the stream captured by HTMLCanvasElement.captureStream(), you need to have initialized its context, and drawn on it.

    This must be done before you call captureStream().

      const chunks_before = [];
      const stream_before = c.captureStream(60);
    try {  const rec_before = new MediaRecorder(stream_before);
      rec_before.ondataavailable = e => chunks_before.push(e.data);
      rec_before.onstop = e => console.log('before : ', chunks_before.length);
      rec_before.start();
      setTimeout(() => {
        if (rec_before.state === 'recording')
          rec_before.stop();
      });
    } catch (e) {
      console.log('before failed');
    }
    
    // simply doing this allows us to do it
    c.getContext('2d').fillRect(0, 0, 20, 20);
    
    const chunks_after = [];
    const stream_after = c.captureStream(60);
    const rec_after = new MediaRecorder(stream_after);
    rec_after.ondataavailable = e => chunks_after.push(e.data);
    rec_after.onstop = e => console.log('after : ', chunks_after.length);
    rec_after.start();
    
    setTimeout(() => {
      if (rec_after.state === 'recording')
        rec_after.stop();
    }, 1000);
    <canvas id="c"></canvas>