Browse Source

去处ai音源切换

weicu
fdp 1 year ago
parent
commit
62b2040dc5
  1. 4
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift
  2. 330
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AudioSessionHub.swift

4
local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift

@ -375,9 +375,9 @@ class AgentServiceImpl: NSObject {
let audioSourceType: AzureAsrHelper.AudioSourceType = useBle ? .external : .microphone
if useBle {
AudioSessionHub.shared.begin(.playback)
// AudioSessionHub.shared.begin(.playback)
} else {
AudioSessionHub.shared.begin(.voice)
//AudioSessionHub.shared.begin(.voice)
}
print("ai启动语音=\(audioSourceType)=\(useBle)")
guard let success = azureAsrHelper?.startContinuousRecognition(

330
local_plugins/agent_service/ios/agent_service/Sources/agent_service/AudioSessionHub.swift

@ -28,196 +28,196 @@ public class AudioSessionHub {
_ = shared // 触发单例初始化
}
public func begin(_ intent: AudioIntent) {
if intent == currentIntent && audioSession.isOtherAudioPlaying == false {
os_log("音频意图未变化且无其他音频播放,跳过设置: %{public}@", log: logger, type: .debug, String(describing: intent))
return
}
// public func begin(_ intent: AudioIntent) {
// if intent == currentIntent && audioSession.isOtherAudioPlaying == false {
// os_log("音频意图未变化且无其他音频播放,跳过设置: %{public}@", log: logger, type: .debug, String(describing: intent))
// return
// }
os_log("开始设置音频会话,意图: %{public}@", log: logger, type: .info, String(describing: intent))
currentIntent = intent
// os_log("开始设置音频会话,意图: %{public}@", log: logger, type: .info, String(describing: intent))
// currentIntent = intent
do {
switch intent {
// do {
// switch intent {
case .voice:
os_log("设置语音模式: category=playAndRecord, mode=voiceChat", log: logger, type: .info)
// case .voice:
// os_log("设置语音模式: category=playAndRecord, mode=voiceChat", log: logger, type: .info)
// 第一步:设置音频类别和模式
try audioSession.setCategory(.playAndRecord,
mode: .voiceChat,
options: [.allowBluetooth, .defaultToSpeaker, .mixWithOthers])
os_log("✓ 音频类别设置成功: playAndRecord + voiceChat", log: logger, type: .info)
// // 第一步:设置音频类别和模式
// try audioSession.setCategory(.playAndRecord,
// mode: .voiceChat,
// options: [.allowBluetooth, .defaultToSpeaker, .mixWithOthers])
// os_log("✓ 音频类别设置成功: playAndRecord + voiceChat", log: logger, type: .info)
// 第二步:检查并设置蓝牙输入
os_log("检查可用输入设备...", log: logger, type: .info)
if let availableInputs = audioSession.availableInputs {
os_log("可用输入设备数量: %d", log: logger, type: .info, availableInputs.count)
for (index, input) in availableInputs.enumerated() {
os_log("输入设备[%d]: %{public}@ (%{public}@)", log: logger, type: .info,
index, input.portName, input.portType.rawValue)
}
// // 第二步:检查并设置蓝牙输入
// os_log("检查可用输入设备...", log: logger, type: .info)
// if let availableInputs = audioSession.availableInputs {
// os_log("可用输入设备数量: %d", log: logger, type: .info, availableInputs.count)
// for (index, input) in availableInputs.enumerated() {
// os_log("输入设备[%d]: %{public}@ (%{public}@)", log: logger, type: .info,
// index, input.portName, input.portType.rawValue)
// }
// 查找蓝牙HFP设备
if let bluetoothInput = availableInputs.first(where: { $0.portType == .bluetoothHFP }) {
os_log("找到蓝牙HFP设备,尝试设置为首选输入: %{public}@", log: logger, type: .info, bluetoothInput.portName)
try audioSession.setPreferredInput(bluetoothInput)
os_log("✓ 蓝牙HFP输入设置成功: %{public}@", log: logger, type: .info, bluetoothInput.portName)
} else {
os_log("未找到蓝牙HFP设备", log: logger, type: .info)
}
} else {
os_log("⚠️ availableInputs 为 nil", log: logger, type: .default)
}
// // 查找蓝牙HFP设备
// if let bluetoothInput = availableInputs.first(where: { $0.portType == .bluetoothHFP }) {
// os_log("找到蓝牙HFP设备,尝试设置为首选输入: %{public}@", log: logger, type: .info, bluetoothInput.portName)
// try audioSession.setPreferredInput(bluetoothInput)
// os_log("✓ 蓝牙HFP输入设置成功: %{public}@", log: logger, type: .info, bluetoothInput.portName)
// } else {
// os_log("未找到蓝牙HFP设备", log: logger, type: .info)
// }
// } else {
// os_log("⚠️ availableInputs 为 nil", log: logger, type: .default)
// }
case .playback:
os_log("设置播放模式: category=playback, mode=default", log: logger, type: .info)
// case .playback:
// os_log("设置播放模式: category=playback, mode=default", log: logger, type: .info)
// 检查当前音频会话状态
os_log("设置前状态检查:", log: logger, type: .info)
os_log(" - 当前类别: %{public}@", log: logger, type: .info, audioSession.category.rawValue)
os_log(" - 当前模式: %{public}@", log: logger, type: .info, audioSession.mode.rawValue)
os_log(" - 当前是否激活: %{public}@", log: logger, type: .info, audioSession.isOtherAudioPlaying ? "是" : "否")
os_log(" - 其他音频播放: %{public}@", log: logger, type: .info, audioSession.isOtherAudioPlaying ? "是" : "否")
// // 检查当前音频会话状态
// os_log("设置前状态检查:", log: logger, type: .info)
// os_log(" - 当前类别: %{public}@", log: logger, type: .info, audioSession.category.rawValue)
// os_log(" - 当前模式: %{public}@", log: logger, type: .info, audioSession.mode.rawValue)
// os_log(" - 当前是否激活: %{public}@", log: logger, type: .info, audioSession.isOtherAudioPlaying ? "是" : "否")
// os_log(" - 其他音频播放: %{public}@", log: logger, type: .info, audioSession.isOtherAudioPlaying ? "是" : "否")
// 如果当前已经激活,先尝试停用
do {
if audioSession.isOtherAudioPlaying {
os_log("检测到其他音频正在播放,先尝试停用当前会话", log: logger, type: .info)
try audioSession.setActive(false, options: .notifyOthersOnDeactivation)
os_log("✓ 成功停用当前音频会话", log: logger, type: .info)
}
} catch let deactivateError as NSError {
os_log("⚠️ 停用当前音频会话失败: %{public}@ (继续尝试设置)", log: logger, type: .default, deactivateError.localizedDescription)
}
// // 如果当前已经激活,先尝试停用
// do {
// if audioSession.isOtherAudioPlaying {
// os_log("检测到其他音频正在播放,先尝试停用当前会话", log: logger, type: .info)
// try audioSession.setActive(false, options: .notifyOthersOnDeactivation)
// os_log("✓ 成功停用当前音频会话", log: logger, type: .info)
// }
// } catch let deactivateError as NSError {
// os_log("⚠️ 停用当前音频会话失败: %{public}@ (继续尝试设置)", log: logger, type: .default, deactivateError.localizedDescription)
// }
// 尝试渐进式设置:先尝试最简单的设置
var settingSuccess = false
// // 尝试渐进式设置:先尝试最简单的设置
// var settingSuccess = false
// 策略1: 只设置类别,不设置选项
if !settingSuccess {
do {
os_log("尝试策略1: 仅设置类别 (playback)", log: logger, type: .info)
try audioSession.setCategory(.playback)
os_log("✓ 策略1成功: 音频类别设置为 playback", log: logger, type: .info)
settingSuccess = true
} catch let error as NSError {
os_log("策略1失败: %{public}@ (OSStatus: %d)", log: logger, type: .info, error.localizedDescription, error.code)
}
}
// // 策略1: 只设置类别,不设置选项
// if !settingSuccess {
// do {
// os_log("尝试策略1: 仅设置类别 (playback)", log: logger, type: .info)
// try audioSession.setCategory(.playback)
// os_log("✓ 策略1成功: 音频类别设置为 playback", log: logger, type: .info)
// settingSuccess = true
// } catch let error as NSError {
// os_log("策略1失败: %{public}@ (OSStatus: %d)", log: logger, type: .info, error.localizedDescription, error.code)
// }
// }
// 策略2: 设置类别和模式,不设置选项
if !settingSuccess {
do {
os_log("尝试策略2: 设置类别和模式 (playback + default)", log: logger, type: .info)
try audioSession.setCategory(.playback, mode: .default)
os_log("✓ 策略2成功: 音频类别和模式设置完成", log: logger, type: .info)
settingSuccess = true
} catch let error as NSError {
os_log("策略2失败: %{public}@ (OSStatus: %d)", log: logger, type: .info, error.localizedDescription, error.code)
}
}
// // 策略2: 设置类别和模式,不设置选项
// if !settingSuccess {
// do {
// os_log("尝试策略2: 设置类别和模式 (playback + default)", log: logger, type: .info)
// try audioSession.setCategory(.playback, mode: .default)
// os_log("✓ 策略2成功: 音频类别和模式设置完成", log: logger, type: .info)
// settingSuccess = true
// } catch let error as NSError {
// os_log("策略2失败: %{public}@ (OSStatus: %d)", log: logger, type: .info, error.localizedDescription, error.code)
// }
// }
// 策略3: 设置类别、模式和单个选项
if !settingSuccess {
do {
os_log("尝试策略3: 设置类别、模式和混音选项", log: logger, type: .info)
try audioSession.setCategory(.playback, mode: .default, options: [.mixWithOthers])
os_log("✓ 策略3成功: 音频类别、模式和混音选项设置完成", log: logger, type: .info)
settingSuccess = true
} catch let error as NSError {
os_log("策略3失败: %{public}@ (OSStatus: %d)", log: logger, type: .info, error.localizedDescription, error.code)
}
}
// // 策略3: 设置类别、模式和单个选项
// if !settingSuccess {
// do {
// os_log("尝试策略3: 设置类别、模式和混音选项", log: logger, type: .info)
// try audioSession.setCategory(.playback, mode: .default, options: [.mixWithOthers])
// os_log("✓ 策略3成功: 音频类别、模式和混音选项设置完成", log: logger, type: .info)
// settingSuccess = true
// } catch let error as NSError {
// os_log("策略3失败: %{public}@ (OSStatus: %d)", log: logger, type: .info, error.localizedDescription, error.code)
// }
// }
// 策略4: 设置类别、模式和蓝牙选项
if !settingSuccess {
do {
os_log("尝试策略4: 设置类别、模式和蓝牙选项", log: logger, type: .info)
try audioSession.setCategory(.playback, mode: .default, options: [.allowBluetoothA2DP])
os_log("✓ 策略4成功: 音频类别、模式和蓝牙选项设置完成", log: logger, type: .info)
settingSuccess = true
} catch let error as NSError {
os_log("策略4失败: %{public}@ (OSStatus: %d)", log: logger, type: .info, error.localizedDescription, error.code)
}
}
// // 策略4: 设置类别、模式和蓝牙选项
// if !settingSuccess {
// do {
// os_log("尝试策略4: 设置类别、模式和蓝牙选项", log: logger, type: .info)
// try audioSession.setCategory(.playback, mode: .default, options: [.allowBluetoothA2DP])
// os_log("✓ 策略4成功: 音频类别、模式和蓝牙选项设置完成", log: logger, type: .info)
// settingSuccess = true
// } catch let error as NSError {
// os_log("策略4失败: %{public}@ (OSStatus: %d)", log: logger, type: .info, error.localizedDescription, error.code)
// }
// }
// 策略5: 完整设置(原始方案)
if !settingSuccess {
os_log("尝试策略5: 完整设置 (playback + default + 所有选项)", log: logger, type: .info)
try audioSession.setCategory(.playback,
mode: .default,
options: [.allowBluetoothA2DP, .mixWithOthers])
os_log("✓ 策略5成功: 完整音频设置完成", log: logger, type: .info)
settingSuccess = true
}
// // 策略5: 完整设置(原始方案)
// if !settingSuccess {
// os_log("尝试策略5: 完整设置 (playback + default + 所有选项)", log: logger, type: .info)
// try audioSession.setCategory(.playback,
// mode: .default,
// options: [.allowBluetoothA2DP, .mixWithOthers])
// os_log("✓ 策略5成功: 完整音频设置完成", log: logger, type: .info)
// settingSuccess = true
// }
if !settingSuccess {
os_log("❌ 所有设置策略都失败了", log: logger, type: .error)
throw NSError(domain: "AudioSessionHub", code: -1, userInfo: [NSLocalizedDescriptionKey: "所有音频类别设置策略都失败"])
}
// if !settingSuccess {
// os_log("❌ 所有设置策略都失败了", log: logger, type: .error)
// throw NSError(domain: "AudioSessionHub", code: -1, userInfo: [NSLocalizedDescriptionKey: "所有音频类别设置策略都失败"])
// }
}
// }
// 第三步:激活音频会话
os_log("尝试激活音频会话...", log: logger, type: .info)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
os_log("✓ 音频会话激活成功", log: logger, type: .info)
// // 第三步:激活音频会话
// os_log("尝试激活音频会话...", log: logger, type: .info)
// try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
// os_log("✓ 音频会话激活成功", log: logger, type: .info)
os_log("✅ 音频会话完整设置成功:%{public}@", log: logger, type: .info, String(describing: intent))
// os_log("✅ 音频会话完整设置成功:%{public}@", log: logger, type: .info, String(describing: intent))
// 输出当前音频路由信息
let hasBluetoothDevice = hasBluetoothAudioDevice()
let hasBluetoothMic = hasBluetoothMicrophone()
let currentInput = getCurrentInputDevice()
// // 输出当前音频路由信息
// let hasBluetoothDevice = hasBluetoothAudioDevice()
// let hasBluetoothMic = hasBluetoothMicrophone()
// let currentInput = getCurrentInputDevice()
os_log("📊 音频状态总览:", log: logger, type: .info)
os_log(" - 蓝牙音频设备: %{public}@", log: logger, type: .info, hasBluetoothDevice ? "已连接" : "未连接")
os_log(" - 蓝牙麦克风: %{public}@", log: logger, type: .info, hasBluetoothMic ? "已连接" : "未连接")
os_log(" - 当前输入设备: %{public}@", log: logger, type: .info, currentInput)
// os_log("📊 音频状态总览:", log: logger, type: .info)
// os_log(" - 蓝牙音频设备: %{public}@", log: logger, type: .info, hasBluetoothDevice ? "已连接" : "未连接")
// os_log(" - 蓝牙麦克风: %{public}@", log: logger, type: .info, hasBluetoothMic ? "已连接" : "未连接")
// os_log(" - 当前输入设备: %{public}@", log: logger, type: .info, currentInput)
if hasBluetoothDevice {
os_log("📋 详细路由信息:\n%{public}@", log: logger, type: .debug, getCurrentAudioRoute())
}
} catch let error as NSError {
let osStatusCode = error.code
let domain = error.domain
let description = error.localizedDescription
// if hasBluetoothDevice {
// os_log("📋 详细路由信息:\n%{public}@", log: logger, type: .debug, getCurrentAudioRoute())
// }
// } catch let error as NSError {
// let osStatusCode = error.code
// let domain = error.domain
// let description = error.localizedDescription
os_log("❌ 设置音频会话失败", log: logger, type: .error)
os_log(" - 错误域: %{public}@", log: logger, type: .error, domain)
os_log(" - OSStatus代码: %d (0x%X)", log: logger, type: .error, osStatusCode, osStatusCode)
os_log(" - 错误描述: %{public}@", log: logger, type: .error, description)
os_log(" - 当前意图: %{public}@", log: logger, type: .error, String(describing: intent))
// os_log("❌ 设置音频会话失败", log: logger, type: .error)
// os_log(" - 错误域: %{public}@", log: logger, type: .error, domain)
// os_log(" - OSStatus代码: %d (0x%X)", log: logger, type: .error, osStatusCode, osStatusCode)
// os_log(" - 错误描述: %{public}@", log: logger, type: .error, description)
// os_log(" - 当前意图: %{public}@", log: logger, type: .error, String(describing: intent))
// 解析具体的 OSStatus 错误
switch osStatusCode {
case -50:
os_log(" ➤ 错误分析: OSStatus -50 通常表示参数错误 (kAudioSessionInvalidPropertyError)", log: logger, type: .error)
case -560557673: // kAudioSessionNotInitialized
os_log(" ➤ 错误分析: 音频会话未初始化", log: logger, type: .error)
case -560030580: // kAudioSessionBadPropertySizeError
os_log(" ➤ 错误分析: 属性大小错误", log: logger, type: .error)
case -560161140: // kAudioSessionIncompatibleCategory
os_log(" ➤ 错误分析: 音频类别不兼容", log: logger, type: .error)
default:
os_log(" ➤ 错误分析: 未知的OSStatus错误代码", log: logger, type: .error)
}
// // 解析具体的 OSStatus 错误
// switch osStatusCode {
// case -50:
// os_log(" ➤ 错误分析: OSStatus -50 通常表示参数错误 (kAudioSessionInvalidPropertyError)", log: logger, type: .error)
// case -560557673: // kAudioSessionNotInitialized
// os_log(" ➤ 错误分析: 音频会话未初始化", log: logger, type: .error)
// case -560030580: // kAudioSessionBadPropertySizeError
// os_log(" ➤ 错误分析: 属性大小错误", log: logger, type: .error)
// case -560161140: // kAudioSessionIncompatibleCategory
// os_log(" ➤ 错误分析: 音频类别不兼容", log: logger, type: .error)
// default:
// os_log(" ➤ 错误分析: 未知的OSStatus错误代码", log: logger, type: .error)
// }
// 输出当前音频会话状态用于调试
os_log("🔍 当前音频会话状态:", log: logger, type: .error)
os_log(" - 类别: %{public}@", log: logger, type: .error, audioSession.category.rawValue)
os_log(" - 模式: %{public}@", log: logger, type: .error, audioSession.mode.rawValue)
os_log(" - 是否激活: %{public}@", log: logger, type: .error, audioSession.isOtherAudioPlaying ? "是" : "否")
os_log(" - 其他音频播放: %{public}@", log: logger, type: .error, audioSession.isOtherAudioPlaying ? "是" : "否")
}
}
// // 输出当前音频会话状态用于调试
// os_log("🔍 当前音频会话状态:", log: logger, type: .error)
// os_log(" - 类别: %{public}@", log: logger, type: .error, audioSession.category.rawValue)
// os_log(" - 模式: %{public}@", log: logger, type: .error, audioSession.mode.rawValue)
// os_log(" - 是否激活: %{public}@", log: logger, type: .error, audioSession.isOtherAudioPlaying ? "是" : "否")
// os_log(" - 其他音频播放: %{public}@", log: logger, type: .error, audioSession.isOtherAudioPlaying ? "是" : "否")
// }
// }
public func appWillEnterForeground() {
os_log("📱 应用即将进入前台", log: logger, type: .info)
if let intent = currentIntent {
os_log("恢复之前的音频意图: %{public}@", log: logger, type: .info, String(describing: intent))
begin(intent)
//begin(intent)
} else {
os_log("无之前的音频意图需要恢复", log: logger, type: .info)
}
@ -385,7 +385,7 @@ public class AudioSessionHub {
if options.contains(.shouldResume), let intent = currentIntent {
os_log("恢复之前的音频意图: %{public}@", log: logger, type: .info, String(describing: intent))
// 恢复之前的音频意图
begin(intent)
//begin(intent)
os_log("✓ 音频会话中断结束,已恢复", log: logger, type: .info)
} else {
os_log("不需要恢复音频会话", log: logger, type: .info)
@ -420,7 +420,7 @@ public class AudioSessionHub {
// 重新应用当前意图以确保正确路由
if let intent = currentIntent {
os_log("重新应用当前音频意图: %{public}@", log: logger, type: .info, String(describing: intent))
begin(intent)
// begin(intent)
} else {
os_log("无当前音频意图需要重新应用", log: logger, type: .info)
}
@ -444,7 +444,7 @@ public class AudioSessionHub {
// 重新应用当前意图以确保正确路由
if let intent = currentIntent {
os_log("重新应用当前音频意图: %{public}@", log: logger, type: .info, String(describing: intent))
begin(intent)
// begin(intent)
} else {
os_log("无当前音频意图需要重新应用", log: logger, type: .info)
}
@ -474,13 +474,13 @@ public class AudioSessionHub {
/// 处理播放音频会话激活请求
@objc private func handleAudioSessionBeginPlayback(notification: Notification) {
os_log("收到播放音频会话激活请求", log: logger, type: .info)
begin(.playback)
// begin(.playback)
}
/// 处理语音音频会话激活请求
@objc private func handleAudioSessionBeginVoice(notification: Notification) {
os_log("收到语音音频会话激活请求", log: logger, type: .info)
begin(.voice)
// begin(.voice)
}
/// 处理音量控制请求

Loading…
Cancel
Save