React Native(Expo)向Whisper API发送音频文件时持续触发“Invalid file format”错误求助
React Native(Expo)向Whisper API发送音频文件时持续触发“Invalid file format”错误求助
看起来你遇到的问题真的很挠人——明明音频能正常播放,Whisper API却死咬着格式不对不放,我来帮你拆解可能的核心问题和修复方案:
核心矛盾点:录音配置的编码与容器不匹配
你当前的录音配置里藏着一个关键矛盾:
- Android端你设置的编码器是
Audio.AndroidAudioEncoder.AAC(压缩编码),但扩展名却用了.wav(通常是为无压缩PCM编码设计的容器) - 虽然播放器能兼容这种“混搭”格式,但Whisper API对格式的检测更严格,它会识别文件的实际编码而非仅看扩展名或你声明的Content-Type,所以直接判定为无效格式。
第一步:修正录音配置,让编码和容器统一
你有两个靠谱的选择,二选一即可:
选项1:录制标准PCM编码的WAV文件(Whisper原生支持)
把Android端的编码器改成PCM格式,和WAV容器匹配:
import { Audio } from 'expo-av'; const recordingOptions: Audio.RecordingOptions = { android: { extension: ".wav", outputFormat: Audio.RecordingOptionsPresets.HIGH, androidEncoder: Audio.AndroidAudioEncoder.PCM_16BIT, // 改为PCM 16位编码器 sampleRate: 44100, numberOfChannels: 2, bitRate: 128000, }, ios: { extension: ".wav", audioQuality: Audio.IOSAudioQuality.HIGH, sampleRate: 44100, numberOfChannels: 2, bitRate: 128000, linearPCMBitDepth: 16, linearPCMIsBigEndian: false, linearPCMIsFloat: false, }, };
选项2:录制AAC编码的M4A文件(更高效,Whisper明确支持)
M4A是AAC编码的标准容器,体积更小且兼容性更好,修改配置如下:
import { Audio } from 'expo-av'; const recordingOptions: Audio.RecordingOptions = { android: { extension: ".m4a", outputFormat: Audio.RecordingOptionsPresets.HIGH, androidEncoder: Audio.AndroidAudioEncoder.AAC, sampleRate: 44100, numberOfChannels: 2, bitRate: 128000, }, ios: { extension: ".m4a", audioQuality: Audio.IOSAudioQuality.HIGH, sampleRate: 44100, numberOfChannels: 2, bitRate: 128000, }, };
第二步:同步修改上传代码的MIME类型
确保上传时声明的mimeType和实际文件格式完全一致:
- 如果用WAV(PCM):
mimeType: "audio/wav" - 如果用M4A:
mimeType: "audio/m4a"
修改后的上传代码示例(以M4A为例):
import * as FileSystem from 'expo-file-system'; const sendAudioToWhisper = async (uri: string) => { try { const response = await FileSystem.uploadAsync( "https://api.openai.com/v1/audio/transcriptions", uri, { headers: { Authorization: `Bearer ${apiKey}`, // 注意:multipart/form-data的Content-Type会由FileSystem自动处理,无需手动设置 }, httpMethod: "POST", uploadType: FileSystem.FileSystemUploadType.MULTIPART, fieldName: "file", mimeType: "audio/m4a", // 与实际文件格式匹配 parameters: { model: "whisper-1", }, } ); const parsedResponse = JSON.parse(response.body); console.log('转录结果:', parsedResponse.text); } catch (error) { console.error("Whisper API Error:", error); } };
额外排查点:
- 抓包验证请求完整性:用Charles或MitmProxy抓上传请求,检查:
- Multipart表单中
file字段的Content-Type是否正确 - 文件内容是否完整(可以把抓包到的文件保存到本地,看能否正常播放)
- Multipart表单中
- PHP后端转发注意事项:如果用PHP中转,确保转发时正确处理文件:
不要手动设置<?php $apiKey = 'your-api-key'; $tmpFile = $_FILES['file']['tmp_name']; $fileName = $_FILES['file']['name']; $mimeType = $_FILES['file']['type']; $ch = curl_init('https://api.openai.com/v1/audio/transcriptions'); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $apiKey" ]); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, [ 'file' => new CURLFile($tmpFile, $mimeType, $fileName), 'model' => 'whisper-1' ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); echo $response; ?>Content-Type: multipart/form-data,让CURL自动生成带boundary的请求头。 - 本地验证文件格式:把录音文件导出到电脑,用
ffmpeg -i your-file.m4a(或wav)查看实际编码信息,确认编码与容器匹配。
内容来源于stack exchange
相关产品推荐
相关产品推荐

