React Native Expo托管应用录音无法适配OpenAI转录接口问题
错误原因排查与解决方法
核心问题1:手动设置Content-Type导致表单解析失败
当使用axios发送FormData时,禁止手动设置Content-Type: multipart/form-data。axios会自动生成包含正确boundary分隔符的Content-Type头,手动设置会丢失该分隔符,导致OpenAI接口无法正确解析表单中的音频文件,最终返回格式错误。
修复代码:
// 修改headers定义,移除手动设置的Content-Type const headers = { 'Authorization': `Bearer ${OPENAI_API_KEY}`, };
核心问题2:Expo iOS录制的文件格式与扩展名不匹配
Expo iOS端的RECORDING_OPTION_IOS_OUTPUT_FORMAT_MPEG4AAC实际生成的是M4A音频文件(而非带视频轨道的MP4),虽然强制使用.mp4扩展名能被系统识别,但Whisper接口对M4A格式的兼容性更稳定。
修复步骤:
- 调整录制选项的扩展名:
ios: { extension: '.m4a', // 替换原.mp4 outputFormat: Audio.RECORDING_OPTION_IOS_OUTPUT_FORMAT_MPEG4AAC, audioQuality: Audio.RECORDING_OPTION_IOS_AUDIO_QUALITY_HIGH, },
- 同步修改文件名称与FormData中的类型:
// 生成文件名时使用.m4a后缀 const fileName = `recording-${Date.now()}.m4a`; // FormData中对应修改类型 formData.append('file', { uri: tempRecordingUri, name: fileName, type: 'audio/m4a', });
可选修复:直接读取文件内容构造Blob(避免URI解析问题)
部分情况下,Expo的文件URI在axios中无法被正确解析为二进制文件,此时可以将文件读取为Base64后转为Blob再传入FormData:
替换原FormData构造代码:
// 读取文件内容为Base64 const fileContent = await FileSystem.readAsStringAsync(tempRecordingUri, { encoding: FileSystem.EncodingType.Base64, }); // 转为Blob const blob = new Blob( [Uint8Array.from(atob(fileContent), c => c.charCodeAt(0))], { type: 'audio/m4a' } ); // 构造FormData const formData = new FormData(); formData.append('file', blob, fileName); formData.append('model', 'whisper-1');
辅助验证:检查文件完整性
添加文件大小验证,确保文件复制过程中未损坏:
const fileInfo = await FileSystem.getInfoAsync(tempRecordingUri); console.log('录制文件大小:', fileInfo.size); // 如果size为0,说明文件复制失败,需检查FileSystem.copyAsync的路径是否正确
内容的提问来源于stack exchange,提问作者Ibra
相关产品推荐
相关产品推荐

