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

expo-audio无法录制语音消息,调用stop()抛出异常问题求助

Expo Audio 语音录制功能异常修复方案

问题描述

使用新版expo-audio开发语音消息录制应用,按官方文档编写代码后功能失效:

  • 执行startRecording后,audioRecorder.isRecording始终为false(预期应为true)
  • 调用stopRecording时抛出异常:
[Error: Call to function 'AudioRecorder.stop' has been rejected.
→ Caused by: java.lang.IllegalStateException]

原代码片段:

const startRecording = async () => {
  await audioRecorder.prepareToRecordAsync();
  audioRecorder.record();
  setRecording(audioRecorder.isRecording);
};

const stopRecording = async () => {
  await audioRecorder.stop();
  setRecording(audioRecorder.isRecording);
  setAudioUri(audioRecorder.uri ?? "");
};

核心问题分析

  1. 异步操作未等待:audioRecorder.record()是异步方法,调用后立刻读取isRecording时,状态还未更新,导致拿到旧值。
  2. 权限缺失:新版expo-audio要求提前申请录音权限,无权限时录制会静默失败,状态不会切换。
  3. Recorder实例初始化错误:若audioRecorder未通过Audio.Recorder.createAsync()正确创建,后续所有录制操作都会无效。

修复步骤

1. 前置处理录音权限

在组件初始化时申请录音权限,无权限时终止录制流程:

import { Audio, PermissionsAndroid, Platform } from 'expo';

const requestRecordingPermission = async () => {
  if (Platform.OS === 'android') {
    const permissionResult = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.RECORD_AUDIO
    );
    return permissionResult === PermissionsAndroid.RESULTS.GRANTED;
  }
  // iOS权限由Expo自动处理,返回true即可
  return true;
};

// 组件挂载时申请权限
useEffect(() => {
  requestRecordingPermission();
}, []);

2. 修正录制流程的异步逻辑

改用recordAsync()(返回Promise)等待录制启动完成,同时确保Recorder实例正确创建:

const [audioRecorder, setAudioRecorder] = useState(null);
const [recording, setRecording] = useState(false);
const [audioUri, setAudioUri] = useState("");

const startRecording = async () => {
  const hasPermission = await requestRecordingPermission();
  if (!hasPermission) {
    alert('请授予录音权限以继续');
    return;
  }

  // 创建Recorder实例(必须步骤)
  const recorder = await Audio.Recorder.createAsync({
    android: {
      extension: '.m4a',
      outputFormat: Audio.RECORDING_OPTION_ANDROID_OUTPUT_FORMAT_MPEG_4,
      audioEncoder: Audio.RECORDING_OPTION_ANDROID_AUDIO_ENCODER_AAC,
      sampleRate: 44100,
      numberOfChannels: 2,
      bitRate: 128000,
    },
    ios: {
      extension: '.m4a',
      audioQuality: Audio.RECORDING_OPTION_IOS_AUDIO_QUALITY_HIGH,
      sampleRate: 44100,
      numberOfChannels: 2,
      bitRate: 128000,
    },
  });

  await recorder.prepareToRecordAsync();
  await recorder.recordAsync(); // 等待录制启动完成
  setAudioRecorder(recorder);
  setRecording(true);
};

const stopRecording = async () => {
  if (!audioRecorder) return;
  
  const result = await audioRecorder.stopAndUnloadAsync();
  setRecording(false);
  setAudioUri(result.uri ?? "");
  // 释放Recorder资源
  setAudioRecorder(null);
};

3. 实时同步录制状态(可选优化)

通过状态监听回调替代主动读取,确保状态同步准确:

useEffect(() => {
  if (!audioRecorder) return;
  
  const statusListener = audioRecorder.addRecordingStatusListener((status) => {
    setRecording(status.isRecording);
  });
  
  // 组件卸载时移除监听
  return () => statusListener.remove();
}, [audioRecorder]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 02:37:45