0

I'm trying to get a screen recording of the browser using the MediaStream API in Javascript. My current method which is in raw Javascript works perfectly for Firefox (it provides me with a ~10sec video of the screen and downloads it) but in Chrome it gives me a video of a single frame - about half a second of footage.

My original code

    var videoEl = document.querySelector('video');
    var stream = videoEl.srcObject;
    var track = stream.getVideoTracks()[0];

    var finalStream = new MediaStream();
    finalStream.addTrack(track);
    this.recorder = new MediaRecorder(finalStream);

    this.recorder.ondataavailable = function(e) {
      var link = document.createElement('a');
      link.setAttribute('href', window.URL.createObjectURL(e.data));
      link.setAttribute('download', 'video_' + Math.floor((Math.random() * 999999)) + '.mp4');
      link.style.display = 'none';

      document.body.appendChild(link);
      link.click();

      document.body.removeChild(link);
    }

    this.recorder.start();
    setTimeout(() => this.recorder.stop(), 10000);

I've also tried using the javascript Blob API but when I use this method Chrome behaves as before and Firefox either records correctly for 10 secs or throws TypeError: stream is null

Blob method

    var videoEl = document.querySelector('video');
    var stream = videoEl.srcObject;
    var track = stream.getVideoTracks()[0];

    var finalStream = new MediaStream();
    finalStream.addTrack(track);
    this.recorder = new MediaRecorder(finalStream);

    var chunks = [];
    this.recorder.ondataavailable = function(e) {
      chunks.push(e.data);
    }

    this.recorder.onstop = function(e) {
      var link = document.createElement('a');
      link.setAttribute('href', window.URL.createObjectURL(new Blob(chunks)));
      link.setAttribute('download', 'video_' + Math.floor((Math.random() * 999999)) + '.mp4');
      link.style.display = 'none';

      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }

    this.recorder.start();
    setTimeout(() => {this.recorder.stop()}, 10000);

I expect that it will record about 10secs and then download the file.

I get the correct result in Firefox but in Chrome I get the less than a second of footage.

Isabella
  • 133
  • 1
  • 2
  • 13
  • 1
    Check [this](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject) out. – StackSlave Apr 08 '19 at 02:07
  • Hi @Kaiido, could you explain how this is a duplicate of my question? Their question is related to the Blob API which I'm not actually using. Thanks :) – Isabella Apr 08 '19 at 02:09
  • Their question is as much related to the Blob API as yours. Read the accepted answer. Your problem is that you are expecting `ondatavailable` callback to fire once, when it will fire multiple times with only chunks of the whole video. You must merge all these chunks in a single Blob, from inside the `onstop` event. – Kaiido Apr 08 '19 at 02:12
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/191419/discussion-between-kaiido-and-isabella). – Kaiido Apr 08 '19 at 04:24

0 Answers0