使用AWS Transcribe Streaming Service转录无结果,Next.js函数提前终止返回空值
问题:Next.js中AWS实时音频转录返回空字符串,函数提前终止
我在Next.js应用里实现AWS实时音频转录功能,但函数没等音频流结束就提前终止,返回空字符串。前端通过异步函数调用该方法并将结果存入状态变量,始终得到空值。
实现代码
export const get_aws = async (file: File, code: string) => { async function* getAudioStream(file: File) { const audioStream = file.stream(); const reader = audioStream.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) break; yield { AudioEvent: { AudioChunk: value } }; } } finally { reader.releaseLock(); } } const transcribe_client = new TranscribeStreamingClient({ region: process.env.NEXT_PUBLIC_AWS_REGION as string, credentials: { accessKeyId: process.env.NEXT_PUBLIC_AWS_ACCESS_KEY_ID as string, secretAccessKey: process.env.NEXT_PUBLIC_AWS_SECRET_ACCESS_KEY as string, }, }); const params = { TranscriptionJobName: file.name, LanguageCode: code as LanguageCode, MediaEncoding: MediaEncoding.OGG_OPUS, MediaSampleRateHertz: 48000, AudioStream: getAudioStream(file), }; let transcription = ""; try { const response = await transcribe_client.send( new StartStreamTranscriptionCommand(params), ); for await (const event of response?.TranscriptResultStream as any) { if (event.TranscriptEvent) { transcription += event.TranscriptEvent.Transcript.Results[0].Alternatives[0] .Transcript; } } return transcription.trim(); } catch (error) { throw `Error Fetching AWS: ${error}`; } };
问题排查与解决方案
1. 转录结果处理逻辑错误
原代码直接取Results[0],但AWS实时转录返回的TranscriptEvent中可能包含多个结果,且部分结果是临时的(IsPartial: true),直接拼接会导致遗漏或重复。修改处理逻辑,只拼接非临时的完整结果:
// 替换原遍历TranscriptResultStream的代码 for await (const event of response.TranscriptResultStream) { if (event.TranscriptEvent) { const results = event.TranscriptEvent.Transcript.Results; // 遍历所有结果,只处理非partial的完整转录片段 for (const result of results) { if (!result.IsPartial && result.Alternatives.length > 0) { transcription += result.Alternatives[0].Transcript + ' '; } } } }
2. 音频参数不匹配
确认MediaSampleRateHertz与实际音频文件的采样率一致。如果你的音频文件采样率不是48000Hz(比如常见的16000Hz),需要修改该参数,否则AWS无法正确解析音频,返回空转录结果。
3. 前端调用未正确处理异步
确保前端调用时使用await等待函数执行完成:
// 前端调用示例 const handleTranscribe = async (file: File) => { try { const transcript = await get_aws(file, 'zh-CN'); // 替换为对应语言码 setTranscription(transcript); // 存入状态变量 } catch (err) { console.error(err); } };
4. 安全风险提示(重要)
当前代码将AWS密钥放在NEXT_PUBLIC_*环境变量中,会直接暴露给前端用户,存在严重的安全隐患。建议将转录逻辑迁移到Next.js的API路由(pages/api或app/api)中,后端处理AWS请求,前端仅上传文件和传递语言参数。
补充调试建议
- 在
getAudioStream中添加日志,确认文件流是否被完整读取:async function* getAudioStream(file: File) { const audioStream = file.stream(); const reader = audioStream.getReader(); try { let chunkCount = 0; while (true) { const { done, value } = await reader.read(); if (done) { console.log(`文件流读取完成,共${chunkCount}个分片`); break; } chunkCount++; yield { AudioEvent: { AudioChunk: value } }; } } finally { reader.releaseLock(); } } - 在转录循环中添加日志,查看是否接收到
TranscriptEvent:for await (const event of response.TranscriptResultStream) { console.log('收到事件:', event); if (event.TranscriptEvent) { console.log('转录结果:', event.TranscriptEvent.Transcript.Results); // ... 后续处理 } }
内容的提问来源于stack exchange,提问作者krishtimil
相关产品推荐
相关产品推荐

