Javascript Tutorial: Record Audio and Encode it to mp3

Jeremy Gottfried
May 1, 2018 · 5 min read

A few weeks ago, I was building a web app using the Google Cloud Voice API and I needed to build a ‘record’ feature in the browser. I discovered Javascript’s MediaRecorder API for recording audio, and the ffmpeg node library for encoding audio.

Here is a link to a CodePen with all the front end code I am covering — https://codepen.io/jeremyagottfried/pen/bMqyNZ. I linked to it instead of embedding because embedded CodePen doesn’t allow you to ask for microphone permission.

If you’re looking to understand how to build a simple web app capable of recording audio and save it to an mp3 file, here is a tutorial:

1. Create a Button

First, create two html buttons for starting and stopping the recording.

You can set your buttons to be rounded in css using the border-radius attribute.

For my record button, I set my css toborder-radius: 50%; , max-width:50%; ,max-height: 15%; , and background-color: red; .

2. Create Event Listeners For Your Buttons

I created two event listeners — one for my start button and one for my stop button. The record.onclick method sets up an event listener for clicks on my record button. The stopRecord.onclick sets up an event listener for the stopRecord button.

Explanation of Event Handlers:

  1. console.log("I was clicked") — set up logs to make sure button clicks are triggering the event handler.
  2. record.disabled = true — after clicking on the recording button, disable it so you can’t keep clicking on it during recording. After you click on stopRecord , re-enable the record button with record.disabled = false .
  3. record.style.backgroundColor = 'blue' — after the record button is clicked, change the color of the record button to signal that you are currently recording.
  4. audioChunks = [] — create an array to hold your audio binary data.
  5. rec.start() — begin recording. let rec = new MediaRecorder(stream); MediaRecorder is a built in class in javascript that allows you to save streamed media data inside an object. Call rec.start()to start recording the audio stream and rec.stop() to stop recording the audio stream.

3. Begin Streaming Audio

The Javascript Web API MediaDevices provides access to connected media devices such as microphones and cameras. getUserMedia API handles streaming from users’ microphones and asking them for permission to use their microphone. In the arguments of getUserMedia(), you pass an object specifying which type of media you’d like to stream. Here I specified audio:true.

Once the media device is streaming, .then(stream => {handlerFunction()})will give you access to the stream and execute a callback function handlerFunction() .

4. Handle The Audio Stream

Explanation of handlerFunction()

  1. rec = new MediaRecorder(stream); — this is where we define the rec variable that we referenced earlier with rec.start() . MediaRecorder is a built in class in javascript that allows you to save streamed media data inside an object.
  2. rec.ondataavailable = e => {} — wait for the streamed audio data to become available, then execute a callback to handle the data.
  3. let blob = new Blob(audioChunks, {type: 'audio/mpeg-3'}); Blob is a built in javascript class for storing binary data. By default, javascript’s getUserMedia() API streams audio data in binary form. Specifying audio/mpeg-3 will allow audio playback in our browser, but it will not encode the audio to a usable format for persisting the audio file.
  4. sendData(blob) — execute a function to send your blob to your server. You can do this via jquery’sajax function, javascript’snew XMLHttpRequest() , or fetch.

Add A Playback Feature

1. In order to add a playback feature, you need to create an audio HTML element with id=recordedAudio. Our handlerFunction will fill the recordedAudio element with audio data so you can play back the recording in the browser.

2. recordedAudio.src = URL.createObjectURL(blob) — associate you blob with a URL and set it to thesrc for your audio element.

3. recordedAudio.controls = true — provide controls for the user to start and stop the recorded audio.

4. recordedAudio.autoplay = true — automatically play back the audio when the user stops recording. You can set this to false if you don’t want the audio to play back automatically.

Encode An mp3 File Using ffmpeg

After you send your blob binary file to the backend, you can use node’s ffmpeg library to convert your file to another format.

First, run npm install ffmpeg , then copy the code below.

fnExtractSoundToMP3() is a method built into the ffmpeg class for converting audio files to mp3. This method also allows you to extract audio from a video file. This code will convert your binary blob file to mp3. There are two lines you need to change —

path/to/blob/file , which is the path to your binary audio file

path/to/new/file.mp3 , which is where your new file will be created.

The rest of the code sets up logging for errors.

Now enjoy and customize your fully functional recording app! You can copy the front end code from the CodePen below. Remember it will not work in this embedded version because embedded CodePen doesn’t allow you to ask for microphone permission.

Jeremy Gottfried’s tech blog

A blog about coding and tech

Jeremy Gottfried

Written by

Programmer, techie, foodie, musician

Jeremy Gottfried’s tech blog

A blog about coding and tech