Browse Source

fix(ios): 修复音频会话配置以正确处理音乐播放和TTS的音频打断

修改音乐服务插件,移除音频会话的 mixWithOthers 选项,使应用播放音乐时能打断外部音乐
在播放、恢复、切换歌曲时重新设置音频会话,确保正确激活
在停止播放时停用音频会话并通知其他应用恢复播放

修改语音插件,在TTS播放时使用 mixWithOthers 替代 duckOthers 选项
添加空闲时停用音频会话的逻辑,避免影响其他应用的音频播放
同时更新应用版本号至 1.0.22
weicu
liwei1dao 8 months ago
parent
commit
60edd1c27b
  1. 19
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift
  2. 9
      local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift
  3. 2
      pubspec.yaml

19
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift

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

9
local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift

@ -57,11 +57,11 @@ public class MusicService: NSObject {
// MARK: - 音频会话设置
private func setupAudioSession() {
do {
// 设置音频会话类别,添加 mixWithOthers 选项以确保通知正常显示
// 设置音频会话类别:不使用 mixWithOthers,让本应用音乐播放时打断外部音乐
try AVAudioSession.sharedInstance().setCategory(
.playback,
mode: .default,
options: [.allowAirPlay, .allowBluetooth, .mixWithOthers]
options: [.allowAirPlay, .allowBluetooth]
)
try AVAudioSession.sharedInstance().setActive(true)
print("🎵 [MusicService] ✅ 音频会话设置成功")
@ -407,6 +407,8 @@ public class MusicService: NSObject {
print("开始播放: \(url), ID: \(currentIdInternal ?? 0)")
setupAudioSession()
// 检查是否已在播放列表中
let existingIndex = playlist.firstIndex { existingSong in
if let existingId = existingSong["id"] as? NSNumber,
@ -450,6 +452,7 @@ public class MusicService: NSObject {
}
public func resume() {
setupAudioSession()
player?.play()
isPlaying = true
updatePlaybackState()
@ -495,6 +498,7 @@ public class MusicService: NSObject {
updatePlaybackState()
updateMediaSessionPlaybackState(isPlaying: false)
stopProgressTimer()
_ = try? AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
print("已停止")
}
@ -969,6 +973,7 @@ public class MusicService: NSObject {
}
// 开始播放
setupAudioSession()
player?.play()
isPlaying = true
updateMediaSessionPlaybackState(isPlaying: true)

2
pubspec.yaml

@ -1,7 +1,7 @@
name: voitrans
description: "Voitrans - AI Voice Assistant."
publish_to: "none"
version: 1.0.21+72
version: 1.0.22+72
environment:
sdk: ">=3.3.0 <4.0.0"

Loading…
Cancel
Save