Swift中如何停止系统默认来电铃声并播放自定义铃声?
来电时播放自定义铃声但系统默认铃声仍在后台播放,如何停止?
我在来电时使用AVPlayer播放自定义铃声,但后台仍会播放系统默认铃声,请问如何停止系统的默认铃声?
相关代码
自定义铃声播放代码
var player: AVPlayer? func playSound() { let url = Bundle.main.url(forResource: "Hold Music", withExtension: "mp3")! do { let audioSession = AVAudioSession.sharedInstance() try audioSession.setActive(false, options: []) try audioSession.setCategory(.playback,mode: .default, options: .mixWithOthers) try audioSession.setActive(true) let playerItem:AVPlayerItem = AVPlayerItem(url: url) player = AVPlayer(playerItem: playerItem) player?.volume = 1 player?.play() } catch let error { print("lool \(error.localizedDescription)") } }
通话状态监听代码
extension LandingViewController: CXCallObserverDelegate{ func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) { if call.hasEnded == true { player?.pause() print("call Disconnected") } if call.isOutgoing == true && call.hasConnected == false { print("call Dialing") player?.pause() } if call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false { print("call Incoming") self.playSound() } if call.hasConnected == true && call.hasEnded == false { print("call Connected") player?.pause() } } }
问题原因
你当前的音频会话配置使用了.mixWithOthers选项,这会允许系统默认铃声与自定义铃声同时播放,无法中断系统铃声;同时代码中存在语法错误,也会影响功能正常执行。
解决方案
1. 修改音频会话配置,抢占音频焦点
移除.mixWithOthers选项,调整音频会话激活逻辑,确保自定义铃声播放时能中断系统铃声:
var player: AVPlayer? func playSound() { guard let url = Bundle.main.url(forResource: "Hold Music", withExtension: "mp3") else { print("无法找到目标音频文件") return } do { let audioSession = AVAudioSession.sharedInstance() // 先停用当前会话,避免冲突 try audioSession.setActive(false, options: .notifyOthersOnDeactivation) // 设置音频会话为播放类别,不允许混音,确保抢占音频焦点 try audioSession.setCategory(.playback, mode: .default) // 激活会话,强制中断语音类音频(如系统来电铃声) try audioSession.setActive(true, options: .interruptSpokenAudioAndMixWithOthers) let playerItem = AVPlayerItem(url: url) player = AVPlayer(playerItem: playerItem) player?.volume = 1 player?.play() } catch let error { print("音频播放错误:\(error.localizedDescription)") } }
2. 修正通话状态监听代码的语法错误
原代码存在多余的闭合括号,修正后如下:
extension LandingViewController: CXCallObserverDelegate { func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) { if call.hasEnded == true { player?.pause() print("call Disconnected") } if call.isOutgoing == true && call.hasConnected == false { print("call Dialing") player?.pause() } if call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false { print("call Incoming") self.playSound() } if call.hasConnected == true && call.hasEnded == false { print("call Connected") player?.pause() } } }
3. 额外优化:监听音频会话中断
添加音频会话中断通知,确保系统音频抢占时自动暂停自定义铃声:
// 在ViewController的viewDidLoad方法中添加监听 override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(handleAudioSessionInterruption(_:)), name: AVAudioSession.interruptionNotification, object: AVAudioSession.sharedInstance()) } // 处理音频中断的方法 @objc func handleAudioSessionInterruption(_ notification: Notification) { guard let info = notification.userInfo, let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt, let type = AVAudioSession.InterruptionType(rawValue: typeValue) else { return } if type == .began { // 音频会话被中断,暂停自定义铃声 player?.pause() } }
内容的提问来源于stack exchange,提问作者Sourav Chakraborty
相关产品推荐
相关产品推荐

