This is the 4th post in our new recording audio in HTML5 series. We’ve previously covered how to record pcm audio using the JavaScript based Recorder.js, pcm, mp3 and Vorbis using WebAudioRecorder.js and mp3 audio using the Web Assembly based vmsg recorder.

We’re now going to take a look at native audio recording in the browser using the Media Recorder API – a W3C standard.

As of this writing the MediaRecorder API spec is in editor’s draft.

What’s cool about the Media Recorder API is that its built-in browsers so your web app will not make any extra HTTP requests or spend time loading external JS libraries.

Another win is the number of code lines needed to set up a recorder. You can cook up a working audio recorder in as little as 21 lines of HTML & JavaScript:

      var recorder, gumStream;
      var recordButton = document.getElementById("recordButton");
      recordButton.addEventListener("click", toggleRecording);
      function toggleRecording() {
        if (recorder && recorder.state=="recording"){
          recorder.stop();
          gumStream.getAudioTracks()[0].stop();
        }else{
          navigator.mediaDevices.getUserMedia({audio: true}).then(function(stream) {
            gumStream = stream;
            recorder = new MediaRecorder(stream);
            recorder.ondataavailable = function(e){
              var url = URL.createObjectURL(e.data);
              var preview = document.createElement('audio');
              preview.controls = true;preview.src = url;
              document.body.appendChild(preview);
            };
            recorder.start();
          });
        }
      }

Browser Support

What’s not so cool is that on desktop computers it is only supported by:

  • Chrome 52
  • Firefox 30
  • Opera 36

while on mobile it is only supported by:

  • Chrome on Android
  • Firefox on Android

This gives you about 75% coverage on desktop (IE, Edge and Safari do not support the standard) and 62% coverage on mobile (Safari on iOS does not support it).

On Safari we might have to wait until Safari 13/iOS13. The API has NOT been announced for Safari 12/iOS 12 due later this year.

This issue on bugs.webkit.org tracks the MediaRecorder API implementation in WebKit/Safari, if you need this API jumping in and leaving a comment will go a lot towards showing Apple developers we need this feature. On the other hand, WebKit is an open source project so anyone with mad skills can jump in and contribute.

On Edge the API is under consideration for implementation with 967 votes.

Edge and Safari polyfill

On Safari 11 (on both macOS and iOS) and Edge you can use this neat polyfill. It enables you to record uncompressed pcm audio in wav containers through the same MediaRecoder API.

This polyfill is cool because it enables you to record audio on most mobile devices – Chrome on Android and Safari on iOS – without relying on the limited HTML Media Capture standard. Go on and give the online polyfill demo a try on your iOS device, here’s what you’ll see:

Once Safari and Edge natively support the standard just remove the polyfill.

With the polyfill you’ll have about 83% coverage on desktop (IE would still not be supported) and 90% coverage on mobile when recording audio.

File formats, audio codecs & quality

Chrome and Opera will record mono channel Opus (default) and pcm (wav, uncompressed) audio at 48kHz in .webm (Matroska) containers.

Firefox will record mono Opus audio at 48kHz in .ogg containers. Firefox used Vorbis for audio recording in the 1st implementations but it moved to Opus since.

I’ve also noticed Firefox will record stereo audio (2 slightly different channels) when recording from a stereo capable recording device like the Logitech C925e or C920 (both have dual mics) or the 15″ Touch Bar MacBook PRO (3 mics).

In terms of controlling the bitrate, the MediaRecorder API spec lists the audioBitPerSecond property but it is not supported at this time by any browser.

In terms of controlling the sample rate, one can specify it through the sampleRate audio constraint in getUserMedia() but it is not supported at this time by any browser.

MediaRecorder.isTypeSupported()

To check whether or not a browser supports a certain file format or audio codec when recording audio you can use the MediaRecorder.isTypeSupported() function. This function 1st appeared in this article by Sam Dutton  and was later introduced in the MediaRecorder API spec.

Syntax:

var canRecord = MediaRecorder.isTypeSupported(mimeType)

To test your browser, open its console and paste:

//true on Chrome and Opera
MediaRecorder.isTypeSupported('audio/webm;codecs=opus')
//true on Firefox
MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')

These are the MIME Types that you can pass to the MediaRecorder constructor:

BROWSERCONTAINERCODECMIME TYPESCHANNELS
Firefox.oggOpus"audio/ogg; codecs=opus"mono or stereo
Chrome.webmOpus"audio/webm; codecs=opus"
"audio/webm; codecs=pcm"
mono
Opera.webmOpus"audio/webm; codecs=opus"
"audio/webm; codecs=pcm"
mono

Length metadata

It’s worth noting that Chrome produces a .webm file without any metadata about the duration of the recording. Such files, with no length information, will not be immediately seekable. The full discussion is in this Chromium bug report. Long story short the length metadata should be at the beginning of the file but the length info is not avb. when the 1st chunk is recorded. Firefox seems to have addressed the issue somehow.

Further reading

https://zhirzh.github.io/2017/09/02/mediarecorder/

https://github.com/ai/audio-recorder-polyfill

https://mozdevs.github.io/MediaRecorder-examples/

https://w3c.github.io/mediacapture-record/