Skip to content

Instantly share code, notes, and snippets.

@rpivo
Last active November 21, 2021 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rpivo/ba17b07a7545639314ae8a98c0e2a16b to your computer and use it in GitHub Desktop.
Save rpivo/ba17b07a7545639314ae8a98c0e2a16b to your computer and use it in GitHub Desktop.
Recording Microphone Audio in the Browser

Recording Microphone Audio in the Browser

Save this as an html file and open in the browser.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="mobile-web-app-capable" content="yes" />
  </head>
  <body>
    <h3>Recording Microphone Audio in the Browser</h3>
    <p>
      Click the "Start Recording" button to record audio from microphone. Then,
      click the "Stop Recording" button to stop recording. After you've
      recorded, you can play back the audio in the player.
    </p>
    <audio id="player" controls></audio>
    <button id="recording-start">Start Recording</button>
    <button id="recording-stop">Stop Recording</button>
    <script type="module">
      (async function () {
        // set immutable variable mediaChunks to an empty array.

        // This will store chunks from the stream.
        const mediaChunks = [];

        // function handleAllowMicrophone is called when the user accepts
        // permission to use the microphone.

        // The stream passed in is the MediaStream object representing the
        // microphone audio stream.
        function handleAllowMicrophone(stream) {
          // set immutable variable recorder equal to a new MediaRecorder
          // instance, passing in stream as the stream to be recorded.
          
          // Set the config object to use the "audio/webm" mimeType.
          const recorder = new MediaRecorder(stream, {
            mimeType: "audio/webm",
          });

          // add click listeners to the start and stop buttons to start and
          // stop the MediaRecorder.
          const startRecordingButton = (document.getElementById(
            "recording-start"
          ).onclick = () => recorder.start());
          const stopRecordingButton = (document.getElementById(
            "recording-stop"
          ).onclick = () => recorder.stop());

          // When data is available on the MediaRecorder, pass it to
          // handleDataAvailable.
          recorder.ondataavailable = handleDataAvailable;
          // when the MediaRecorder is set in the stop state, call
          // handleRecorderStop.
          recorder.onstop = handleRecorderStop;
        }

        // function handleDataAvailable takes in an event.
        // this event contains a data property, which is a media chunk.
        function handleDataAvailable(e) {
          if (e.data.size > 0) {
            // push the media chunk to mediaChunks.
            mediaChunks.push(e.data);
          }
        }

        // function handleRecorderStop is called with an event, but we're not
        // using it here.
        function handleRecorderStop(_e) {
          // create a single blog from the mediaChunks array.
          const blob = new Blob(mediaChunks, {
            type: "audio/webm",
          });
          // URLify the blob so that it can be used on a src property.
          // Set it as the src of the audio player.
          document.getElementById("player").src = URL.createObjectURL(blob);
        }

        try {
          // ask for permission to use the microphone.
          const stream = await navigator.mediaDevices.getUserMedia({
            audio: true,
          });
          // if the user accepts, call handleAllowMicrophone() with the
          // audio stream from the microphone.
          handleAllowMicrophone(stream);
        // if the user denies permission...
        } catch (e) {
          console.error(
            "There was an error when trying to connect to the microphone",
            e
          );
        }
      })();
    </script>
  </body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment