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

Android 16下react-native-audio-recorder-player快速启停麦克风失败问题

React Native麦克风录制快速启停在Android 16上的初始化失败问题

我在React Native中使用react-native-audio-recorder-player组件处理麦克风启停逻辑,在Android 16系统上遇到了异常:首次麦克风会话可正常运行,但快速重复执行录制器的启停操作2-3轮后,麦克风会话最终无法完成初始化。

复现代码示例

await audioRecorderPlayer.startRecorder()
await audioRecorderPlayer.stopRecorder()

await audioRecorderPlayer.startRecorder()
await audioRecorderPlayer.stopRecorder()

await audioRecorderPlayer.startRecorder() // 此处执行失败

重要说明(排除权限问题)

  • 已成功获取RECORD_AUDIO权限
  • 首次初始化始终成功
  • 仅在快速重复启停循环后才会出现失败

观察到的现象

  • 仅在Android 16系统上可复现该问题
  • 重启前等待几秒通常可解决问题
  • 疑似原生音频资源未在下次初始化前完全释放
  • 有时在重复循环后,startRecorder()会挂起或无法正常初始化

疑问

  1. Android 16是否修改了AudioRecord的销毁/重新初始化时序?
  2. react-native-audio-recorder-player是否存在已知的快速重启录制器问题?
  3. stopRecorder()与startRecorder()之间是否建议设置延迟/防抖?
  4. 是否需要序列化录制器的启停调用以避免原生竞态条件?

当前流程代码

const start = async () => {
  await audioRecorderPlayer.startRecorder()
}

const stop = async () => {
  await audioRecorderPlayer.stopRecorder()
}

问题解答

  1. Android 16的AudioRecord时序变化
    Android 16(API 34)对音频子系统做了优化调整,其中包含AudioRecord资源释放的异步延迟处理逻辑。如果在资源未完全释放时发起新的初始化请求,会因资源占用冲突导致初始化失败。

  2. react-native-audio-recorder-player的已知问题
    该组件的社区issue中存在大量Android 13+版本下快速启停录制失败的反馈,核心原因是原生层未正确处理AudioRecord资源释放的异步回调,导致JS层调用startRecorder()时,原生资源仍处于未完全释放状态。

  3. 是否需要设置延迟/防抖
    是,临时解决方案可以在stopRecorder()执行完成后添加500ms-1s的固定延迟,给原生层足够时间释放音频资源;也可以通过防抖函数限制启停操作的触发频率,避免短时间内重复调用。

  4. 是否需要序列化调用
    必须做序列化处理。JS层异步调用无法保证原生层的执行顺序,需要维护状态锁或使用队列,确保stopRecorder()的资源释放操作完全完成后,再执行下一次startRecorder()请求。

优化后的示例代码

let isRecording = false;
let isStopping = false;

const start = async () => {
  if (isRecording || isStopping) return;
  isRecording = true;
  try {
    await audioRecorderPlayer.startRecorder();
  } catch (e) {
    console.error('录制启动失败:', e);
    isRecording = false;
  }
};

const stop = async () => {
  if (!isRecording || isStopping) return;
  isStopping = true;
  try {
    await audioRecorderPlayer.stopRecorder();
    // 添加延迟确保资源释放完成
    await new Promise(resolve => setTimeout(resolve, 800));
  } catch (e) {
    console.error('录制停止失败:', e);
  } finally {
    isRecording = false;
    isStopping = false;
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 03:52:26