diff --git a/lib/modules/translation/views/translation_view.dart b/lib/modules/translation/views/translation_view.dart index fed9c1558..58a5d33c9 100644 --- a/lib/modules/translation/views/translation_view.dart +++ b/lib/modules/translation/views/translation_view.dart @@ -206,16 +206,35 @@ class TranslationView extends GetView { : Colors.grey[100], borderRadius: BorderRadius.circular(16.r), ), - child: Obx(() => Text( - '${controller.targetLanguage.value.split(' ')[0]}' - .tr, // Just show the English part - style: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.w600, - color: isDarkMode ? Colors.white : Colors.black, - ), - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, + child: Obx(() => Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Flexible( + child: Text( + '${controller.targetLanguage.value.split(' ')[0]}' + .tr, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w600, + color: + isDarkMode ? Colors.white : Colors.black, + ), + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + ), + ), + //只在通话翻译模式下显示电话图标 + if (controller.currentMode.value == 'call') ...[ + SizedBox(width: 4.w), + Icon( + Icons.phone_in_talk, + size: 20.sp, + color: isDarkMode + ? Colors.white70 + : Colors.grey[600], + ), + ], + ], )), ), ), @@ -418,23 +437,27 @@ class TranslationView extends GetView { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - // 耳机图标按钮 (说话者1) - _buildHoldToTalkButton( - isDarkMode: isDarkMode, - speakerId: 1, - activeSpeaker: controller.activeSpeaker.value, - icon: Icons.headset, - label: "headsetUser".tr, - ), - SizedBox(width: 40.w), - // 手机图标按钮 (说话者2) - _buildHoldToTalkButton( - isDarkMode: isDarkMode, - speakerId: 2, - activeSpeaker: controller.activeSpeaker.value, - icon: Icons.phone_android, - label: "phoneUser".tr, - ), + // 耳机图标按钮 (说话者1)-显示源语言 + Obx(() => _buildHoldToTalkButton( + isDarkMode: isDarkMode, + speakerId: 1, + activeSpeaker: controller.activeSpeaker.value, + icon: Icons.mic_none, + label: controller.sourceLanguage.value + .split(' ')[0] + .tr, // 源语言名称 + )), + SizedBox(width: 16.w), + // 手机图标按钮 (说话者2)-显示目标语言 + Obx(() => _buildHoldToTalkButton( + isDarkMode: isDarkMode, + speakerId: 2, + activeSpeaker: controller.activeSpeaker.value, + icon: Icons.mic_none, + label: controller.targetLanguage.value + .split(' ')[0] + .tr, // 目标语言名称 + )), ], ) else @@ -569,15 +592,15 @@ class TranslationView extends GetView { }, child: AnimatedContainer( duration: const Duration(milliseconds: 200), - width: 80.w, - height: 80.w, + width: 160.w, // 长条形宽度 + height: 54.h, // 长条形高度 decoration: BoxDecoration( color: isActive ? (isDarkMode ? Colors.green[700] : Colors.green) : (isDisabled ? (isDarkMode ? Colors.grey[800] : Colors.grey[300]) : (isDarkMode ? AppColors.primary : Colors.blue)), - shape: BoxShape.circle, + borderRadius: BorderRadius.circular(25.r), // 圆角长条形 boxShadow: isActive ? [ BoxShadow( @@ -586,32 +609,42 @@ class TranslationView extends GetView { spreadRadius: 3, ) ] - : null, + : [ + BoxShadow( + color: (isDarkMode ? Colors.black : Colors.grey) + .withOpacity(0.2), + blurRadius: 8, + spreadRadius: 1, + offset: Offset(0, 2), + ) + ], ), - child: Column( + child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Stack( - alignment: Alignment.center, - children: [ - // 设备类型图标 - Icon( - icon, + // 左边图标 + Icon( + icon, + color: isActive + ? Colors.white + : Colors.white.withOpacity(isDisabled ? 0.3 : 0.9), + size: 20.sp, + ), + SizedBox(width: 8.w), // 图标和文字间距 + // 右边语言名称 + Flexible( + child: Text( + label, + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w500, color: isActive ? Colors.white : Colors.white.withOpacity(isDisabled ? 0.3 : 0.9), - size: 24.sp, ), - ], - ), - SizedBox(height: 4.h), - Text( - label, - style: TextStyle( - fontSize: 12.sp, - color: isActive - ? Colors.white - : Colors.white.withOpacity(isDisabled ? 0.3 : 0.9), + textAlign: TextAlign.center, + maxLines: 1, + overflow: TextOverflow.ellipsis, // 防止文本溢出 ), ), ], diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrToAsr.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrToAsr.kt index c04bc32cb..f2b170bdf 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrToAsr.kt +++ b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrToAsr.kt @@ -328,10 +328,14 @@ class IntegratedSpeechTranslationService( confidence ) Log.d(TAG, "识别完成事件: ${event.result.text},serviceConfig.sourceLanguage:${serviceConfig.sourceLanguage}") - // 触发翻译流程 - launch { - Log.d(TAG, "触发翻译流程: ${event.result.text}") - processTranslationAndSynthesis(event.result.text) + // 只有在服务仍在运行时才触发翻译流程 + if (serviceState.isRecognizing.get()) { + launch { + Log.d(TAG, "触发翻译流程: ${event.result.text}") + processTranslationAndSynthesis(event.result.text) + } + } else { + Log.d(TAG, "服务已停止,跳过翻译流程: ${event.result.text}") } } } @@ -478,6 +482,7 @@ class IntegratedSpeechTranslationService( recognizer?.stopContinuousRecognitionAsync() audioProcessor?.stopRecording() recordfile1!!.closeFile(true) + serviceState.isRecognizing.set(false) // 等待当前处理完成 while (serviceState.isTranslating.get() || serviceState.isSynthesizing.get()) { Thread.sleep(100) @@ -494,7 +499,13 @@ class IntegratedSpeechTranslationService( * 处理翻译和合成流程 */ private suspend fun processTranslationAndSynthesis(text: String) { - Log.d(TAG, " 翻译状态:${serviceState.isTranslating.get()}") + // 检查服务是否仍在运行 + if (!serviceState.isRecognizing.get()) { + Log.d(TAG, "服务已停止,取消翻译流程: $text") + return + } + + Log.d(TAG, " 翻译状态:${serviceState.isTranslating.get()}") if (serviceState.isTranslating.get()) { Log.w(TAG, "翻译正在进行中,跳过当前请求") return diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/IntegratedSpeechTranslationService.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/IntegratedSpeechTranslationService.swift index db83bd553..70d8773bd 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/IntegratedSpeechTranslationService.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/IntegratedSpeechTranslationService.swift @@ -388,9 +388,13 @@ import os.log os_log("识别完成事件: %@", log: self.log, type: .info, text) - // 触发翻译流程 - Task { - await self.processTranslationAndSynthesis(text: text) + // 检查服务状态,只有在识别仍然活跃时才触发翻译流程 + if self.serviceState.isRecognizing { + Task { + await self.processTranslationAndSynthesis(text: text) + } + } else { + os_log("服务已停止,跳过翻译流程", log: self.log, type: .info) } } @@ -593,6 +597,7 @@ import os.log */ public func stopContinuousTranslation() { do { + self.serviceState.isRecognizing = false try recognizer?.stopContinuousRecognition() audioProcessor?.stopMicrophoneCapture() recordFile?.closeFile(isSave: true) @@ -614,6 +619,12 @@ import os.log * 处理翻译和合成流程 */ private func processTranslationAndSynthesis(text: String) async { + // 添加服务状态检查 + guard serviceState.isRecognizing else { + os_log("服务已停止,取消翻译流程", log: log, type: .info) + return + } + os_log("翻译状态: %@", log: log, type: .debug, serviceState.isTranslating ? "进行中" : "空闲") if serviceState.isTranslating {