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

Flutter麦克风Uint8List传输至Node.js服务适配语音转文本服务的问题排查与解决

解决Flutter WebSocket传输PCM音频到Node.js的格式不兼容问题

我之前也碰到过几乎一模一样的场景:把Flutter麦克风采集的Uint8List音频通过WebSocket传到Node.js代理服务器后,数据变成了[7, 13, 114, ...]这种数组格式,导致语音转文本(STT)服务无法识别,而其他客户端传过来的都是正常的<Buffer ...>格式。

问题根源分析

首先得明确STT服务的硬性要求:

  • 必须是PCM格式
  • 单声道
  • 16比特位深,采样率8000Hz或16000Hz
  • 双块对齐(每个16比特采样带填充位)

Flutter端采集的Uint8List本身是符合PCM格式的,但通过WebSocket传输时,会被默认序列化为普通JSON数组,而Node.js端接收后需要还原成二进制数组类型,才能匹配STT服务的格式要求——这就是你遇到的核心问题。

已验证的快速解决:Node.js端转换格式

你已经找到的方法完全可行,只需要把接收的数组数据转成Uint8Array,再转成Node.js的Buffer就能被STT服务识别:

// 接收WebSocket传来的数组格式数据
const uint8Array = new Uint8Array(data);
// 转换为Node.js Buffer传给STT服务
const audioBuffer = Buffer.from(uint8Array);

这个方法简单直接,不需要改动Flutter端的代码,就能快速解决兼容性问题。

优化方向:Flutter端直接发送兼容二进制数据

如果想让Flutter端直接输出无需后端转换的二进制数据,可以尝试以下两个调整:

  1. 严格配置音频采集参数
    确保Flutter麦克风采集的音频完全符合STT服务的要求,以record插件为例:

    final recorder = AudioRecorder();
    await recorder.start(
      const RecordConfig(
        sampleRate: 16000, // 对应每秒32000字节
        numChannels: 1, // 单声道
        bitRate: 16, // 16比特位深
      ),
    );
    

    这里16比特位深的PCM每个采样占2字节,天然满足“双块对齐”的要求,不需要额外处理填充位。

  2. 指定WebSocket发送二进制帧
    不要依赖默认的发送逻辑,明确告诉WebSocket发送二进制数据:

    // 假设webSocket是已连接的WebSocket实例
    // 方法1:使用addBinaryFrame发送
    await webSocket.addBinaryFrame(audioUint8List);
    // 方法2:直接add Uint8List(部分库会自动识别为二进制)
    await webSocket.add(audioUint8List);
    

    如果还是不行,可以尝试把Uint8List包装成ByteData再发送:

    final byteData = ByteData.view(audioUint8List.buffer);
    await webSocket.add(byteData);
    

总结

你当前的Node.js端转换方案已经能完美解决问题,如果想进一步优化传输效率,可以从Flutter端的采集配置和WebSocket发送方式入手,实现二进制数据的直接传输,减少后端的转换步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:18:14