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

使用Expo Audio录制音频时触发TypeError:requestPermissionsAsync未定义

解决Expo Audio录制时的权限请求错误

这个错误Failed to start recording, TypeError: undefined is not an object evaluating '_ExponentAV.default.requestPermissionsAsync',主要是API调用方式不对或者Recording实例的创建逻辑有问题,下面是具体修复方案:

1. 替换权限请求的API

如果你的Expo SDK版本是48及以上,Audio.requestPermissionsAsync可能已经被更明确的requestRecordingPermissionsAsync替代,直接替换即可:

// 把原来的await Audio.requestPermissionsAsync();改成
await Audio.requestRecordingPermissionsAsync();

2. 用useRef保存Recording实例

你现在直接在组件里创建const recording = new Audio.Recording();,每次组件重新渲染都会生成新实例,不仅会搞乱录制逻辑,还可能导致API调用异常。改用useRef持久化这个实例:

// 先导入useRef
import React, { useState, useRef } from "react";

// 在组件内部替换成ref
const recordingRef = useRef<Audio.Recording | null>(null);

// startRecording里创建实例并保存到ref
const startRecording = async () => {
  try {
    console.log("Requesting permissions..");
    await Audio.requestRecordingPermissionsAsync();
    await Audio.setAudioModeAsync({
      allowsRecordingIOS: true,
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true, // 安卓可选,录制时压低其他音频
    });

    console.log("Starting recording..");
    // 创建新的Recording实例
    const recording = new Audio.Recording();
    await recording.prepareToRecordAsync(
      Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
    );
    await recording.startAsync();
    // 保存到ref里
    recordingRef.current = recording;
    setIsRecording(true);
    console.log("Recording started");
  } catch (err) {
    console.error("Failed to start recording", err);
  }
};

// stopRecording里从ref获取实例
const stopRecording = async () => {
  try {
    console.log("Stopping recording..");
    setIsRecording(false);
    // 先判断实例是否存在
    if (!recordingRef.current) return;
    await recordingRef.current.stopAndUnloadAsync();
    const uri = recordingRef.current.getURI();
    console.log("Recording stopped and stored at", uri);
    // 重置ref
    recordingRef.current = null;
  } catch (err) {
    console.error("Failed to stop recording", err);
  }
};

3. 确保expo-av依赖是最新的

执行命令更新依赖:

npx expo install expo-av

4. 配置app.json里的权限

iOS和安卓都需要配置对应的权限,否则会直接被拒绝访问麦克风:

// app.json里的expo字段下添加
"ios": {
  "infoPlist": {
    "NSMicrophoneUsageDescription": "需要访问麦克风来录制语音消息"
  }
},
"android": {
  "permissions": ["RECORD_AUDIO"]
}

关键注意点

  • 绝对不能在组件渲染时直接创建Recording实例,必须用useRef持久化,不然组件状态更新时会丢失之前的录制实例
  • 权限请求优先用requestRecordingPermissionsAsync,比通用的requestPermissionsAsync更明确,避免版本兼容问题
  • 一定要配置权限描述,iOS会在请求权限时显示这个描述,没有的话会直接拒绝

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:05:29