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 MediaStream Recorder API – a W3C standard.

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

What’s cool about the MediaStream Recorder API is that it is 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. The CodePen is available here.

Online Demo

We've also put together a better demo showing how to use the MediaStream Recorder API to record audio natively in the browser. The code is on GitHub.

Browser Support

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

  • Chrome 52
  • Firefox 30
  • Opera 36
  • Chrome 79

while on mobile it is only supported by:

  • Chrome on Android
  • Firefox on Android

This gives you about 75% coverage on desktop (IE, Edge (non Chromium) 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 79 (Chromium) now supports the standard.

Edge and Safari polyfill

On Safari 11 (on both macOS and iOS) and Edge (non Chromium) 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:

Both Safari and WebView on iOS 11 allow webcam and microphone access permitting MediaRecorder API polyfills to exist.

The MediaRecorder API polyfill allowed us to record uncompressed pcm audio in .wav container. Audio playback will continue in background even if Safari is minimised.

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 (.webm is supported starting with Firefox 63). 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:

BROWSER CONTAINER CODEC MIME TYPES CHANNELS
Firefox .ogg Opus "audio/ogg; codecs=opus" mono or stereo
Chrome .webm Opus "audio/webm; codecs=opus", "audio/webm; codecs=pcm" mono
Opera .webm Opus "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.

More about the MediaStream Recording API on our blog:

Further reading