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

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

额外排查点:

  1. 抓包验证请求完整性:用Charles或MitmProxy抓上传请求,检查:
    • Multipart表单中file字段的Content-Type是否正确
    • 文件内容是否完整(可以把抓包到的文件保存到本地,看能否正常播放)
  2. 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的请求头。
  3. 本地验证文件格式:把录音文件导出到电脑,用ffmpeg -i your-file.m4a(或wav)查看实际编码信息,确认编码与容器匹配。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 10:08:01