From 4f6173d8f6f50bd45e5f59cd720848944879a07b Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Mon, 25 Aug 2025 18:22:04 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9A=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E7=94=B5=E9=87=8F=E6=98=BE=E7=A4=BA=E6=A8=AA=E6=9D=86?= =?UTF-8?q?ui=E5=BC=82=E5=B8=B8=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/modules/home/views/home_view.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/modules/home/views/home_view.dart b/lib/modules/home/views/home_view.dart index 5afc3586f..7e994eb38 100644 --- a/lib/modules/home/views/home_view.dart +++ b/lib/modules/home/views/home_view.dart @@ -91,6 +91,7 @@ class HomeView extends GetView { // 设备状态卡片 IntroStepBuilder( + key: const ValueKey('home_device_status'), // 添加唯一key group: 'home', order: 1, onWidgetLoad: () { @@ -115,6 +116,7 @@ class HomeView extends GetView { SizedBox(height: 20.h), IntroStepBuilder( + key: const ValueKey('home_wakeup_guide'), // 添加唯一key group: 'home', order: 2, getOverlayPosition: IntroOverlayBuilder.overlayPosition, @@ -719,6 +721,7 @@ class HomeView extends GetView { Expanded( flex: 1, child: IntroStepBuilder( + key: const ValueKey('home_ai_assistant'), // 添加唯一key group: 'home', order: 3, getOverlayPosition: IntroOverlayBuilder.overlayPosition, From 32985b32d575b6c35f5140226ff5f5544587b4ea Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Tue, 26 Aug 2025 18:12:26 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=89=E5=8D=93?= =?UTF-8?q?=E5=BD=95=E9=9F=B3=EF=BC=8C=E9=80=9A=E8=AF=9D=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../azure_speech/AzureAsrHelper.kt | 7 +++---- .../azure_speech/tools/SimpleAudioReceiver.kt | 20 +++++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt index a2837aa39..8f7d5b571 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt +++ b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt @@ -504,10 +504,9 @@ class AzureAsrHelper(private val context: Context) { } // 启动音频处理 - audioStream!!.startAudioRecord( when(audioSourceType) { - AudioSourceType.MICROPHONE -> SimpleAudioReceiver.AudioSourceType.MICROPHONE - AudioSourceType.EXTERNAL -> SimpleAudioReceiver.AudioSourceType.EXTERNAL - },audioDataCallback) + audioStream!!.startAudioRecord(SimpleAudioReceiver.AudioSourceType.MICROPHONE + + ,audioDataCallback) audioStream!!.recordfile!!.closeFile(true) diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt index 5ad74f4b9..0505ff46d 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt +++ b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt @@ -85,7 +85,8 @@ class SimpleAudioReceiver(private val context: Context) { * 初始化音频录制 */ fun initAudioRecord() { - + val format = getOptimalAudioFormat() + pushAudioStream = AudioInputStream.createPushStream(format) isRunning.set(true) Log.d(TAG, "initAudioRecord: ${isRunning}") startWriteThread() // 再启动数据读取线程 @@ -142,7 +143,7 @@ class SimpleAudioReceiver(private val context: Context) { if(audioDataCallback!=null){ audioDataCallback?.onAudio(finalData) } - if(pushAudioStream!=null){ + if(pushAudioStream!=null&&audioDataCallback==null){ pushAudioStream?.write(finalData) } if(recordfile!=null){ @@ -184,8 +185,6 @@ class SimpleAudioReceiver(private val context: Context) { * @param callback 音频数据回调,可为空 */ fun startAudioRecord(audioSourceType: AudioSourceType, callback: AudioDataCallback?) { - val format = getOptimalAudioFormat() - pushAudioStream = AudioInputStream.createPushStream(format) this.audioSourceType = audioSourceType this.audioDataCallback = callback writeQueue.clear() @@ -240,8 +239,6 @@ class SimpleAudioReceiver(private val context: Context) { try { // 首先设置通话音频模式 //setupCommunicationAudioMode() - - val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) val sampleRate = supportedSampleRates.firstOrNull { rate -> val bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat) @@ -278,7 +275,7 @@ class SimpleAudioReceiver(private val context: Context) { } audioRecord?.startRecording() - + Log.d("TAG", "通话模式录音开始,采样率: $sampleRate Hz") } catch (e: Exception) { @@ -316,7 +313,8 @@ class SimpleAudioReceiver(private val context: Context) { //setupCommunicationAudioMode() // 停止录音 audioRecord?.startRecording() - + + } catch (e: Exception) { Log.e(TAG, "继续录音失败: ${e.message}") } @@ -331,11 +329,7 @@ class SimpleAudioReceiver(private val context: Context) { // 停止录音 audioRecord?.stop() - - if(pushAudioStream != null){ - pushAudioStream?.close() - pushAudioStream = null - } + // 恢复音频模式 这里会导致关闭麦克风卡住待优化 //restoreCommunicationAudioMode() From 850f9917f481548bb409a042aa955cf797db00dd Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Tue, 26 Aug 2025 18:41:49 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=9B=E5=85=A5?= =?UTF-8?q?=E9=80=9A=E8=AF=9D=E9=87=8D=E6=96=B0=E5=9B=9E=E5=88=B0=E5=BD=95?= =?UTF-8?q?=E9=9F=B3=EF=BC=8C=E5=BD=95=E9=9F=B3=E4=B8=8D=E4=BA=86=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/azure_speech/AzureAsrHelper.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift index dd070d8af..ad1911137 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift @@ -677,10 +677,18 @@ public class AzureAsrHelper: NSObject { audioStream?.recordfile = RecordFile() } - + self.audioSourceType = .microphone // 修复:移除多余的 audioDataCallback 参数 + // 修复:添加类型转换 audioStream?.startAudioRecord( - audioSourceType: audioSourceType == .microphone ? .microphone : .external, + audioSourceType: { + switch audioSourceType { + case .microphone: + return SimpleAudioReceiver.AudioSourceType.microphone + case .external: + return SimpleAudioReceiver.AudioSourceType.external + } + }(), audioDataCallback: audioDataCallback ) From ad485b8f6a2f865ce50c8a4404718b2826897d99 Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Tue, 26 Aug 2025 19:36:12 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=8E=BB=E5=A4=84=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../navigation_bar_bottom_sheet.dart | 64 +++++++++---------- .../translation/views/translation_view.dart | 26 ++++---- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/lib/modules/meeting/views/bottomSheet/navigation_bar_bottom_sheet.dart b/lib/modules/meeting/views/bottomSheet/navigation_bar_bottom_sheet.dart index 7f594cdc6..150c3549f 100644 --- a/lib/modules/meeting/views/bottomSheet/navigation_bar_bottom_sheet.dart +++ b/lib/modules/meeting/views/bottomSheet/navigation_bar_bottom_sheet.dart @@ -35,38 +35,38 @@ class NavigationBarBottomSheet extends GetView { controller.addMeetingAudio(); }, ), - if (controller.meetingController.type == 1) - _buildItem( - context, // 传递 context 参数 - 'audioVideoRecording'.tr, // 对应中文:音、视频录音 - Icons.videocam, - Colors.green, - onTap: controller.bleManager.isConnected - ? () async { - Get.back(); - await Get.toNamed(Routes.meetingRecord, arguments: { - 'audioTypes': 1, - }); - controller.addMeetingAudio(); - } - : null, - ), - if (controller.meetingController.type == 1) - _buildItem( - context, // 传递 context 参数 - 'callRecording'.tr, // 对应中文:通话录音 - Icons.phone, - Colors.orange, - onTap: controller.bleManager.isConnected - ? () async { - Get.back(); - await Get.toNamed(Routes.meetingRecord, arguments: { - 'audioTypes': 2, - }); - controller.addMeetingAudio(); - } - : null, - ), + // if (controller.meetingController.type == 1) + // _buildItem( + // context, // 传递 context 参数 + // 'audioVideoRecording'.tr, // 对应中文:音、视频录音 + // Icons.videocam, + // Colors.green, + // onTap: controller.bleManager.isConnected + // ? () async { + // Get.back(); + // await Get.toNamed(Routes.meetingRecord, arguments: { + // 'audioTypes': 1, + // }); + // controller.addMeetingAudio(); + // } + // : null, + // ), + // if (controller.meetingController.type == 1) + // _buildItem( + // context, // 传递 context 参数 + // 'callRecording'.tr, // 对应中文:通话录音 + // Icons.phone, + // Colors.orange, + // onTap: controller.bleManager.isConnected + // ? () async { + // Get.back(); + // await Get.toNamed(Routes.meetingRecord, arguments: { + // 'audioTypes': 2, + // }); + // controller.addMeetingAudio(); + // } + // : null, + // ), _buildItem( context, // 传递 context 参数 'importAudio'.tr, // 对应中文:导入音频 diff --git a/lib/modules/translation/views/translation_view.dart b/lib/modules/translation/views/translation_view.dart index 3458da2d6..364993c46 100644 --- a/lib/modules/translation/views/translation_view.dart +++ b/lib/modules/translation/views/translation_view.dart @@ -1115,19 +1115,19 @@ class TranslationView extends GetView { } : null, ), - _buildModeItem( - context, - 'audioVideoTranslation'.tr, - Icons.videocam, - Colors.orange, - onTap: controller.bleManager.isConnected - ? () async { - Get.back(); - await controller.changeTranslationMode('audioVideo'); - await controller.startRecognition(); - } - : null, - ), + // _buildModeItem( + // context, + // 'audioVideoTranslation'.tr, + // Icons.videocam, + // Colors.orange, + // onTap: controller.bleManager.isConnected + // ? () async { + // Get.back(); + // await controller.changeTranslationMode('audioVideo'); + // await controller.startRecognition(); + // } + // : null, + // ), _buildModeItem( context, 'callTranslation'.tr, From f1b95098746fe41e2dfa68f237b42ec5e9a5aa0e Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Tue, 26 Aug 2025 20:24:59 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=81=A2=E5=A4=8Dios=E9=9D=A2=E5=AF=B9?= =?UTF-8?q?=E9=9D=A2=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/azure_speech/AzureAsrHelper.swift | 4 +- .../azure_speech/AzureSpeechPlugin.swift | 8 +- .../Sources/tools/SimpleAudioReceiver.swift | 79 ++++++++++++++++++- 3 files changed, 82 insertions(+), 9 deletions(-) diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift index ad1911137..d8795a60c 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift @@ -639,7 +639,7 @@ public class AzureAsrHelper: NSObject { do { print("禁用蓝牙音频功能,切换回正常音频模式") - // audioStream?.disableBluetoothAudio() + audioStream?.disableBluetoothAudio() } catch { print("disableBluetoothAudio") } @@ -651,7 +651,7 @@ public class AzureAsrHelper: NSObject { do { print("恢复原始音频设备状态(通常是重新启用蓝牙)") - //audioStream?.restoreOriginalAudioState() + audioStream?.restoreOriginalAudioState() } catch { print("restoreOriginalAudioState") } diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift index f807e96db..f068f476f 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift @@ -522,18 +522,16 @@ private func sendAstEvent(_ event: [String: Any]) { if (type == 0) { // 默认(如果有耳机选耳机,否则使用系统扬声器) azureAsrHelper.restoreOriginalAudioState(); - // azureTtsHelper.setAudioOutputDevice() - - + azureTtsHelper.setAudioOutputDevice() } else if (type == 1) { // 强制使用声器 azureAsrHelper.disableBluetoothAudio(); - // azureTtsHelper.setAudioOutputDevice() + azureTtsHelper.setAudioOutputDevice() } else if (type == 2) { // 强制使用耳机 azureAsrHelper.restoreOriginalAudioState(); - //azureTtsHelper.setAudioOutputDevice() + azureTtsHelper.setAudioOutputDevice() } 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 22cb05061..f7e6bced6 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 @@ -365,7 +365,82 @@ public class SimpleAudioReceiver: NSObject { } - + // MARK: - 协议定义 +/** + * 禁用蓝牙音频功能,切换回正常音频模式 + * 强制使用设备内置扬声器或听筒 + */ +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)") + } +} + +/** + * 恢复原始音频设备状态(重新启用蓝牙) + * 允许系统自动选择最佳音频设备 + */ +public func restoreOriginalAudioState() { + do { + print("恢复原始音频设备状态(重新启用蓝牙)") + + // 暂停当前音频引擎 + if _isWriting { + audioEngine?.pause() + try audioSession.setActive(false) + } + + // 恢复完整的蓝牙音频支持 + try audioSession.setCategory( + .playAndRecord, + mode: .videoChat, + options: [.defaultToSpeaker, .allowBluetooth, .mixWithOthers] + ) + + // 取消音频端口覆盖,让系统自动选择 + try audioSession.overrideOutputAudioPort(.none) + + // 重新激活音频会话 + if _isWriting { + try audioSession.setActive(true) + try audioEngine?.start() + } + + // 重置路由状态,让系统自动选择 + currentRoute = nil + + } catch { + print("恢复原始音频状态失败: \(error.localizedDescription)") + } +} public func stopMicrophoneCapture() { @@ -568,5 +643,5 @@ private class LinkedBlockingQueue { } } -// MARK: - 协议定义 +