Web/API/MediaStream Recording API

From Get docs


The MediaStream Recording API, sometimes simply referred to as the Media Recording API or the MediaRecorder API, is closely affiliated with the Media Capture and Streams API and the WebRTC API. The MediaStream Recording API makes it possible to capture the data generated by a MediaStream or HTMLMediaElement object for analysis, processing, or saving to disk. It's also surprisingly easy to work with.

Basic concepts

The MediaStream Recording API is comprised of a single major interface, MediaRecorder, which does all the work of taking the data from a MediaStream and delivering it to you for processing. The data is delivered by a series of dataavailable events, already in the format you specify when creating the MediaRecorder. You can then process the data further or write it to file as desired.

Overview of the recording process

The process of recording a stream is simple:

  1. Set up a MediaStream or HTMLMediaElement (in the form of an <audio> or <video> element) to serve as the source of the media data.
  2. Create a MediaRecorder object, specifying the source stream and any desired options (such as the container's MIME type or the desired bit rates of its tracks).
  3. Set MediaRecorder.ondataavailable to an event handler for the dataavailable event; this will be called whenever data is available for you.
  4. Once the source media is playing and you've reached the point where you're ready to record video, call MediaRecorder.start() to begin recording.
  5. Your dataavailable event handler gets called every time there's data ready for you to do with as you will; the event has a data attribute whose value is a Blob that contains the media data. You can force a dataavailable event to occur, thereby delivering the latest sound to you so you can filter it, save it, or whatever.
  6. Recording stops automatically when the source media stops playing.
  7. You can stop recording at any time by calling MediaRecorder.stop().

Note: Individual Blobs containing slices of the recorded media will not necessarily be individually playable. The media needs to be reassembled before playback.


If anything goes wrong during recording, an error event is sent to the MediaRecorder. You can listen for error events by setting up a onerror event handler. Example here, we use an HTML Canvas as source of the MediaStream, and stop recording after 9 seconds.

var canvas = document.querySelector("canvas");

// Optional frames per second argument.
var stream = canvas.captureStream(25);
var recordedChunks = [];

console.log(stream);
var options = { mimeType: "video/webm; codecs=vp9" };
mediaRecorder = new MediaRecorder(stream, options);

mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();

function handleDataAvailable(event) {
  console.log("data-available");
  if (event.data.size > 0) {
    recordedChunks.push(event.data);
    console.log(recordedChunks);
    download();
  } else {
    // ...
  }
}
function download() {
  var blob = new Blob(recordedChunks, {
    type: "video/webm"
  });
  var url = URL.createObjectURL(blob);
  var a = document.createElement("a");
  document.body.appendChild(a);
  a.style = "display: none";
  a.href = url;
  a.download = "test.webm";
  a.click();
  window.URL.revokeObjectURL(url);
}

// demo: to download after 9sec
setTimeout(event => {
  console.log("stopping");
  mediaRecorder.stop();
}, 9000);

Examining and controlling the recorder status

You can also use the properties of the MediaRecorder object to determine the state of the recording process, and its pause() and resume() methods to pause and resume recording of the source media.

If you need or want to check to see if a specific MIME type is supported, that's possible as well. Just call MediaRecorder.isTypeSupported().

Examining potential input sources

If your goal is to record camera and/or microphone input, you may wish to examine the available input devices before beginning the process of constructing the MediaRecorder. To do so, you'll need to call navigator.mediaDevices.enumerateDevices() to get a list of the available media devices. You can then examine that list and identify the potential input sources, and even filter the list based on desired criteria.

In this code snippet, enumerateDevices() is used to examine the available input devices, locate those which are audio input devices, and create <option> elements that are then added to a <select> element representing an input source picker.

navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
  devices.forEach(function(device) {
    let menu = document.getElementById("inputdevices");
    if (device.kind == "audioinput") {
      let item = document.createElement("option");
      item.innerHTML = device.label;
      item.value = device.deviceId;
      menu.appendChild(item);
    }
  });
});

Code similar to this can be used to let the user restrict the set of devices they wish to use.

For more information

To learn more about using the MediaStream Recording API, see Using the MediaStream Recording API, which shows how to use the API to record audio clips. A second article, Recording a media element, describes how to receive a stream from an <audio> or <video> element and use the captured stream (in this case, recording it and saving it to a local disk).

Reference

BlobEvent
Each time a chunk of media data is finished being recorded, it's delivered to consumers in Blob form using a BlobEvent of type dataavailable.
MediaRecorder
The primary interface that implements the MediaStream Recording API.
MediaRecorderErrorEvent
The interface that represents errors thrown by the MediaStream Recording API. Its error property is a DOMException that specifies that error occurred.

Specifications

Specification Status Comment
MediaStream Recording Working Draft Initial definition

Browser compatibility

MediaRecorder

Update compatibility data on GitHub

Desktop Mobile
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet
MediaRecorder Chrome

Full support 47

Edge

Full support 79

Firefox Full support 25

Notes'

Full support 25

Notes'

Notes' Prior to Firefox 58, using MediaStream.addTrack() on a stream obtained using getUserMedia(), then attempting to record the resulting stream would result in only recording the original stream without the added tracks (severe bug).

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 47

Chrome Android

Full support 47

Firefox Android Full support 25

Notes'

Full support 25

Notes'

Notes' Prior to Firefox 58, using MediaStream.addTrack() on a stream obtained using getUserMedia(), then attempting to record the resulting stream would result in only recording the original stream without the added tracks (severe bug).

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

MediaRecorder() constructor Chrome

Full support 47

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 47

Chrome Android

Full support 47

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

audioBitsPerSecond

Experimental'

Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 71

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

?

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

error event Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

ignoreMutedMedia

Deprecated'Non-standard'

Chrome

No support 49 — 57

Edge

No support No

Firefox

?

IE

No support No

Opera

No support 36 — 44

Safari

No support No

WebView Android

No support 49 — 57

Chrome Android

No support 49 — 57

Firefox Android

?

Opera Android

No support 36 — 44

Safari iOS

No support No

Samsung Internet Android

No support 5.0 — 7.0

isTypeSupported Chrome

Full support 47

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 47

Chrome Android

Full support 47

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

mimeType

Chrome Full support 49


Full support 49


No support 47 — 49

Notes'

Notes' Prior to Chrome 49, only video is supported, not audio.

Edge

Full support 79

Firefox Full support 25

Notes'

Full support 25

Notes'

Notes' Starting with Firefox 71, the behavior of mimeType is more consistent. For example, it now returns the media type even after recording has stopped.

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android Full support 49


Full support 49


No support 47 — 49

Notes'

Notes' Prior to Chrome 49, only video is supported, not audio.

Chrome Android Full support 49


Full support 49


No support 47 — 49

Notes'

Notes' Prior to Chrome 49, only video is supported, not audio.

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

ondataavailable Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

onerror Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

onpause Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 65

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 65

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

onresume Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 65

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 65

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

onstart Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

onstop Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

onwarning

Deprecated'

Chrome

Full support 49

Edge

Full support 79

Firefox

No support 25 — 71

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

pause Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

requestData Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

resume Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

start Chrome

Full support 47

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 47

Chrome Android

Full support 47

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

state

Chrome Full support 49


Full support 49


No support 47 — 49

Notes'

Notes' Prior to Chrome 49, only video is supported, not audio.

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android Full support 49


Full support 49


No support 47 — 49

Notes'

Notes' Prior to Chrome 49, only video is supported, not audio.

Chrome Android Full support 49


Full support 49


No support 47 — 49

Notes'

Notes' Prior to Chrome 49, only video is supported, not audio.

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

stop Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

stream

Chrome Full support 49


Full support 49


No support 47 — 49

Notes'

Notes' Prior to Chrome 49, only video is supported, not audio.

Edge

Full support 79

Firefox

Full support 25

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android Full support 49


Full support 49


No support 47 — 49

Notes'

Notes' Prior to Chrome 49, only video is supported, not audio.

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

videoBitsPerSecond

Experimental'

Chrome

Full support 49

Edge

Full support 79

Firefox

Full support 71

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

?

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

warning event

Deprecated'

Chrome

Full support 49

Edge

Full support 79

Firefox

No support 25 — 71

IE

No support No

Opera

Full support 36

Safari

No support No

WebView Android

Full support 49

Chrome Android

Full support 49

Firefox Android

Full support 25

Opera Android

Full support 36

Safari iOS

No support No

Samsung Internet Android

Full support 5.0

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
Experimental. Expect behavior to change in the future.'
Experimental. Expect behavior to change in the future.
Non-standard. Expect poor cross-browser support.'
Non-standard. Expect poor cross-browser support.
Deprecated. Not for use in new websites.'
Deprecated. Not for use in new websites.
See implementation notes.'
See implementation notes.


See also