Swift中AVAudio是否存在可检测其他声音播放的相关代理?
解决方法
没有专门的「其他音频播放状态」AVAudio代理回调,但可以通过以下两种AVAudioSession相关能力完全覆盖你的需求:
方案1:监听音频中断通知(优先推荐,无性能损耗)
当系统有其他优先级更高的音频(铃声、第三方音乐播放、语音助手唤醒、通话等)抢占音频会话时,系统会自动触发AVAudioSessionInterruptionNotification通知,你可以在中断开始回调中停止录音,中断结束后根据业务需要判断是否恢复录音。
代码示例:
// Swift 注册监听 NotificationCenter.default.addObserver(self, selector: #selector(handleAudioInterruption(notification:)), name: AVAudioSession.interruptionNotification, object: AVAudioSession.sharedInstance())
// Objective-C 注册监听 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAudioInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
回调处理逻辑:
- 从通知的userInfo中读取
AVAudioSessionInterruptionTypeKey字段值- 值为
AVAudioSessionInterruptionTypeBegan:其他音频抢占会话,立即停止AVAudioEngine录音、断开输入节点tap并释放相关资源 - 值为
AVAudioSessionInterruptionTypeEnded:中断结束,可根据业务需要决定是否恢复录音
- 值为
该方案可以覆盖所有系统主动抢占音频会话的场景,包括你提到的突然播放音乐、响起铃声的情况。
方案2:主动检测其他音频播放状态
如果需要在录音启动前做前置校验,或者需要自定义轮询检测逻辑,可以读取AVAudioSession的isOtherAudioPlaying属性(iOS 8.0+支持):
// 返回true即代表当前有其他App的音频正在播放 let hasOtherPlayingAudio = AVAudioSession.sharedInstance().isOtherAudioPlaying
该方案适合按需主动查询的场景,不建议高频轮询使用,性能劣于方案1的通知回调。
注意事项
- 录音场景需要先将AVAudioSession的category设置为
record或playAndRecord,并配置合理的优先级选项,避免和系统音频逻辑冲突 - 收到中断通知后必须先停止AVAudioEngine运行,再做资源释放操作,否则会触发底层异常崩溃
内容的提问来源于stack exchange,提问作者Alireza12t
相关产品推荐
相关产品推荐

