如何将MediaRecorder流编码为PCM格式适配AWS Transcribe Medical
解决AWS Transcribe Medical实时PCM音频流问题的工具包与代码方案
你的核心问题是MediaRecorder无法直接输出AWS要求的原始PCM格式,以下是两种可行方案:
1. 原生Web Audio API实现(无额外依赖)
直接通过浏览器原生API捕获原始音频样本,转换为AWS要求的16位PCM格式后实时发送,无需安装工具包。修改后的完整代码如下:
import React, { useState, useRef } from "react"; import { TranscribeStreamingClient, StartMedicalStreamTranscriptionCommand, } from "@aws-sdk/client-transcribe-streaming"; import logo from "./logo.svg"; import "./App.css"; function App() { const [isRecording, setIsRecording] = useState(false); const audioContextRef = useRef(null); const scriptProcessorRef = useRef(null); const mediaStreamRef = useRef(null); const transcribeQueueRef = useRef([]); const client = new TranscribeStreamingClient({ region: "your-region", credentials: { accessKeyId: "your-access-key", secretAccessKey: "your-secret-key", }, }); const handleMicClick = () => { isRecording ? stopRecording() : startRecording(); }; const startRecording = async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 44100 } }); mediaStreamRef.current = stream; audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: 44100 }); const source = audioContextRef.current.createMediaStreamSource(stream); // 创建音频处理器,每次处理4096个样本(可根据需求调整) scriptProcessorRef.current = audioContextRef.current.createScriptProcessor(4096, 1, 1); source.connect(scriptProcessorRef.current); scriptProcessorRef.current.connect(audioContextRef.current.destination); // 初始化AWS转录流 initTranscribeStream(); // 实时处理音频样本 scriptProcessorRef.current.onaudioprocess = (event) => { const floatPcm = event.inputBuffer.getChannelData(0); // 转换为AWS要求的16位有符号整数PCM const int16Pcm = new Int16Array(floatPcm.length); for (let i = 0; i < floatPcm.length; i++) { const sample = Math.max(-1, Math.min(1, floatPcm[i])); int16Pcm[i] = sample < 0 ? sample * 0x8000 : sample * 0x7FFF; } // 加入发送队列 if (transcribeQueueRef.current.length > 0) { const resolve = transcribeQueueRef.current.shift(); resolve(int16Pcm); } }; setIsRecording(true); } catch (error) { console.error("启动录制失败: ", error); } }; const initTranscribeStream = async () => { const input = { LanguageCode: "en-US", MediaSampleRateHertz: 44100, MediaEncoding: "pcm", Specialty: "PRIMARYCARE", Type: "CONVERSATION", AudioStream: (async function* () { while (true) { yield await new Promise(resolve => transcribeQueueRef.current.push(resolve)); } })() }; const command = new StartMedicalStreamTranscriptionCommand(input); const response = await client.send(command); // 处理转录结果 (async () => { for await (const event of response.TranscriptResultStream) { if (event.TranscriptEvent) { event.TranscriptEvent.Transcript.Results.forEach(result => { result.Alternatives?.forEach(alternative => { const transcript = alternative.Items?.map(item => item.Content).join(" ") || ""; console.log("转录内容:", transcript); }); }); } } })(); }; const stopRecording = () => { // 清理所有资源 scriptProcessorRef.current?.disconnect(); audioContextRef.current?.close(); mediaStreamRef.current?.getTracks().forEach(track => track.stop()); transcribeQueueRef.current = []; setIsRecording(false); }; return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <button onClick={handleMicClick}> {isRecording ? "停止录制" : "开始录制"} </button> </header> </div> ); } export default App;
2. 使用audio-recorder-polyfill简化开发
这个库可以让MediaRecorder支持输出WAV格式(包含PCM数据),只需简单配置即可适配现有代码,之后提取WAV中的PCM数据发送给AWS。
安装命令:
npm install audio-recorder-polyfill
代码修改:
在文件顶部添加配置:
import AudioRecorder from 'audio-recorder-polyfill'; // 强制MediaRecorder输出WAV格式 AudioRecorder.prototype.mimeType = 'audio/wav'; window.MediaRecorder = AudioRecorder;
修改handleDataAvailable函数提取PCM数据:
const handleDataAvailable = async (event) => { const arrayBuffer = await event.data.arrayBuffer(); // WAV文件前44字节是头部,后面为原始PCM数据 const pcmData = new Uint8Array(arrayBuffer.slice(44)); sendAudioChunk(pcmData); };
同时需要调整sendAudioChunk函数,用异步迭代器向AWS发送流式数据(逻辑参考原生方案中的initTranscribeStream部分)。
关键注意事项
- AWS Transcribe要求PCM为16位有符号整数、单声道、采样率与配置的44100Hz一致,转换时需确保格式正确。
- 实时流式发送必须用
async generator实现AWS要求的AudioStream异步迭代器,不能直接传递单个Blob。 - 停止录制时需完整清理音频上下文、媒体流等资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Shubham Ambastha
相关产品推荐
相关产品推荐

