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

如何防止Callkit中断AVAudioPlayer?VoIP回铃音持续播放问题

解决CallKit激活音频会话时回铃音中断的问题

嗨,这个问题我之前做VoIP应用的时候也踩过坑!CallKit激活音频会话时确实会默认打断正在播放的音频,这是系统优先保障通话音频通路的机制导致的。给你几个实际可行的解决思路:

1. 调整AVAudioSession配置,允许音频混合

首先,初始化音频会话时一定要加上.mixWithOthers选项,让回铃音能和CallKit的通话音频共存。修改你的configure()方法:

func configure() {
    do {
        try AVAudioSession.sharedInstance().setCategory(
            AVAudioSessionCategoryPlayAndRecord,
            mode: AVAudioSessionModeVideoChat,
            options: [.mixWithOthers, .allowBluetooth, .defaultToSpeaker]
        )
        try AVAudioSession.sharedInstance().setActive(true)
    } catch {
        print("音频会话配置失败:\(error.localizedDescription)")
    }
}

注:defaultToSpeaker是可选配置,如果你希望回铃音从扬声器播放可以加上,按需调整即可。

2. 在CallKit激活会话后重启回铃音

当CallKit调用didActivate:audioSession时,系统已经接管了音频会话,之前的AVAudioPlayer会被中断。你需要在这个方法里重新启动回铃音,同时别忘了先激活Twilio的音频设备:

func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
    // 先激活Twilio音频设备,保障通话音频正常
    TwilioVoiceSDK.audioDevice?.activate(audioSession)
    
    // 重启回铃音播放
    do {
        try audioSession.setActive(true)
        // 确保回铃音播放器设置为循环播放(numberOfLoops = -1)
        self.ringtonePlayer?.numberOfLoops = -1
        self.ringtonePlayer?.play()
    } catch {
        print("重启回铃音失败:\(error.localizedDescription)")
    }
}

3. 监听音频会话中断,自动恢复播放

系统可能会因为其他场景(比如来电、切换音频输出)中断音频会话,这时候要监听中断通知,在中断结束后自动恢复回铃音:

// 在初始化逻辑里添加通知监听
NotificationCenter.default.addObserver(
    self,
    selector: #selector(handleAudioSessionInterruption(_:)),
    name: AVAudioSession.interruptionNotification,
    object: nil
)

// 处理音频会话中断的方法
@objc private func handleAudioSessionInterruption(_ notification: Notification) {
    guard let info = notification.userInfo else { return }
    
    // 判断中断类型
    if let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
       let type = AVAudioSession.InterruptionType(rawValue: typeValue) {
        
        if type == .ended {
            // 中断结束,尝试恢复回铃音播放
            if let optionValue = info[AVAudioSessionInterruptionOptionKey] as? UInt {
                let options = AVAudioSession.InterruptionOptions(rawValue: optionValue)
                if options.contains(.shouldResume) {
                    self.ringtonePlayer?.play()
                }
            }
        }
    }
}

4. 同步Twilio SDK的音频状态

Twilio Voice SDK本身会管理音频会话,要确保回铃音播放时机和Twilio的状态同步:

  • 不要在发起呼叫请求前就启动回铃音,建议在收到CallKit的didStartCall回调或Twilio呼叫连接中的状态通知后再启动。
  • 当呼叫接通后,记得立刻停止回铃音播放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:48:23