كيفية معالجة الصوت من ميكروفون المستخدم

François Beaufort
François Beaufort

يمكن الوصول إلى كاميرا المستخدم وميكروفونه على النظام الأساسي للويب من خلال واجهة برمجة تطبيقات التقاط الوسائط والبث. تطلب طريقة getUserMedia() من المستخدم الوصول إلى كاميرا و/أو ميكروفون لالتقاط صورة كبث وسائط. يمكن بعد ذلك معالجة هذا البث في سلسلة محادثات Web Audio منفصلة باستخدام AudioWorklet الذي يوفّر معالجة صوت بوقت استجابة سريع جدًا.

يوضّح المثال أدناه كيفية معالجة الصوت الصادر من ميكروفون المستخدم بطريقة فعّالة.

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");

  source.connect(processor).connect(context.destination);
  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.");
});
// processor.js
// This file is evaluated in the audio rendering thread
// upon context.audioWorklet.addModule() call.

class Processor extends AudioWorkletProcessor {
  process([input], [output]) {
    // Copy inputs to outputs.
    output[0].set(input[0]);
    return true;
  }
}

registerProcessor("processor", Processor);

المتصفحات المتوافقة

MediaDevices.getUserMedia()

التوافق مع المتصفح

  • 53
  • 12
  • 36
  • 11

المصدر

محتوى صوتي على الويب

التوافق مع المتصفح

  • 35
  • 12
  • 25
  • 14.1

المصدر

AudioWorklet

التوافق مع المتصفح

  • 66
  • 79
  • 76
  • 14.1

المصدر

محتوى إضافي للقراءة

الخصائص الديموغرافية

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="icon"
      href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%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>
  </head>
  <body>
    <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>
  </body>
</html>

CSS


        :root {
  color-scheme: dark light;
}
html {
  box-sizing: border-box;
}
*,
*:before,
*: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;
}
        

JS


        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");

  source.connect(processor).connect(context.destination);

  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.");
});