You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过WebSocket定时发送浏览器录制的16kHz 16位有符号PCM音频数据

实现浏览器端麦克风音频捕获并通过WebSocket发送16kHz 16位PCM数据

当然可以实现定期获取原始音频数据并通过WebSocket发送,下面是基于现代Web API的完整方案:

核心思路

利用AudioContext配合AudioWorklet(推荐,替代已弃用的ScriptProcessorNode)实时捕获音频帧,将浏览器默认的32位浮点PCM转换为16位有符号整数PCM,定期缓存并通过WebSocket发送。

完整实现步骤

1. 初始化WebSocket连接

// 替换为你的服务器WebSocket地址
const ws = new WebSocket('ws://your-server-domain:port');

ws.onopen = () => {
  console.log('WebSocket连接已建立,开始音频传输');
};

ws.onerror = (err) => {
  console.error('WebSocket连接出错:', err);
};

ws.onclose = () => {
  console.log('WebSocket连接已关闭');
};

2. 创建AudioWorklet处理器脚本

新建audio-capture-processor.js文件,用于处理音频数据转换和定期发送:

class AudioCaptureProcessor extends AudioWorkletProcessor {
  constructor() {
    super();
    this.dataBuffer = [];
    // 每100ms发送一次数据(16kHz采样率下对应1600个音频样本)
    this.sendInterval = 100;
    this.lastSendTimestamp = performance.now();
  }

  process(inputs) {
    const inputChannel = inputs[0][0];
    if (!inputChannel) return true;

    // 将32位浮点PCM转换为16位有符号整数PCM
    const int16Data = new Int16Array(inputChannel.length);
    for (let i = 0; i < inputChannel.length; i++) {
      // 浮点范围[-1,1]映射到16位整数范围[-32768, 32767]
      const clampedSample = Math.max(-1, Math.min(1, inputChannel[i]));
      int16Data[i] = clampedSample < 0 ? clampedSample * 32768 : clampedSample * 32767;
    }

    this.dataBuffer.push(int16Data);

    // 检查是否到达发送时间间隔
    const now = performance.now();
    if (now - this.lastSendTimestamp >= this.sendInterval) {
      // 合并缓存的音频数据
      const totalLength = this.dataBuffer.reduce((sum, arr) => sum + arr.length, 0);
      const mergedData = new Int16Array(totalLength);
      let offset = 0;
      this.dataBuffer.forEach(arr => {
        mergedData.set(arr, offset);
        offset += arr.length;
      });

      // 发送二进制数据到服务器
      if (ws.readyState === WebSocket.OPEN) {
        ws.send(mergedData.buffer);
      }

      // 重置缓存和时间戳
      this.dataBuffer = [];
      this.lastSendTimestamp = now;
    }

    return true;
  }

  static get parameterDescriptors() {
    return [];
  }
}

registerProcessor('audio-capture-processor', AudioCaptureProcessor);

3. 主脚本初始化音频捕获

async function startAudioCapture() {
  try {
    // 请求麦克风权限,优先指定16kHz单声道
    const audioStream = await navigator.mediaDevices.getUserMedia({
      audio: {
        sampleRate: 16000,
        channelCount: 1,
        echoCancellation: false, // 根据需求关闭回声消除
        noiseSuppression: false // 根据需求关闭降噪
      },
      video: false
    });

    // 创建16kHz采样率的AudioContext
    const audioContext = new AudioContext({ sampleRate: 16000 });
    // 加载AudioWorklet处理器
    await audioContext.audioWorklet.addModule('audio-capture-processor.js');

    // 创建音频源节点和捕获节点
    const sourceNode = audioContext.createMediaStreamSource(audioStream);
    const captureNode = new AudioWorkletNode(audioContext, 'audio-capture-processor');

    // 连接节点:麦克风 -> 捕获处理器 -> 扬声器(可选,如需监听自己的声音)
    sourceNode.connect(captureNode);
    captureNode.connect(audioContext.destination);

    console.log('音频捕获已启动');
  } catch (err) {
    console.error('音频捕获初始化失败:', err);
  }
}

// 页面加载完成后启动捕获
window.addEventListener('load', startAudioCapture);

关键注意事项

  • 采样率适配:如果浏览器无法提供16kHz的麦克风输入,AudioContext会自动将音频重采样到16kHz,无需额外处理。
  • 发送间隔调整:sendInterval可根据需求修改,间隔越小延迟越低,但WebSocket负载越高,建议50-200ms之间。
  • 兼容性方案:如果需要兼容旧版浏览器(如Chrome <66),可以用已弃用的ScriptProcessorNode替代AudioWorklet,示例代码如下:
// 替换主脚本中的AudioWorklet部分
const scriptNode = audioContext.createScriptProcessor(4096, 1, 1);
scriptNode.onaudioprocess = (event) => {
  const channelData = event.inputBuffer.getChannelData(0);
  const int16Data = new Int16Array(channelData.length);
  for (let i = 0; i < channelData.length; i++) {
    const clampedSample = Math.max(-1, Math.min(1, channelData[i]));
    int16Data[i] = clampedSample < 0 ? clampedSample * 32768 : clampedSample * 32767;
  }
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(int16Data.buffer);
  }
};
sourceNode.connect(scriptNode);
scriptNode.connect(audioContext.destination);

内容的提问来源于stack exchange,提问作者Nathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:15:21