From bf631f6d7ad697d2d05f2bd826e22c6498aee7e9 Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Tue, 28 Oct 2025 11:48:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E9=9F=B3=E4=B9=90=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent_service/AudioSessionHub.swift | 11 ++ .../Sources/music_service/MusicService.swift | 121 ++++++------------ 2 files changed, 52 insertions(+), 80 deletions(-) diff --git a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AudioSessionHub.swift b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AudioSessionHub.swift index 65cbf38af..c0364b79c 100644 --- a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AudioSessionHub.swift +++ b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AudioSessionHub.swift @@ -50,6 +50,7 @@ public class AudioSessionHub { os_log("已设置系统音量绑定监听", log: logger, type: .info) } + /** * 同步应用音量与系统音量 * @param systemVolume 系统音量值 (0.0 - 1.0) @@ -586,6 +587,16 @@ public class AudioSessionHub { os_log(" - 当前类别: %{public}@", log: logger, type: .info, audioSession.category.rawValue) os_log(" - 当前模式: %{public}@", log: logger, type: .info, audioSession.mode.rawValue) + // 发送中断结束通知给其他服务,包含恢复建议 + NotificationCenter.default.post( + name: NSNotification.Name("AudioSessionInterruptionEnded"), + object: nil, + userInfo: [ + "type": "ended", + "shouldResume": false, + "options": 0 + ] + ) case .override: os_log("🔀 音频路由被覆盖", log: logger, type: .info) diff --git a/local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift b/local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift index 40bcfbc9e..226cf7d1f 100644 --- a/local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift +++ b/local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift @@ -9,6 +9,7 @@ import Foundation import AVFoundation import MediaPlayer import UIKit +//import CallKit public class MusicService: NSObject { public static let shared: MusicService = MusicService() @@ -35,11 +36,15 @@ public class MusicService: NSObject { // 音频中断处理相关 private var interruptedDuringPlayback: Bool = false +// private let callObserver = CXCallObserver() + private override init() { super.init() setupRemoteCommandCenter() setupAudioSession() setupNotificationObservers() + // 监听通话状态(需主线程队列) +// callObserver.setDelegate(self, queue: DispatchQueue.main) } public func initialize(serviceUrl: String, userToken: String) { @@ -103,6 +108,9 @@ public class MusicService: NSObject { print("🎵 [MusicService] ✅ 已注册AudioSessionHub_ResumeMusicPlayback通知") } + + + // MARK: - 基础播放控制 func getCurrentUrlString() -> String? { guard let urlAsset = player?.currentItem?.asset as? AVURLAsset else { @@ -1003,96 +1011,24 @@ public class MusicService: NSObject { @objc private func handleAudioSessionHubInterruption(_ notification: Notification) { interruptedDuringPlayback = isPlaying pause() - print("🎵 [MusicService] 收到AudioSessionHub中断开始通知") + print("🎵 [MusicService] 收到AudioSessionHub中断开始通知:\(interruptedDuringPlayback)") // AudioSessionHub已经处理了中断开始,我们这里可以做额外的处理 } // 处理AudioSessionHub发送的中断结束通知 @objc private func handleAudioSessionHubInterruptionEnded(_ notification: Notification) { - print("🎵 [MusicService] 收到AudioSessionHub中断结束通知") - - guard let userInfo = notification.userInfo else { - print("🎵 [MusicService] AudioSessionHub通知缺少userInfo") - return - } - - let shouldResume = userInfo["shouldResume"] as? Bool ?? false - let options = userInfo["options"] as? UInt ?? 0 - - print("🎵 [MusicService] AudioSessionHub建议恢复: \(shouldResume), 选项: \(options)") - print("🎵 [MusicService] 中断前播放状态: \(interruptedDuringPlayback)") - - // 只有在中断前正在播放且系统建议恢复时才恢复播放 - if interruptedDuringPlayback && shouldResume { - print("🎵 [MusicService] 准备恢复音乐播放...") - - // 延迟恢复,给AudioSessionHub时间完成音频会话重新激活 - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in - guard let self = self else { return } - - do { - // 设置音频会话为播放模式 -// let audioSession = AVAudioSession.sharedInstance() -// try audioSession.setCategory(.playback, mode: .default, options: [.mixWithOthers]) -// try audioSession.setActive(true, options: []) - print("🎵 [MusicService] 音频会话已设置为播放模式") - - // 恢复播放 - self.resume() - print("🎵 [MusicService] 已恢复音乐播放") - self.interruptedDuringPlayback = false - } catch { - print("🎵 [MusicService] 设置音频会话失败: \(error)") - - // 即使设置失败也尝试恢复播放 - self.resume() - print("🎵 [MusicService] 已尝试恢复音乐播放(音频会话设置失败)") - self.interruptedDuringPlayback = false - } - } - } else if !shouldResume { - print("🎵 [MusicService] AudioSessionHub不建议恢复,保持暂停状态") - interruptedDuringPlayback = false - } else { - print("🎵 [MusicService] 中断前未在播放,不恢复") + print("🎵 [MusicService] 收到AudioSessionHub中断结束通知:\(interruptedDuringPlayback)") + if (interruptedDuringPlayback){ + self.resume() interruptedDuringPlayback = false } } @objc private func handleAudioSessionHubResumeMusicPlayback(_ notification: Notification) { - print("🎵 [MusicService] ✅ 收到AudioSessionHub恢复播放通知") - print("🎵 [MusicService] 当前状态 - interruptedDuringPlayback: \(interruptedDuringPlayback), isPlaying: \(isPlaying)") - - // 简化逻辑:只要收到通知且之前被中断,就尝试恢复 - if interruptedDuringPlayback { - print("🎵 [MusicService] 开始恢复音乐播放...") - - // 延迟一点时间确保音频会话已经正确设置 - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in - guard let self = self else { return } - - do { - // 设置音频会话为播放模式 -// let audioSession = AVAudioSession.sharedInstance() -// try audioSession.setCategory(.playback, mode: .default, options: [.mixWithOthers]) -// try audioSession.setActive(true, options: []) - print("🎵 [MusicService] 音频会话已设置为播放模式") - - // 恢复播放 - self.resume() - print("🎵 [MusicService] ✅ 已恢复音乐播放") - self.interruptedDuringPlayback = false - } catch { - print("🎵 [MusicService] ❌ 设置音频会话失败: \(error)") - - // 即使设置失败也尝试恢复播放 - self.resume() - print("🎵 [MusicService] ⚠️ 已尝试恢复音乐播放(音频会话设置失败)") - self.interruptedDuringPlayback = false - } - } - } else { - print("🎵 [MusicService] ℹ️ 不需要恢复播放 - interruptedDuringPlayback: \(interruptedDuringPlayback)") + print("🎵 [MusicService] ✅ 收到AudioSessionHub恢复播放通知:\(interruptedDuringPlayback)") + if (interruptedDuringPlayback){ + self.resume() + interruptedDuringPlayback = false } } @@ -1116,3 +1052,28 @@ public class MusicService: NSObject { ) } } + +// 实现 CXCallObserverDelegate +//extension MusicService: CXCallObserverDelegate { +// public func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) { +// // 检测通话开始(来电被接听 或 呼出被接通) +// if call.hasConnected && !call.hasEnded { +// // 记录播放状态(避免重复标记,仅在通话刚连接时标记) +// if !call.hasEnded { // 确保是通话开始而非结束 +// self.interruptedDuringPlayback = isPlaying +// if isPlaying { +// print("检测到通话开始,暂停音乐") +// pause() +// } +// } +// } +// // 通话结束且当前无其他活跃通话 +// if call.hasEnded && call.hasConnected { +// // 确保播放器处于暂停状态再恢复 +// if self.interruptedDuringPlayback { +// print("检测到通话结束,恢复音乐") +// self.resume() +// } +// } +// } +//}