Browse Source

fix(azure_speech): 优化蓝牙HFP麦克风检测和音频路由配置

动态检测蓝牙HFP输入设备并优先选择
移除默认外放选项,根据输出设备智能路由
添加音频会话配置的兜底逻辑
newdev_shunjiawei
liwei1dao 9 months ago
parent
commit
f1a8da1da1
  1. 2
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift
  2. 44
      local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift

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

@ -191,7 +191,7 @@ class AgentServiceImpl: NSObject {
"""
}
func initialize(config: [String: Any]) -> Bool {
if isInitialized { return true }
// if isInitialized { return true }
// os_log("initialize: config=%{public}@", log: logger, type: .info, config)
self.config = config

44
local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift

@ -128,10 +128,11 @@ public class SimpleAudioReceiver: NSObject {
_isWriting=true
self.audioSourceType = audioSourceType;
self.audioDataCallback = audioDataCallback
print("startAudioRecord=audioSourceType\(audioSourceType)")
print("音源设制---------- startAudioRecord=audioSourceType:\(audioSourceType)")
switch audioSourceType {
case .microphone:
isReceiverHFP = true
// 根据当前可用输入设备动态判定是否存在蓝牙HFP麦克风
isReceiverHFP = hasBluetoothHFPInput()
runMicrophoneCapture()
case .external:
isReceiverHFP = false
@ -139,6 +140,21 @@ public class SimpleAudioReceiver: NSObject {
}
}
/**
* 检测是否存在蓝牙HFP输入设备
* 参数:无
* 返回值:存在返回true,否则返回false
* 异常:无
*/
private func hasBluetoothHFPInput() -> Bool {
let session = AVAudioSession.sharedInstance()
if let inputs = session.availableInputs {
return inputs.contains { $0.portType == .bluetoothHFP }
}
// 兜底使用当前路由的输入
return session.currentRoute.inputs.contains { $0.portType == .bluetoothHFP }
}
/**
* 开启音频写入线程
* 修复:使用userInitiated QoS避免优先级反转
@ -263,7 +279,7 @@ public class SimpleAudioReceiver: NSObject {
// 非通话:保持原有逻辑,但使用 .allowBluetooth 以支持录音(而不是 A2DP)
desiredCategory = .playAndRecord
desiredMode = .videoChat
desiredOptions = [.allowBluetooth, .mixWithOthers, .defaultToSpeaker]
desiredOptions = [.allowBluetooth, .mixWithOthers]
//desiredOptions = [.mixWithOthers, .defaultToSpeaker]
}else{
desiredCategory = .playAndRecord
@ -276,13 +292,13 @@ public class SimpleAudioReceiver: NSObject {
// 通话中:录音优先,避免 A2DP(仅播放),改用 HFP(.allowBluetooth)
desiredCategory = .record
desiredMode = .voiceChat
desiredOptions = [.allowBluetoothA2DP]
desiredOptions = [.allowBluetooth]
} else {
if(isHeadphones){
// 非通话:保持原有逻辑,但使用 .allowBluetooth 以支持录音(而不是 A2DP)
desiredCategory = .playAndRecord
desiredMode = .videoChat
desiredOptions = [.allowBluetoothA2DP, .mixWithOthers, .defaultToSpeaker]
desiredOptions = [.allowBluetoothA2DP, .mixWithOthers]
//desiredOptions = [.mixWithOthers, .defaultToSpeaker]
}else{
desiredCategory = .playAndRecord
@ -307,6 +323,22 @@ public class SimpleAudioReceiver: NSObject {
// 保持激活;这里重复 setActive(true) 一般安全,但如果你观察到重复激活也触发路由回调,可在外层控制频率
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
// 路由校正:有蓝牙输出时不强制外放,并优先选择蓝牙输入(HFP)或内置麦克风
let outputs = audioSession.currentRoute.outputs
let hasBtOutput = outputs.contains { out in
out.portType == .bluetoothA2DP || out.portType == .bluetoothHFP || out.portType == .bluetoothLE
}
if hasBtOutput {
try audioSession.overrideOutputAudioPort(.none)
}
if let inputs = audioSession.availableInputs {
if isReceiverHFP, let btInput = inputs.first(where: { $0.portType == .bluetoothHFP }) {
try audioSession.setPreferredInput(btInput)
} else if let builtInMic = inputs.first(where: { $0.portType == .builtInMic }) {
try audioSession.setPreferredInput(builtInMic)
}
}
} catch {
// 兜底:尽量保证能开始录音
print("音频会话配置失败,尝试兜底配置: \(error)")
@ -561,5 +593,3 @@ private class LinkedBlockingQueue<T> {
}
}

Loading…
Cancel
Save