You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键修改说明

  1. 自动生成Content-Type:当使用FormData作为请求体时,fetch会自动添加带boundary的multipart/form-data头,这是API解析表单文件的必要标识,手动设置会丢失该信息。
  2. File对象适配API要求:将Blob包装为File对象时,指定了文件名和MIME类型,完全匹配ElevenLabs API对files参数的类型预期。
  3. 增强错误调试:增加response.ok判断,可直接打印API返回的具体错误信息,便于排查问题。

额外注意事项

  • 若DocumentPicker返回的asset中mimeType为空,可手动指定默认值(如audio/mpeg)。
  • 确保API密钥正确配置,避免因权限问题导致的请求失败。

内容的提问来源于stack exchange,提问作者Austin Hale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:14:59