using faster_whisper with javascript frontend via websockets – different audio format?

用户尝试在浏览器中使用 navigator.mediaDevices.getUserMedia 和 ScriptProcessorNode 获取实时音频,通过 WebSocket 将 Float32Array 数据发送到 Python 后端,后端使用 faster_whisper 进行实时语音转录。

using faster_whisper with javascript frontend via websockets - different audio format?

using faster_whisper with javascript frontend via websockets – different audio format?

快速结论:此报错发生在通过 WebSocket 将浏览器麦克风获取的 Float32Array 音频数据实时传输到 Python 后端,并使用 faster_whisper 进行转录时。优先排查音频数据的格式转换是否正确,尤其是 Web Audio API 输出的 Float32Array 与 numpy/pyaudio 的格式差异。

问题场景

用户尝试在浏览器中使用 navigator.mediaDevices.getUserMediaScriptProcessorNode 获取实时音频,通过 WebSocket 将 Float32Array 数据发送到 Python 后端,后端使用 faster_whisper 进行实时语音转录。但转录结果异常(例如只识别出 “Bye”,实际上从未提到该词),且通过 pyaudio 采集的音频可以正常工作。

报错原文

both codes should work out-of-the-box with the 2nd one producing ok results, but the combination of the javascript/python-backend only recognizes "Bye" although never mentioned.

无具体报错代码,主要表现为转录结果错误。

原因分析

可能原因:

  • Web Audio API 的 event.inputBuffer.getChannelData(0) 返回的 Float32Array 数据格式(例如字节序、采样率、位深等)与 numpy 默认的 np.frombuffer(..., dtype=np.float32) 解析方式不匹配。
  • 音频数据在传输过程中缺少必要的元数据(如采样率、声道数),导致 faster_whisper 无法正确解码。
  • WebSocket 传输过程中可能存在帧丢失或数据混叠,但用户无法检测到该问题。
  • JavaScript 的 Float32Array 与 pyaudio 的 paFloat32 格式可能使用了不同的编码规范,导致数值范围或排列方式存在差异。

社区成员指出,通过将接收到的数据保存为 WAV 文件再传入模型可以正常转录,说明问题可能出在数据直接传输的格式转换环节。

注释中建议的归一化操作(除以 32768.0)可能并不适用,因为 Web Audio API 的 Float32Array 值域已经是 -1 到 1 之间。

环境排查

  • 确认 Python 版本及 faster_whisper 版本
  • 确认后端是否使用了 np.frombuffer(b''.join(frames), dtype=np.float32) 来处理接收到的数据
  • 确认浏览器 AudioContext 的采样率设置(默认可能是 48000,而 faster_whisper 期望 16000)
  • 确认 WebSocket 传输是否使用了正确的内容类型(如 blobarraybuffer

解决步骤

  1. 可优先尝试:保存音频到文件验证
    将接收到的数据先保存为 WAV 文件,再传给模型:

    import soundfile as sf
    fname = r"C:\test.wav"
    sig = np.frombuffer(b''.join(frames), dtype=np.float32)
    sf.write(fname, sig, 16000, format="wav")
    segments, info = model.transcribe(fname, language="en")

    如果保存为文件后转录正常,说明数据流本身没有问题,问题出在数据直接传输格式上。

  2. 可优先尝试:使用 BytesIO 避免写磁盘
    如果不想写磁盘,可以将数据写入内存:

    import io
    import soundfile as sf
    
    f = io.BytesIO()
    sf.write(f, sig, 16000, format="wav")
    f.seek(0)
    segments, _ = model.transcribe(f, language="en")
  3. 备选方案:使用 WebRTC + aiortc
    社区成员建议使用 aiortc 库替代纯 WebSocket 传输,因为 aiortc 会自动处理音频格式转换(如 codec、bitrate 等)。相关示例可参考 https://github.com/aiortc/aiortc/tree/main/examples/server
  4. 排查数据归一化问题
    检查接收到的 Float32Array 的值域是否已经在 -1 到 1 之间,不需要额外除以 32768.0。如果确认值域正确,可跳过归一化步骤。

验证方法

成功转录时,faster_whisper 返回的文本应与实际说的内容一致,且不再出现随机或重复的词语(如 “Bye”)。如果使用文件方式验证通过,则可以确认问题出在实时数据流的格式转换上。

参考来源

SYSTRAN/faster-whisper #671

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 8251

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注