Expo/React Native调用Elevenlabs添加语音API问题:无法发送音频文件
解决Expo应用上传音频到ElevenLabs语音克隆API的格式错误问题
在Expo移动端应用中使用DocumentPicker选择音频文件后,调用ElevenLabs添加语音API时收到格式错误:Expected UploadFile, received: <class 'str'>,但curl请求可正常工作。以下是解决方案:
核心问题与修复方案
- 移除手动设置的
Content-Type请求头:fetch会自动生成包含boundary的正确multipart/form-data头,手动设置会破坏表单数据的解析逻辑。 - 用File对象替代Blob:ElevenLabs API期望接收标准
UploadFile类型,将Blob包装为File对象能匹配API的参数要求。
修改后的createVoice函数代码
export const createVoice = async (name: string, audioClips: DocumentPicker.DocumentPickerAsset[]) => { const formData = new FormData(); formData.append('name', name); formData.append('remove_background_noise', 'true'); for (const clip of audioClips) { // 从Expo文件URI创建标准File对象 const file = await fetch(clip.uri) .then(res => res.blob()) .then(blob => new File([blob], clip.name, { type: clip.mimeType || 'audio/mpeg' })); formData.append('files', file); } const options = { method: 'POST', headers: { 'xi-api-key': 'apikey', // 替换为你的实际API密钥 }, body: formData }; const response = await fetch('https://api.elevenlabs.io/v1/voices/add', options); if (!response.ok) { const error = await response.json(); console.error('API错误:', error); return null; } const json = await response.json(); return json.voice_id; }
关键修改说明
- 自动生成Content-Type:当使用FormData作为请求体时,fetch会自动添加带boundary的
multipart/form-data头,这是API解析表单文件的必要标识,手动设置会丢失该信息。 - File对象适配API要求:将Blob包装为File对象时,指定了文件名和MIME类型,完全匹配ElevenLabs API对
files参数的类型预期。 - 增强错误调试:增加
response.ok判断,可直接打印API返回的具体错误信息,便于排查问题。
额外注意事项
- 若DocumentPicker返回的asset中
mimeType为空,可手动指定默认值(如audio/mpeg)。 - 确保API密钥正确配置,避免因权限问题导致的请求失败。
内容的提问来源于stack exchange,提问作者Austin Hale
相关产品推荐
相关产品推荐

