使用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
相关产品推荐
相关产品推荐

