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

使用AWS Transcribe Streaming实时转写返回空响应的问题求助

问题解决:AWS Transcribe实时转写返回空结果

核心问题诊断

你遇到的空响应问题,大概率是音频格式与AWS Transcribe的要求不匹配。虽然你验证了音频写入文件可播放,但该文件可能是前端默认的压缩格式(比如WebM),而AWS Transcribe Streaming API要求输入必须是未压缩的RAW PCM,且参数需严格匹配:

  • 采样率:16000Hz(或8000Hz,仅支持特定语言)
  • 声道:单声道
  • 位深:16位
  • 字节顺序:小端序

修复步骤

1. 前端调整:输出正确的PCM格式

前端默认的MediaRecorder通常输出WebM/MP4等压缩格式,需要改用Web Audio API将音频转换成符合要求的RAW PCM:

// 前端音频采集与格式转换示例
navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 16000, channelCount: 1 } })
  .then(stream => {
    const audioContext = new AudioContext({ sampleRate: 16000 });
    const source = audioContext.createMediaStreamSource(stream);
    // 创建脚本处理器,处理单声道音频
    const processor = audioContext.createScriptProcessor(4096, 1, 1);

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

    processor.onaudioprocess = (e) => {
      const inputBuffer = e.inputBuffer;
      const channelData = inputBuffer.getChannelData(0);
      // 将32位浮点音频数据转换为16位Int(小端序)
      const int16Array = new Int16Array(channelData.length);
      for (let i = 0; i < channelData.length; i++) {
        const normalized = Math.max(-1, Math.min(1, channelData[i]));
        int16Array[i] = normalized < 0 ? normalized * 0x8000 : normalized * 0x7FFF;
      }
      // 通过Socket.io发送转换后的PCM buffer
      socket.emit('audio', int16Array.buffer);
    };
  })
  .catch(err => console.error('音频采集失败:', err));

2. 后端优化:确保音频块符合AWS要求

AWS要求每个AudioChunk至少包含10ms的音频(16kHz采样率下为320字节),同时需要在客户端断开时终止流生成:

io.on("connection", (socket) => {
  console.log("Client connected");

  let audioQueue = [];
  let isClientConnected = true;

  socket.on("audio", (chunk) => {
    audioQueue.push(new Uint8Array(chunk));
  });

  socket.on("disconnect", () => {
    console.log("Client disconnected");
    isClientConnected = false; // 终止音频流生成
  });

  const audioStream = async function* () {
    while (isClientConnected) {
      if (audioQueue.length > 0) {
        let currentChunk = audioQueue.shift();
        // 合并小音频块,确保至少10ms的音频数据
        while (audioQueue.length > 0 && currentChunk.length < 320) {
          currentChunk = new Uint8Array([...currentChunk, ...audioQueue.shift()]);
        }
        if (currentChunk.length >= 320) {
          yield { AudioEvent: { AudioChunk: currentChunk } };
        }
      } else {
        await new Promise((resolve) => setTimeout(resolve, 50));
      }
    }
  };

  // 保留原有的Transcribe命令和启动逻辑
  const command = new StartStreamTranscriptionCommand({
    LanguageCode: "en-US", // 若为中文语音需改为"zh-CN"
    MediaSampleRateHertz: 16000,
    MediaEncoding: "pcm",
    AudioStream: audioStream(),
  });

  const startTranscription = async () => {
    try {
      const response = await transcribeClient.send(command);
      for await (const event of response.TranscriptResultStream) {
        if (event.TranscriptEvent) {
          const transcriptResults = event.TranscriptEvent.Transcript.Results;
          transcriptResults.forEach((result) => {
            // 筛选出非空、非部分结果(视需求调整)
            if (result.Alternatives.length > 0 && !result.IsPartial) {
              const transcriptText = result.Alternatives[0].Transcript;
              socket.emit("transcript", transcriptText);
            }
          });
        }
      }
    } catch (error) {
      console.error("转写错误:", error);
      socket.emit("error", error.message);
    }
  };

  startTranscription();
});

3. 额外验证

  • 保存后端接收的音频块为RAW PCM文件,用音频工具(如Audacity)导入时选择16000Hz、16位、单声道、小端序,确认能正常播放。
  • 检查AWS权限:确保你的IAM角色拥有transcribe:StartStreamTranscription权限。

替代实现方案

1. 前端直接对接AWS Transcribe

使用AWS官方的浏览器端SDK,直接在前端将音频流发送到AWS,省去Node.js中转环节:

// 前端示例(需引入AWS SDK)
import { TranscribeStreamingClient, StartStreamTranscriptionCommand } from "@aws-sdk/client-transcribe-streaming";

const client = new TranscribeStreamingClient({
  region: "us-west-2",
  credentials: { /* 前端身份凭证,建议使用Cognito */ }
});

// 音频流生成逻辑同之前的Web Audio处理
const audioStream = async function* () {
  // ... 生成符合要求的AudioChunk
};

const command = new StartStreamTranscriptionCommand({
  LanguageCode: "en-US",
  MediaSampleRateHertz: 16000,
  MediaEncoding: "pcm",
  AudioStream: audioStream(),
});

const response = await client.send(command);
// 处理转写结果
for await (const event of response.TranscriptResultStream) {
  // ... 解析并展示转写文本
}

2. 使用第三方实时转写服务

  • Google Cloud Speech-to-Text:支持实时流式转写,提供多语言、标点自动添加等功能。
  • Azure Speech Services:集成度高,支持实时转写+翻译,适合多场景需求。

3. 自建WebSocket直连AWS

若需自定义传输逻辑,可直接通过WebSocket连接AWS Transcribe的端点(需处理AWS签名),但实现复杂度较高,仅适合特殊场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:15:23