JavaScript 采集PCM 麦克风声音

引言

在现代的 Web 开发中,通过浏览器采集麦克风声音变得越来越常见。原生的 JavaScript API 提供了一种简单的方法来收集 PCM(脉冲编码调制)格式的音频数据。本文将介绍如何使用 JavaScript 采集麦克风声音,并提供相应的代码示例。

PCM 音频数据

PCM 是数字音频的一种编码方式,它将连续的模拟音频信号转换为数字形式,以便于存储和处理。PCM 音频数据由一系列采样点组成,每个采样点表示特定时间点上的音频振幅。对于每个采样点,我们可以通过一个数字来表示振幅的大小。常见的 PCM 格式有 8 位、16 位和 32 位,不同的精度决定了音频数据的质量和大小。

使用 getUserMedia 获取麦克风访问权限

在开始采集麦克风声音之前,我们需要通过浏览器的 getUserMedia API 获取麦克风的访问权限。以下是一段获取麦克风访问权限的代码示例:

if (navigator.mediaDevices.getUserMedia) {
  navigator.mediaDevices.getUserMedia({ audio: true })
    .then(function(stream) {
      // 麦克风访问权限获取成功
    })
    .catch(function(err) {
      // 麦克风访问权限获取失败
    });
} else {
  // 浏览器不支持 getUserMedia API
}

上述代码首先检查浏览器是否支持 getUserMedia API,然后调用 getUserMedia 方法并传递 { audio: true } 参数来获取麦克风访问权限。获取成功后,我们可以通过 stream 对象来访问麦克风的音频数据。

采集 PCM 音频数据

一旦我们获得了麦克风的访问权限,我们就可以开始采集 PCM 音频数据了。我们可以使用 Web API 中的 AudioContextScriptProcessorNode 来实现采集过程。以下是一段采集 PCM 音频数据的代码示例:

var audioContext = new (window.AudioContext || window.webkitAudioContext)();
var scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1);

scriptProcessor.onaudioprocess = function(event) {
  var inputData = event.inputBuffer.getChannelData(0);
  // 处理 PCM 音频数据
};

var microphoneStream = audioContext.createMediaStreamSource(stream);
microphoneStream.connect(scriptProcessor);
scriptProcessor.connect(audioContext.destination);

上述代码首先创建了一个 AudioContext 对象和一个 ScriptProcessorNode 对象。ScriptProcessorNode 对象用于处理音频数据。我们可以通过 onaudioprocess 事件来监听音频数据的采集过程。在事件处理函数中,我们可以通过 event.inputBuffer 获取 PCM 音频数据,并进行相应的处理。

接下来,我们将麦克风的音频数据流连接到 ScriptProcessorNode 对象和 AudioContext 的输出。这样,采集到的音频数据将被传递给 ScriptProcessorNode 对象,并输出到设备的音频输出。

示例:实时音频可视化

下面的示例将展示如何使用上述方法采集 PCM 音频数据,并实时可视化音频波形。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>实时音频可视化</title>
  <style>
    canvas {
      width: 100%;
      height: 200px;
    }
  </style>
</head>
<body>
  <canvas id="waveform"></canvas>
  <script>
    if (navigator.mediaDevices.getUserMedia) {
      navigator.mediaDevices.getUserMedia({ audio: true })
        .then(function(stream) {
          var audioContext = new (window.AudioContext || window.webkitAudioContext)();
          var scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1);
          var canvas = document.getElementById('waveform');
          var canvasContext = canvas.getContext('2d');
  
          scriptProcessor.onaudi