diff --git a/lib/modules/translation/controllers/translation_controller.dart b/lib/modules/translation/controllers/translation_controller.dart index 037ea6aa2..30aef106f 100644 --- a/lib/modules/translation/controllers/translation_controller.dart +++ b/lib/modules/translation/controllers/translation_controller.dart @@ -847,53 +847,64 @@ class TranslationController extends GetxController with WidgetsBindingObserver { /// 处理语音识别事件 /// [event] 识别事件 void _handleRecognitionEvent(RecognitionEvent event) { - if (event.type == RecognitionEventType.finalResult && - event.text.isNotEmpty) { - detectedLanguageCode = event.detectedLanguage; - print("处理识别完成:${event.text}"); - if (currentMode.value != 'faceToFace') { - handleFinalResult(event.text); - } else { - faceToFaceRecognitionText.value += event.text; - // 添加日志打印 - Logger.info('lxm-面对面翻译识别文本更新: ${faceToFaceRecognitionText.value}'); - } - if (currentMode.value == 'faceToFace' && activeSpeaker.value == 0) { - handleFinalResult(faceToFaceRecognitionText.value); - faceToFaceRecognitionText.value = ''; - } - } else if (event.type == RecognitionEventType.finalResult1 && - event.text.isNotEmpty) { - // 通话模式下:己方(麦克风)识别完成事件 - // 若原生未返回检测语言,则兜底为源语言 - detectedLanguageCode = event.detectedLanguage.isNotEmpty - ? event.detectedLanguage - : sourceLanguageCode.value; - print("处理己方识别完成:${event.text}"); - if (currentMode.value != 'faceToFace') { + // Logger.info("处理识别事件:${event}"); + switch (event.type) { + case RecognitionEventType.finalResult: + if (event.text.isEmpty) break; + // 通话模式下:目标语言即为识别语言,无需判断 + detectedLanguageCode = currentMode.value == 'call' + ? targetLanguageCode.value + : event.detectedLanguage; + Logger.info("处理识别完成:${event.text}"); + if (currentMode.value != 'faceToFace') { + handleFinalResult(event.text); + } else { + faceToFaceRecognitionText.value += event.text; + Logger.info('lxm-面对面翻译识别文本更新: ${faceToFaceRecognitionText.value}'); + } + if (currentMode.value == 'faceToFace' && activeSpeaker.value == 0) { + handleFinalResult(faceToFaceRecognitionText.value); + faceToFaceRecognitionText.value = ''; + } + break; + + case RecognitionEventType.finalResult1: + // 通话模式下:己方(麦克风)识别完成事件(对应ast服务) + if (event.text.isEmpty) break; + //通话模式下:己方语言即为源语言,无需判断 + detectedLanguageCode = sourceLanguageCode.value; + Logger.info("处理己方识别完成:${event.text}"); handleFinalResult(event.text); - } else { - faceToFaceRecognitionText.value += event.text; - Logger.info('lxm-面对面翻译识别文本更新(己方): ${faceToFaceRecognitionText.value}'); - } - if (currentMode.value == 'faceToFace' && activeSpeaker.value == 0) { - handleFinalResult(faceToFaceRecognitionText.value); - faceToFaceRecognitionText.value = ''; - } - } else if (event.type == RecognitionEventType.intermediateResult && - event.text.isNotEmpty) { - if (event.detectedLanguage.isNotEmpty) { - detectedLanguageCode = event.detectedLanguage; - } - print("处理识别中事件:${event.text}"); - handleIntermediateResult(event.text); - } else if (event.type == RecognitionEventType.error) { - Get.snackbar('error'.tr, event.error); - isRecognizing.value = false; - Logger.error('语音识别错误: ${event.error}'); - } else if (event.type == RecognitionEventType.canceled) { - isRecognizing.value = false; - Logger.error('语音识别取消: ${event.error}'); + break; + + case RecognitionEventType.intermediateResult: + if (event.text.isEmpty) break; + // 通话模式下:目标语言即为识别语言,无需判断 + detectedLanguageCode = currentMode.value == 'call' + ? targetLanguageCode.value + : event.detectedLanguage; + Logger.info("处理识别中事件:${event.text}"); + handleIntermediateResult(event.text); + break; + + case RecognitionEventType.error: + Get.snackbar('error'.tr, event.error); + isRecognizing.value = false; + Logger.error('语音识别错误: ${event.error}'); + break; + + case RecognitionEventType.canceled: + isRecognizing.value = false; + Logger.error('语音识别取消: ${event.error}'); + break; + + case RecognitionEventType.sessionStarted: + // 可按需处理会话开始事件 + break; + + case RecognitionEventType.sessionStopped: + // 可按需处理会话结束事件 + break; } } @@ -919,18 +930,21 @@ class TranslationController extends GetxController with WidgetsBindingObserver { /// [text] 识别的文本 void handleIntermediateResult(String text) { if (text.isEmpty) return; - print( + Logger.info( "handleIntermediateResult:${translationHistory.isEmpty}${translationHistory.isNotEmpty ? translationHistory.last.isIntermediate : 'N/A'}"); if (translationHistory.isEmpty || (translationHistory.isNotEmpty && !translationHistory.last.isIntermediate)) { currentSessionId ??= DateTime.now().millisecondsSinceEpoch.toString(); + // 关键调整:使用与最终结果一致的语言方向,避免左右“跳变” + final languageCodes = _determineLanguageCodes(); + final newItem = TranslationItem( sourceText: text, translatedText: '', - sourceLanguageCode: sourceLanguageCode.value, - targetLanguageCode: targetLanguageCode.value, + sourceLanguageCode: languageCodes['source']!, + targetLanguageCode: languageCodes['target']!, timestamp: DateTime.now(), sessionId: currentSessionId!, isFirstInSession: translationHistory.isEmpty || diff --git a/lib/modules/translation/views/widgets/translation_item_widget.dart b/lib/modules/translation/views/widgets/translation_item_widget.dart index 49ce94472..56ae1b264 100644 --- a/lib/modules/translation/views/widgets/translation_item_widget.dart +++ b/lib/modules/translation/views/widgets/translation_item_widget.dart @@ -49,15 +49,19 @@ class TranslationItemWidget extends GetView { // 判断是否是己方的翻译项(依据控制器当前源语言) final bool isSelf = item.sourceLanguageCode == controller.sourceLanguageCode.value; + // 新增:通话模式标记,用于控制右侧显示与隐藏中间态 + final bool isCallMode = controller.currentMode.value == 'call'; return GestureDetector( onTap: () => onToggleActionItem(item), // 触碰气泡时切换按钮显隐 onLongPressStart: (details) => onLongPressStart(context, isDarkMode, details, item), child: Align( - alignment: item.isIntermediate - ? Alignment.center - : (isSelf ? Alignment.centerLeft : Alignment.centerRight), + alignment: isCallMode + ? (isSelf ? Alignment.centerLeft : Alignment.centerRight) + : item.isIntermediate + ? Alignment.center + : (isSelf ? Alignment.centerLeft : Alignment.centerRight), child: Container( margin: EdgeInsets.only(bottom: 8.h), padding: EdgeInsets.all(12.w), diff --git a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt index 71dea5336..02f2c6cc6 100644 --- a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt +++ b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt @@ -893,12 +893,14 @@ object BleService { // 统计接收到的字节数 bytesReceivedInCurrentSecond += data.size processAudioData(data) + Log.i(TAG, "lxm--收到音频特征数据, 字节数=${data.size}") } BleConst.CALL_RECEIVE_AUDIO_CHAR_UUID -> { // 统计接收到的字节数 bytesReceivedInCurrentSecond += data.size processAudioData(data) + Log.i(TAG, "lxm--收到通话音频特征数据, 字节数=${data.size}") } // 通知特征数据(命令和控制) BleConst.NOTIFY_CHAR_UUID -> {