|
|
@ -1413,6 +1413,7 @@ private let audioSessionQueueKey = DispatchSpecificKey<UInt8>() |
|
|
private var audioSessionQueueKeySet = false |
|
|
private var audioSessionQueueKeySet = false |
|
|
private var audioInterrupted = false |
|
|
private var audioInterrupted = false |
|
|
private var audioSessionObserversAdded = false |
|
|
private var audioSessionObserversAdded = false |
|
|
|
|
|
private var shouldDeactivateAudioSessionWhenIdle = false |
|
|
// 新增:路由变化的去抖与配置重入保护标记 |
|
|
// 新增:路由变化的去抖与配置重入保护标记 |
|
|
private var routeChangeDebounceWorkItem: DispatchWorkItem? |
|
|
private var routeChangeDebounceWorkItem: DispatchWorkItem? |
|
|
private var isApplyingAudioSessionConfig = false |
|
|
private var isApplyingAudioSessionConfig = false |
|
|
@ -1471,6 +1472,7 @@ private func applyAudioSessionForTTS() -> Bool { |
|
|
let otherAudioPlaying = audioSession.isOtherAudioPlaying |
|
|
let otherAudioPlaying = audioSession.isOtherAudioPlaying |
|
|
let isRecording = (self.micCapture?.isCapturing == true) |
|
|
let isRecording = (self.micCapture?.isCapturing == true) |
|
|
self.isHeadphones = hasHeadphones |
|
|
self.isHeadphones = hasHeadphones |
|
|
|
|
|
self.shouldDeactivateAudioSessionWhenIdle = otherAudioPlaying |
|
|
|
|
|
|
|
|
let desiredCategory: AVAudioSession.Category |
|
|
let desiredCategory: AVAudioSession.Category |
|
|
let desiredMode: AVAudioSession.Mode |
|
|
let desiredMode: AVAudioSession.Mode |
|
|
@ -1490,7 +1492,7 @@ private func applyAudioSessionForTTS() -> Bool { |
|
|
desiredOptions = [.allowBluetooth, .defaultToSpeaker] |
|
|
desiredOptions = [.allowBluetooth, .defaultToSpeaker] |
|
|
} |
|
|
} |
|
|
if otherAudioPlaying { |
|
|
if otherAudioPlaying { |
|
|
desiredOptions.insert(.duckOthers) |
|
|
desiredOptions.insert(.mixWithOthers) |
|
|
} |
|
|
} |
|
|
} else if self.currentRecognitionMode == "push_to_talk" || self.currentRecognitionMode == "normal" || self.currentRecognitionMode == "ble_wakeup" { |
|
|
} else if self.currentRecognitionMode == "push_to_talk" || self.currentRecognitionMode == "normal" || self.currentRecognitionMode == "ble_wakeup" { |
|
|
if isRecording { |
|
|
if isRecording { |
|
|
@ -1500,7 +1502,7 @@ private func applyAudioSessionForTTS() -> Bool { |
|
|
desiredCategory = .playback |
|
|
desiredCategory = .playback |
|
|
desiredMode = .spokenAudio |
|
|
desiredMode = .spokenAudio |
|
|
if otherAudioPlaying { |
|
|
if otherAudioPlaying { |
|
|
desiredOptions.insert(.duckOthers) |
|
|
desiredOptions.insert(.mixWithOthers) |
|
|
} |
|
|
} |
|
|
} else if isRecording { |
|
|
} else if isRecording { |
|
|
desiredCategory = .playAndRecord |
|
|
desiredCategory = .playAndRecord |
|
|
@ -1515,13 +1517,13 @@ private func applyAudioSessionForTTS() -> Bool { |
|
|
desiredOptions.insert(.defaultToSpeaker) |
|
|
desiredOptions.insert(.defaultToSpeaker) |
|
|
} |
|
|
} |
|
|
if otherAudioPlaying { |
|
|
if otherAudioPlaying { |
|
|
desiredOptions.insert(.duckOthers) |
|
|
desiredOptions.insert(.mixWithOthers) |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
desiredCategory = .playback |
|
|
desiredCategory = .playback |
|
|
desiredMode = .spokenAudio |
|
|
desiredMode = .spokenAudio |
|
|
if otherAudioPlaying { |
|
|
if otherAudioPlaying { |
|
|
desiredOptions.insert(.duckOthers) |
|
|
desiredOptions.insert(.mixWithOthers) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -1551,7 +1553,7 @@ private func applyAudioSessionForTTS() -> Bool { |
|
|
try audioSession.setActive(true) |
|
|
try audioSession.setActive(true) |
|
|
} catch { |
|
|
} catch { |
|
|
do { |
|
|
do { |
|
|
try audioSession.setCategory(.playback, mode: .default, options: []) |
|
|
try audioSession.setCategory(.playback, mode: .default, options: [.mixWithOthers]) |
|
|
try audioSession.setActive(true) |
|
|
try audioSession.setActive(true) |
|
|
} catch { |
|
|
} catch { |
|
|
success = false |
|
|
success = false |
|
|
@ -1645,6 +1647,13 @@ private func deactivateAudioSessionAfterTTSIfIdle() { |
|
|
self.audioEngine = nil |
|
|
self.audioEngine = nil |
|
|
self.playerNode = nil |
|
|
self.playerNode = nil |
|
|
self.pcmFormat = nil |
|
|
self.pcmFormat = nil |
|
|
|
|
|
if self.shouldDeactivateAudioSessionWhenIdle { |
|
|
|
|
|
do { |
|
|
|
|
|
try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation) |
|
|
|
|
|
} catch { |
|
|
|
|
|
} |
|
|
|
|
|
self.shouldDeactivateAudioSessionWhenIdle = false |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if DispatchQueue.getSpecific(key: audioSessionQueueKey) != nil { |
|
|
if DispatchQueue.getSpecific(key: audioSessionQueueKey) != nil { |
|
|
|