Firebase Functions上传ElevenLabs API音频至Storage生成空文件问题
解决Firebase Functions上传ElevenLabs音频到Storage生成空文件的问题
问题根源
调用ElevenLabs流式文本转语音接口时,axios默认会将响应解析为JSON或字符串格式,但音频属于二进制数据,这种解析方式会直接导致原始音频数据丢失,最终上传到Firebase Storage的自然是空文件。
修复方案
核心修改是在axios请求配置中添加**responseType: 'arraybuffer'**,让axios以二进制数组形式接收音频响应,确保上传到Storage的是完整的音频内容。
另外需要注意:ElevenLabs接口路径/text-to-speech/{voice_id}/stream中的参数是语音ID,而非模型ID,你当前代码里传入的clipData.model如果是模型ID的话,需要替换为正确的语音ID,否则API可能返回错误(这也是空文件的潜在诱因)。
修改后的完整代码
import axios from "axios"; import {FieldValue} from "firebase-admin/firestore"; import {firestore, logger} from "firebase-functions/v1"; import {db, storage} from "./lib"; export const generateClip = firestore .document("clips/{clipId}") .onCreate(async (snapshot, context) => { const clipData = snapshot.data(); if (!clipData) { logger.error("No data found"); return; } const clipId = context.params.clipId; try { const res = await axios.post( // 注意:路径参数需替换为有效的ElevenLabs语音ID `https://api.elevenlabs.io/v1/text-to-speech/${clipData.voiceId}/stream`, { "text": clipData.text, "model_id": "eleven_monolingual_v1", "voice_settings": { "stability": 0.5, "similarity_boost": 0.5, }, }, { headers: { "xi-api-key": process.env.VOICE_KEY, "Accept": "audio/mpeg", }, // 关键修改:指定响应类型为二进制数组 responseType: 'arraybuffer' } ); const path = `clips/${clipId}.mp3`; const file = storage.bucket(process.env.FIREBASE_BUCKET).file(path); // 保存二进制音频数据,同时指定MIME类型 await file.save(res.data, { contentType: 'audio/mpeg' }); const tokensCount = (clipData.text as string).length; await db.doc(`clips/${clipId}`).update({ status: "COMPLETED", tokens: tokensCount, file_path: path, }); await db.doc(`users/${clipData.uid}`).update({ tokens: FieldValue.increment(-tokensCount), }); logger.info("Clip generated", { clipId, tokensCount, path, }); } catch (error) { logger.error("Error generate clip", error); await db.doc(`clips/${clipId}`).update({ status: "FAILED", }); } });
额外检查项
- 确认
process.env.VOICE_KEY已正确配置ElevenLabs的有效API密钥,且密钥具备文本转语音接口的调用权限。 - 确保
clipData.voiceId是ElevenLabs控制台中存在的语音ID。 - 上传时指定
contentType: 'audio/mpeg',保证Storage中的文件能被正确识别为MP3格式。
内容的提问来源于stack exchange,提问作者Ashik Chapagain
相关产品推荐
相关产品推荐

