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

Flutter iOS端通话中断后恢复录音失败:AVFAudio错误-10868求助

Flutter iOS端通话中断后恢复录音失败:AVFAudio错误-10868求助

我之前做Flutter iOS音频开发时刚好碰到过类似的AVFAudio错误-10868,这个问题本质上是系统音频会话抢占后,应用端的音频资源状态不一致导致的。结合你用到的record: ^6.0.0和audio_session: ^0.2.1两个包,给你几个针对性的排查和修复方案,亲测有效的概率很高:

先搞懂错误本身

AVFAudio的-10868错误对应AVAudioSessionErrorCodeCannotStartPlaying(iOS的录音与播放共享音频会话资源,所以录音场景也会触发这个错误),说白了就是你的应用尝试获取音频资源时,系统当前的音频状态和你请求的配置不匹配,或者之前的资源没有正确释放。

针对性修复方案

1. 重写中断处理逻辑:先激活会话再恢复录音

你现在的问题大概率是在通话中断结束后直接调用了录音的resume,但此时系统已经把你的应用音频会话置为非激活状态,直接恢复肯定会冲突。正确流程应该是:

  • 中断开始时,暂停录音并主动释放会话激活状态
  • 中断结束时,先重新激活音频会话,再恢复录音

给你一段参考代码:

// 初始化阶段监听音频中断事件
void _setupAudioInterruptionListener() async {
  final session = await AudioSession.instance;
  session.interruptionEventStream.listen((event) async {
    if (event.type == AudioInterruptionType.began) {
      // 收到中断(比如来电),先暂停录音
      if (recorder.isRecording) {
        await recorder.pause();
      }
      // 主动失活会话,避免系统强制回收资源
      await session.setActive(false);
    } else if (event.type == AudioInterruptionType.ended) {
      // 中断结束,先重新激活音频会话
      try {
        await session.setActive(true, 
          options: AudioSessionActivationOptions.notifyOthersOnDeactivation);
        // 再尝试恢复录音
        if (recorder.isPaused) {
          await recorder.resume();
        }
      } catch (e) {
        // 激活失败则触发录音实例重置
        await _resetRecorder();
      }
    }
  });
}

// 重置录音实例的方法
Future<void> _resetRecorder() async {
  if (recorder != null) {
    await recorder.dispose();
  }
  // 重新创建录音实例并初始化
  recorder = Recorder();
  await recorder.start(const RecordConfig(), path: '你的录音文件路径');
}

2. 捕获错误后直接重置录音实例

如果第一次恢复失败(比如你说的短暂工作后停止),别反复调用resume,直接 dispose 旧的录音实例重新创建——因为旧实例已经和失效的音频会话绑定了,复用只会触发资源冲突。

你可以在捕获到-10868错误时自动触发重置:

try {
  await recorder.resume();
} on PlatformException catch (e) {
  if (e.code == 'record' && e.message?.contains('-10868') == true) {
    // 触发录音实例重置
    await _resetRecorder();
  }
}

3. 确保音频会话配置匹配场景

初始化录音前,一定要设置正确的音频会话类别和模式,语音录音场景推荐用spokenAudio模式,它对通话类中断的兼容性更好:

void _setupAudioSession() async {
  final session = await AudioSession.instance;
  await session.configure(const AudioSessionConfiguration(
    category: AudioSessionCategory.playAndRecord,
    mode: AudioSessionMode.spokenAudio,
    options: AudioSessionOptions(
      mixWithOthers: false, // 不要和其他音频混合,确保录音优先级
      allowBluetooth: true, // 按需开启,支持蓝牙麦克风
    ),
  ));
}

4. 调试技巧:查看Xcode控制台的音频日志

如果还是不行,打开Xcode连接测试设备,运行应用后在Console面板过滤AVAudioSession或audio_session关键词,你能看到系统何时抢占了音频会话、应用会话的激活/失活状态变化,甚至能定位到具体哪个步骤导致了资源冲突,比瞎试代码高效多了。

我当时就是靠Xcode日志发现,中断结束后系统没有自动恢复我的会话激活状态,手动加了setActive(true)后就解决了问题。

如果这些方案都试过还是不行,可以把你的完整中断处理和录音初始化代码贴出来,我再帮你抠细节~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 12:24:33