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

Expo安卓端上传M4A音频至服务器提示非音频文件问题

问题原因分析
  • Android端URI格式不兼容:Expo在Android上返回的录音文件URI带有file://前缀,但FormData在Android环境下需要的是本地文件的绝对路径而非带scheme的URI,保留前缀会导致无法正确读取文件内容,服务器收到异常数据后判定不是音频文件。
  • MIME类型匹配问题:代码中指定的audio/m4a是iOS端标准MIME类型,但Android上Expo录制的M4A文件实际对应的标准MIME类型为audio/mp4,服务器的文件类型校验逻辑可能对MIME类型的匹配要求更严格。
解决方案
  1. 恢复Android端URI前缀处理逻辑
    取消注释代码中移除file://前缀的逻辑,确保上传的是正确的本地文件路径:
let convertedUri = uri;
if (Platform.OS === 'android') {
  // Android环境下需移除file://前缀,使用绝对路径
  convertedUri = uri.replace('file://', '');
}
  1. 适配跨平台MIME类型
    根据系统平台设置对应的MIME类型,避免服务器校验不通过:
formData.append('session_audio', {
  uri: convertedUri,
  type: Platform.OS === 'android' ? 'audio/mp4' : 'audio/m4a',
  name: `recording_${Date.now()}.m4a`, // 用时间戳生成唯一文件名,避免重复冲突
});
  1. 上传前验证文件有效性(可选)
    使用Expo的FileSystem模块检查文件是否存在,避免上传无效路径:
import * as FileSystem from 'expo-file-system';

const handleSubmit = async () => {
  let convertedUri = uri;
  if (Platform.OS === 'android') {
    convertedUri = uri.replace('file://', '');
  }

  // 检查文件是否存在且为有效文件
  const fileInfo = await FileSystem.getInfoAsync(convertedUri);
  if (!fileInfo.exists || !fileInfo.isFile) {
    console.error('录音文件不存在或路径无效');
    return;
  }

  const formData = new FormData();
  formData.append('session_name', textInputValue);
  formData.append('session_audio', {
    uri: convertedUri,
    type: Platform.OS === 'android' ? 'audio/mp4' : 'audio/m4a',
    name: `recording_${Date.now()}.m4a`,
  });

  mutate({ assets: formData });
  // 重置状态逻辑...
};
  1. 确认服务器校验规则
    如果上述调整后仍有问题,需确认服务器是仅通过MIME类型判断文件,还是会校验文件头(magic number)。可使用ffmpeg工具检查Android端录制文件的编码格式:
ffmpeg -i 本地录音文件路径

若文件编码为标准M4A格式,可要求服务器放宽MIME类型匹配规则,同时支持audio/mp4和audio/m4a。

内容的提问来源于stack exchange,提问作者Waleed Taher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:41:14