Using the Mic to Record Audio on a Browser

by Kristian Ranstrom
November 5, 2021
8 min read

I've had a few clients who have wanted to capture audio from a user and upload that audio to the server. Usually it was because they wanted the user to just chat instead of type in their response to a question.  As it turns out, this isn't that hard these days.  Advances in JavaScript with Files, Audio, MediaRecorder as well as 3rd party libraries can really make this easy.  Here are 2 examples.  

Capture Audio as weba

This example doesn't use any 3rd party libraries. It's clean and quick.  

<html>
<head>
    <title>audio recorder test</title>
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <style>
        li { list-style: none; }
    </style>
</head>
<body>
    <div class="container text-center">
        <h1>Mic Recorder to weba Example</h1>
        <p>Check your web developer tool console for output.</p>

        <hr />

        <button class="btn btn-primary">Start recording</button>

        <br />
        <br />
        <br />

        <ul id="playlist"></ul>
    </div>

    <!--
        <a id="download">Download</a>
        <button id="stop">Stop</button>
        <br />
        <audio id="player" controls></audio>
    -->

    <script>
        const button = document.querySelector('button');

        const options = {mimeType: 'audio/webm'};
        const buffer = [];
        var mediaRecorder = null;

        // start the recording
        const startRecording = function() {
            mediaRecorder.start();
            button.classList.toggle('btn-danger');
            button.removeEventListener('click', startRecording);
            button.addEventListener('click', stopRecording);
        }

        // stop the recording
        const stopRecording = function() {
            mediaRecorder.stop();
            button.textContent = 'Start recording';
            button.classList.toggle('btn-danger');
            button.removeEventListener('click', stopRecording);
            button.addEventListener('click', startRecording);
        }

        // init the audio system
        const handleInit = function(stream) {
            // start recording with a click of the button
            button.addEventListener('click', startRecording);

            // the mediaRecord object that captures the stream
            mediaRecorder = new MediaRecorder(stream, options);

            // catches stream of bytearray
            mediaRecorder.addEventListener('dataavailable', function(e) {
                if (e.data.size > 0) buffer.push(e.data);
            });

            // when stopped, create a file and allow playback
            mediaRecorder.addEventListener('stop', function() {
                console.dir(buffer);
                // create a file
                const file = new File(buffer, 'audio.webm', {
                    type: 'audio/webm',
                    lastModified: Date.now()
                });

                // display the file via an Audio object
                const li = document.createElement('li');
                const player = new Audio(URL.createObjectURL(file));
                player.controls = true;
                li.appendChild(player);
                document.querySelector('#playlist').appendChild(li);
                buffer.length = 0; // empty the buffer for the next one
            });          
        };

        // init the stream from the audio device
        navigator.mediaDevices.getUserMedia({ audio: true, video: false })
            .then(handleInit);

    </script>
</body>
</html>

Capture Audio as mp3

This example uses a a library called mic-recorder-to-mp3
https://github.com/closeio/mic-recorder-to-mp3

<html>
<head>
    <title>audio recorder test</title>
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script type="text/javascript" src="https://unpkg.com/mic-recorder-to-mp3"></script>
    <style>
        li { list-style: none; }
    </style>
</head>
<body>
    <div class="container text-center">
        <h1>Mic Recorder to Mp3 Example</h1>
        <p>Check your web developer tool console for output.</p>

        <hr />

        <button class="btn btn-primary">Start recording</button>

        <br />
        <br />
        <br />

        <ul id="playlist"></ul>
    </div>

     <script>
        const button = document.querySelector('button');

        // set the options of this 3rd party mp3 js encoder
        const recorder = new MicRecorder({
            bitRate: 128
        });

        // start recording with a click of the button
        button.addEventListener('click', startRecording);

        // start the recording
        function startRecording() {
            recorder.start().then(() => {
                button.textContent = 'Stop recording';
                button.classList.toggle('btn-danger');
                button.removeEventListener('click', startRecording);
                button.addEventListener('click', stopRecording);
            }).catch((e) => {
                console.error(e);
            });
        }

        // stop the recording
        function stopRecording() {
            // create the mp3
            recorder.stop().getMp3().then(([buffer, blob]) => {
                console.log(buffer, blob);
                // create the file
                const file = new File(buffer, 'audio.mp3', {
                    type: blob.type,
                    lastModified: Date.now()
                });

                // display the as an Audio object
                const li = document.createElement('li');
                const player = new Audio(URL.createObjectURL(file));
                player.controls = true;
                li.appendChild(player);
                document.querySelector('#playlist').appendChild(li);

                // reset
                button.textContent = 'Start recording';
                button.classList.toggle('btn-danger');
                button.removeEventListener('click', stopRecording);
                button.addEventListener('click', startRecording);
            }).catch((e) => {
                console.error(e);
            });
        }
    </script>
</body>
</html>

Conclusion

Once you have your File Blob, you can either just play it back or transfer it to the server side and save or process it from there.