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

