From b748eaf11683fc459880c820897b1b0489de4a68 Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Fri, 19 Sep 2025 15:40:15 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtts=E5=A5=94=E6=BA=83?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E5=85=81=E8=AE=B8=E6=B7=B7=E9=9F=B3?= =?UTF-8?q?=E3=80=829.19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/azure_speech/AzureTtsHelper.swift | 27 ++++- .../Sources/tools/MicrophoneCapture.swift | 24 ----- .../Sources/tools/SimpleAudioReceiver.swift | 99 +++---------------- 3 files changed, 36 insertions(+), 114 deletions(-) diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift index 30dfd7464..a5857fe4e 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift @@ -124,10 +124,33 @@ public class AzureTtsHelper: NSObject, ITtsService { */ public func startspeak(sessionid sessionid: String)-> Bool { self.sessionid = sessionid - + print("startspeak sessionid \(sessionid)") // 重置当前会话的文本计数 self.currentSessionTextCount = 0 self.pendingTextCount = 0 + + do { + // 新增:使用 AVAudioSession.sharedInstance 配置为“通话模式 + 扬声器外放” + // - 使用 .playAndRecord 以保证通话上下行链路 + // - 使用 .voiceChat 获得通话处理(AEC 等) + // - 使用 .defaultToSpeaker 默认走外放 + // - 通过 overrideOutputAudioPort(.speaker) 强制切到扬声器 + let audioSession = AVAudioSession.sharedInstance() + + //try audioSession.setActive(false) + try audioSession.setCategory(.playAndRecord, + mode: .voiceChat, + options: [.defaultToSpeaker, + .mixWithOthers, + .defaultToSpeaker, + .allowBluetoothA2DP, + .allowBluetooth]) + try audioSession.overrideOutputAudioPort(.none) + try audioSession.setActive(true) + } catch { + print("音频会话配置失败: \(error.localizedDescription)") + } + return true } @@ -187,7 +210,7 @@ public class AzureTtsHelper: NSObject, ITtsService { totalTextCount += text.count currentSessionTextCount += text.count - print("流式合成文本\(text.count),总计文本数量:\(totalTextCount),当前会话:\(currentSessionTextCount)") + //print("流式合成文本\(text.count),总计文本数量:\(totalTextCount),当前会话:\(currentSessionTextCount)") // 清理文本并添加到缓冲区 let cleanedText = cleanTextForTTS(text) diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/tools/MicrophoneCapture.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/tools/MicrophoneCapture.swift index 857d30041..1d14da379 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/tools/MicrophoneCapture.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/tools/MicrophoneCapture.swift @@ -445,30 +445,6 @@ public class MicrophoneCapture: NSObject { // 安全地处理音频会话 guard let audioSession = audioSession else { return } - do { - try audioSession.setActive(false) - - if self.hasBluetoothDevices { - // 设置音频会话参数 - try audioSession.setCategory(.playback, - mode: .videoChat, - options: [ - .allowBluetoothA2DP, - .allowBluetooth - ]) // 添加音频优先级控制 - } else { - try audioSession.setCategory(.playback, - mode: .videoChat, - options: [ - .mixWithOthers, - .defaultToSpeaker]) - } - - try audioSession.overrideOutputAudioPort(.none) - try audioSession.setActive(true) - } catch { - print("音频会话配置失败: \(error.localizedDescription)") - } } /** diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift index 5aef34be7..b37cd56f4 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift @@ -193,12 +193,15 @@ public class SimpleAudioReceiver: NSObject { // 确保正在写入状态 guard self._isWriting else { return } // 设置音频会话参数 - try audioSession.setCategory(.playAndRecord, - mode: .videoChat, - options: [.allowBluetoothA2DP, // 允许蓝牙耳机,不占用hfp链路 - .mixWithOthers, - .defaultToSpeaker]) // 添加音频优先级控制 - try audioSession.setActive(true) + try audioSession.setCategory(.playAndRecord, + mode: .voiceChat, + options: [.defaultToSpeaker, + .mixWithOthers, + .defaultToSpeaker, + .allowBluetoothA2DP, + .allowBluetooth]) + try audioSession.overrideOutputAudioPort(.none) + try audioSession.setActive(true) try micCapture.startCapture() try micCapture.audioDataHandler = { data in self.writeQueue.put(data) @@ -264,37 +267,7 @@ public class SimpleAudioReceiver: NSObject { * 强制使用设备内置扬声器或听筒 */ public func disableBluetoothAudio() { - // do { - // print("禁用蓝牙音频功能,切换回正常音频模式") - - // // 暂停当前音频引擎 - // if _isWriting { - // audioEngine?.pause() - // try audioSession.setActive(false) - // } - - // // 设置音频会话为不允许蓝牙 - // try audioSession.setCategory( - // .playAndRecord, - // mode: .videoChat, - // options: [.defaultToSpeaker, .mixWithOthers] // 移除 .allowBluetooth - // ) - - // // 强制使用扬声器 - // try audioSession.overrideOutputAudioPort(.speaker) - - // // 重新激活音频会话 - // if _isWriting { - // try audioSession.setActive(true) - // try audioEngine?.start() - // } - - // // 更新当前路由状态 - // currentRoute = .speaker - - // } catch { - // print("禁用蓝牙音频失败: \(error.localizedDescription)") - // } + } /** @@ -369,57 +342,7 @@ public func restoreOriginalAudioState() { public func setAudioOutputRoute(_ route: AudioOutputRoute) { - // do { - // // - // if self._isWriting { - // print("当前正在识别") - // micCapture.stopCapture() - // // 先停用以避免冲突 - // try audioSession.setActive(false) - - // } - // print("setAudioOutputRoutecurrent,route=\(route)") - // switch route { - // case .speaker: - // print("setAudioOutputRoutecurrent,speaker") - // // 使用扬声器时必须用videoChat模式 - // try audioSession.setCategory( - // .playAndRecord, - // mode: .videoChat, - // options: [.defaultToSpeaker,.allowBluetooth,.mixWithOthers] - // ) - // try audioSession.overrideOutputAudioPort(.speaker) - - // case .receiver: - // // 听筒模式使用voiceChat节省资源 - // try audioSession.setCategory( - // .playAndRecord, - // mode: .voiceChat, - // options: [.allowBluetooth] - // ) - // try audioSession.overrideOutputAudioPort(.none) - - // case .bluetooth: - // // 完整蓝牙设备支持 - // try audioSession.setCategory( - // .playAndRecord, - // mode: .voiceChat, - // options: [.allowBluetooth, .allowBluetoothA2DP] - // ) - // try audioSession.overrideOutputAudioPort(.none) - // // 不需要override,系统自动路由 - // } - // self.currentRoute = route - // if self._isWriting { - - // // 重新激活 - // try audioSession.setActive(true, options: [.notifyOthersOnDeactivation]) - // try micCapture.startCapture() - - // } - // } catch { - // print("路由切换失败: \(error)") - // } + } From a70155806b33fe1daaf12501b1808347b1fc9bb8 Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Fri, 19 Sep 2025 16:30:08 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=89=93=E7=94=B5=E8=AF=9D=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E5=8E=BB=E5=A4=84=E5=98=9F=E5=98=9F=E5=98=9F=E5=A3=B0?= =?UTF-8?q?=E9=9F=B3=EF=BC=8C=E5=BD=B1=E5=93=8D=E5=9B=9E=E9=9F=B3=E6=B6=88?= =?UTF-8?q?=E9=99=A4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/agent_service/AgentServiceImpl.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift index b294b6a05..e51d45a41 100644 --- a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift +++ b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift @@ -81,7 +81,7 @@ class AgentServiceImpl: NSObject { private let maxIdleSeconds: TimeInterval = 10 var micCapture: MicrophoneCapture! // 语音识别模式 - private var currentRecognitionMode: String = "normal" + public var currentRecognitionMode: String = "normal" internal var audioPlayer: AudioPlayer? // private var locationInfo:[String: String]? @@ -1581,9 +1581,14 @@ class AudioPlayer { } func playAwaitSound() { - // 先停止之前的等待音效和定时器 + //先停止之前的等待音效和定时器 stopAwaitSound() + // 修复:通过 agentService 引用访问 currentRecognitionMode + if agentService?.currentRecognitionMode == "phone_call" {//电话模式不要嘟嘟嘟。影响回音消除功能 + return + } + // 播放等待音效 playLoopSound(named: "await", fileType: "mp3", player: &awaitPlayer,volume:0.2)