Node.js中处理OpenAI TTS API响应:转MP3缓冲区并存储
解决OpenAI TTS API的二进制响应处理与MP3存储问题
核心问题分析
你的代码未配置axios的响应类型,默认情况下axios会把二进制分块响应解析成字符串,导致音频数据损坏。必须明确指定响应类型为二进制格式,才能正确处理audio/mpeg的流数据。
修改后的实现方案
以下是两种常用处理方式,按需选择:
方式1:获取MP3 Buffer并存储
适合需要先对音频数据做处理再存储的场景:
const fs = require('fs').promises; const axios = require('axios'); const speechUrl = 'https://api.openai.com/v1/audio/speech'; const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` }; async function voiceGenerator(text) { console.log('voiceGenerator is triggered'); console.log('text: ', text); const body = { "model": "tts-1", "input": text, "voice": "alloy", "response_format": "mp3", "speed": 0.9 }; try { const res = await axios.post(speechUrl, body, { headers: headers, responseType: 'arraybuffer' // 关键配置:以二进制数组形式接收响应 }); if (res.status === 200) { // 将ArrayBuffer转换为Node.js Buffer const mp3Buffer = Buffer.from(res.data); // 示例:存储为本地MP3文件 await fs.writeFile('./output.mp3', mp3Buffer); console.log('MP3文件已成功存储'); return mp3Buffer; } else { console.error('请求失败,状态码:', res.status); throw new Error(`请求失败,状态码: ${res.status}`); } } catch (err) { console.error('OpenAI API调用失败:', err.response?.data || err.message); throw err; } }
方式2:直接通过流存储(更高效,适合大文件)
如果不需要对音频数据做中间处理,直接用流可以减少内存占用:
const fs = require('fs'); const axios = require('axios'); const speechUrl = 'https://api.openai.com/v1/audio/speech'; const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` }; async function voiceGenerator(text) { console.log('voiceGenerator is triggered'); console.log('text: ', text); const body = { "model": "tts-1", "input": text, "voice": "alloy", "response_format": "mp3", "speed": 0.9 }; try { const res = await axios.post(speechUrl, body, { headers: headers, responseType: 'stream' // 关键配置:以流形式接收响应 }); if (res.status === 200) { return new Promise((resolve, reject) => { const writeStream = fs.createWriteStream('./output.mp3'); // 将响应流管道到文件写入流 res.data.pipe(writeStream); writeStream.on('finish', () => { console.log('MP3文件已成功存储'); resolve(); }); writeStream.on('error', (err) => { console.error('文件写入失败:', err); reject(err); }); }); } else { console.error('请求失败,状态码:', res.status); throw new Error(`请求失败,状态码: ${res.status}`); } } catch (err) { console.error('OpenAI API调用失败:', err.response?.data || err.message); throw err; } }
关键说明
- responseType配置:必须设置为
arraybuffer或stream,否则axios会把二进制数据转成UTF-8字符串,导致MP3文件损坏无法播放。 - 状态码判断:OpenAI TTS接口成功响应的状态码是200,204代表无内容,无需保留该判断。
- 错误处理优化:捕获错误时优先读取
err.response?.data,可以拿到OpenAI返回的具体错误信息(比如API密钥无效、输入文本过长等)。
内容的提问来源于stack exchange,提问作者Terry Windwalker
相关产品推荐
相关产品推荐

