FS Readable Stream与Axios responseType:'stream'传入OpenAI接口异常
问题解决:Axios流传入OpenAI语音转写触发栈溢出
问题背景
本地读取文件转成可读流传入OpenAI语音转写接口完全正常:
const transcription = await openai.audio.transcriptions.create({ file: fs.createReadStream('./audio.mp3'), model: "whisper-1", });
但改用Axios从URL直接获取流传入时,Node进程会挂起数秒,随后反复打印数百次栈溢出错误:
RangeError: Maximum call stack size exceeded Exception in
PromiseRejectCallback:
file:///home/domingo/WebstormProjects/call2jira-proxy/node_modules/openai/uploads.mjs:152
}; ^
问题根源
Axios返回的流是IncomingMessage(HTTP响应流),虽然属于Node.js可读流范畴,但它的内部事件处理逻辑和FS模块的ReadStream存在差异。OpenAI的上传处理模块在处理这类流时,触发了无限递归调用,最终导致栈溢出。
可行解决方案
方案1:用原生https模块直接获取流
绕开Axios的包装,直接用Node原生https模块获取流,返回的响应流能被OpenAI模块正确处理:
import https from 'https'; // 封装获取流的函数 function fetchAudioStream(url) { return new Promise((resolve, reject) => { const request = https.get(url, (response) => { if (response.statusCode !== 200) { reject(new Error(`请求失败,状态码:${response.statusCode}`)); return; } resolve(response); }); request.on('error', reject); }); } // 使用示例 const fileStream = await fetchAudioStream('你的Twilio录音URL'); const transcription = await openai.audio.transcriptions.create({ file: fileStream, model: "whisper-1", });
方案2:用PassThrough中转Axios流
通过Node的PassThrough流中转Axios返回的流,转换成标准可读流:
import { PassThrough } from 'stream'; import axios from 'axios'; const { data: axiosStream } = await axios.get(url, { responseType: 'stream' }); // 创建中转流 const fileStream = new PassThrough(); axiosStream.pipe(fileStream); // 传入OpenAI接口 const transcription = await openai.audio.transcriptions.create({ file: fileStream, model: "whisper-1", });
验证提示
直接使用你提供的Twilio录音URL测试上述方案,即可解决栈溢出问题。
内容的提问来源于stack exchange,提问作者DomingoSL
相关产品推荐
相关产品推荐

