Learning How to Capture and Record Audio in HTML5

It is known that getUserMedia, the API defined by WebRTC, is the main method for accessing media capture devices such as webcam and microphone in web pages. The compatible desktop web browsers include Chrome, Firefox, Opera, and Edge. This article will share the resources for learning how to capture and record audio in HTML5.

record audio in HTML5

How to capture audio from a microphone in HTML5?

Here is the code snippet from MDN (Mozilla Developer Network):

var p = navigator.mediaDevices.getUserMedia({ audio: true, video: true });

p.then(function(mediaStream) {
  var video = document.querySelector('video');
  video.src = window.URL.createObjectURL(mediaStream);
  video.onloadedmetadata = function(e) {
// Do something with the video here.


p.catch(function(err) { console.log(err.name); }); // always check for errors at the end.

The returned media stream includes video stream track and audio stream track.

Browser compatibility:


getusermedia desktop


getusermedia mobile

How to record audio stream and upload it to a remote server?

Interfaces for Recording Audio

Using MediaRecorder API is the ideal way for recording media streams, but it is not well supported so far.

Browser compatibility:


mediarecorder desktop


mediarecorder mobile

Alternatively, we can record audio with AudioNodes, which represents audio sources, the audio destination, and intermediate processing modules.

The basic steps of recording audio in HTML5

  1. Capture media stream with getUserMedia.
  2. Create a MediaStreamAudioSourceNode with createMediaStreamSource.
    if (navigator.getUserMedia) {
       console.log('getUserMedia supported.');
       navigator.getUserMedia (
          // constraints: audio and video for this app
             audio: true,
             video: true
          // Success callback
          function(stream) {
             video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
             video.onloadedmetadata = function(e) {
                video.muted = 'true';
             // Create a MediaStreamAudioSourceNode
             // Feed the HTMLMediaElement into it
             var source = audioCtx.createMediaStreamSource(stream);
          // Error callback
          function(err) {
             console.log('The following gUM error occured: ' + err);
    } else {
       console.log('getUserMedia not supported on your browser!');
  3. Connect AudioNodes. Process audio with ScriptProcessorNode. Use the onaudioprocess event to get the audio buffer.
    var scriptNode = audioCtx.createScriptProcessor(4096, 1, 1);
    scriptNode.onaudioprocess = function(audioProcessingEvent) {
      // The input buffer is the song we loaded earlier
      var inputBuffer = audioProcessingEvent.inputBuffer;
      // Loop through the output channels (in this case there is only one)
      for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) {
        var inputData = inputBuffer.getChannelData(channel);
  4. Encode the audio buffer and send it via XMLHttpRequest or WebSockets.

JavaScript Libraries

I found two useful JavaScript libraries for audio recording on GitHub: RecordRTC and Recorderjs.

RecordRTC is powerful for both video and audio recording (try the online demo), whereas Recorderjs is less complicated that it only supports audio recording. Let’s anatomize the code logic of Recorderjs.

Use onaudioprocess event to receive audio buffer:

this.context = source.context;
        this.node = (this.context.createScriptProcessor || this.context.createJavaScriptNode).call(this.context, this.config.bufferLen, this.config.numChannels, this.config.numChannels);

        this.node.onaudioprocess = function (e) {
            if (!_this.recording) return;

            var buffer = [];
            for (var channel = 0; channel < _this.config.numChannels; channel++) {
                command: 'record',
                buffer: buffer

        this.node.connect(this.context.destination); //this should not be necessary

Cache received audio buffer:

function record(inputBuffer) {
                for (var channel = 0; channel < numChannels; channel++) {
                recLength += inputBuffer[0].length;

Encode audio buffer to WAV format:

function encodeWAV(samples) {
                var buffer = new ArrayBuffer(44 + samples.length * 2);
                var view = new DataView(buffer);

                /* RIFF identifier */
                writeString(view, 0, 'RIFF');
                /* RIFF chunk length */
                view.setUint32(4, 36 + samples.length * 2, true);
                /* RIFF type */
                writeString(view, 8, 'WAVE');
                /* format chunk identifier */
                writeString(view, 12, 'fmt ');
                /* format chunk length */
                view.setUint32(16, 16, true);
                /* sample format (raw) */
                view.setUint16(20, 1, true);
                /* channel count */
                view.setUint16(22, numChannels, true);
                /* sample rate */
                view.setUint32(24, sampleRate, true);
                /* byte rate (sample rate * block align) */
                view.setUint32(28, sampleRate * 4, true);
                /* block align (channel count * bytes per sample) */
                view.setUint16(32, numChannels * 2, true);
                /* bits per sample */
                view.setUint16(34, 16, true);
                /* data chunk identifier */
                writeString(view, 36, 'data');
                /* data chunk length */
                view.setUint32(40, samples.length * 2, true);

                floatTo16BitPCM(view, 44, samples);

                return view;

Merge audio buffer and export WAV data:

function exportWAV(type) {
                var buffers = [];
                for (var channel = 0; channel < numChannels; channel++) {
                    buffers.push(mergeBuffers(recBuffers[channel], recLength));
                var interleaved = undefined;
                if (numChannels === 2) {
                    interleaved = interleave(buffers[0], buffers[1]);
                } else {
                    interleaved = buffers[0];
                var dataview = encodeWAV(interleaved);
                var audioBlob = new Blob([dataview], { type: type });


6 thoughts on “Learning How to Capture and Record Audio in HTML5

  1. Hey would you mind sharing which blog platform you’re working with?

    I’m looking to start my own blog in the near
    future but I’m having a difficult time deciding
    between BlogEngine/Wordpress/B2evolution and Drupal. The
    reason I ask is because your layout seems different then most blogs and I’m
    looking for something completely unique.
    P.S My apologies for being off-topic but I had to ask!

  2. Its like you learn my mind! You appear to understand so
    much about this, such as you wrote the e-book in it or something.
    I believe that you can do with some percent to power the message
    house a bit, but instead of that, that is fantastic blog.
    An excellent read. I will certainly be back.

Comments are closed.