<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
      href="data:image/svg+xml,<svg xmlns=%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎙️</text></svg>"
    <title>How to process audio from the user's microphone</title>
    <h1>How to process audio from the user's microphone</h1>
    <button id="startMicrophoneButton">Start using microphone</button>
    <button id="stopMicrophoneButton" disabled>Stop using microphone</button>
    <pre id="logs"></pre>


        :root {
  color-scheme: dark light;
html {
  box-sizing: border-box;
*:after {
  box-sizing: inherit;
body {
  margin: 1rem;
  font-family: system-ui, sans-serif;
button {
  display: block;
  margin-bottom: 4px;
pre {
  color: red;
  white-space: pre-line;


        const startMicrophoneButton = document.querySelector('#startMicrophoneButton');
const stopMicrophoneButton = document.querySelector('#stopMicrophoneButton');

let stream;

startMicrophoneButton.addEventListener("click", async () => {
  // Prompt the user to use their microphone.
  stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
  const context = new AudioContext();
  const source = context.createMediaStreamSource(stream);

  // Load and execute the module script.
  await context.audioWorklet.addModule("processor.js");
  // Create an AudioWorkletNode. The name of the processor is the
  // one passed to registerProcessor() in the module script.
  const processor = new AudioWorkletNode(context, "processor");


  stopMicrophoneButton.disabled = false;
  log("Your microphone audio is being used.");

stopMicrophoneButton.addEventListener("click", () => {
  // Stop the stream.
  stream.getTracks().forEach(track => track.stop());

  log("Your microphone audio is not used anymore.");