Javascript Tutorial: Record Audio and Encode it to mp3
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:
console.log("I was clicked")
— set up logs to make sure button clicks are triggering the event handler.record.disabled = true
— after clicking on the recording button, disable it so you can’t keep clicking on it during recording. After you click onstopRecord
, re-enable the record button withrecord.disabled = false
.record.style.backgroundColor = 'blue'
— after therecord
button is clicked, change the color of therecord
button to signal that you are currently recording.audioChunks = []
— create an array to hold your audio binary data.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. Callrec.start()
to start recording the audio stream andrec.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()
rec = new MediaRecorder(stream);
— this is where we define therec
variable that we referenced earlier withrec.start()
. MediaRecorder is a built in class in javascript that allows you to save streamed media data inside an object.rec.ondataavailable = e => {}
— wait for the streamed audio data to become available, then execute a callback to handle the data.let blob = new Blob(audioChunks, {type: 'audio/mpeg-3'});
—Blob
is a built in javascript class for storing binary data. By default, javascript’sgetUserMedia()
API streams audio data in binary form. Specifyingaudio/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.sendData(blob)
— execute a function to send your blob to your server. You can do this via jquery’sajax
function, javascript’snew XMLHttpRequest()
, orfetch
.
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.