diff --git a/android/app/src/main/kotlin/com/example/deep_voice/AzureAsrHelper.kt b/android/app/src/main/kotlin/com/example/deep_voice/AzureAsrHelper.kt index 6ca172b66..b9f5d6718 100644 --- a/android/app/src/main/kotlin/com/example/deep_voice/AzureAsrHelper.kt +++ b/android/app/src/main/kotlin/com/example/deep_voice/AzureAsrHelper.kt @@ -166,7 +166,7 @@ class AzureAsrHelper(private val context: Context) { } else { currentLanguage } - FileLogger.d(TAG, "最终识别结果: ${event.result.text}") + // FileLogger.d(TAG, "最终识别结果: ${event.result.text}") callback.onResult(event.result.text, detectedLanguage) } } @@ -181,7 +181,7 @@ class AzureAsrHelper(private val context: Context) { } else { currentLanguage } - FileLogger.d(TAG, "识别中结果: ${event.result.text}") + // FileLogger.d(TAG, "识别中结果: ${event.result.text}") callback.onRecognizing(event.result.text, detectedLanguage) } } diff --git a/android/app/src/main/kotlin/com/example/deep_voice/AzureTtsHelper.kt b/android/app/src/main/kotlin/com/example/deep_voice/AzureTtsHelper.kt index a6c7d46b0..402560690 100644 --- a/android/app/src/main/kotlin/com/example/deep_voice/AzureTtsHelper.kt +++ b/android/app/src/main/kotlin/com/example/deep_voice/AzureTtsHelper.kt @@ -279,7 +279,7 @@ class AzureTtsHelper(private val context: Context) { */ fun speakText(text: String, callback: TTSCallback) { if (!isInitialized) { - callback.onError("TTS 引擎尚未初始化") + callback.onError("TTS 引擎尚未初始化===") return } @@ -361,8 +361,8 @@ class AzureTtsHelper(private val context: Context) { callback.onError("语音合成取消: ${cancellation.reason}, ${cancellation.errorDetails}") } else -> { - FileLogger.e(TAG, "语音合成失败: ${result.reason}") - callback.onError("语音合成失败: ${result.reason}") + FileLogger.e(TAG, "语音合成失败kt: ${result.reason}") + callback.onError("语音合成失败kt: ${result.reason}") } } diff --git a/android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt b/android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt index e2d9f23f5..91cfa2077 100644 --- a/android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt +++ b/android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt @@ -220,9 +220,33 @@ class VoiceInteractionService : Service() { // 设置回调 mediaSession.setCallback(object : MediaSessionCompat.Callback() { override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean { - FileLogger.d(TAG, "initMediaSession收到媒体按钮事件: $mediaButtonEvent") - handleDoubleClick() - return true + val keyEvent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT, KeyEvent::class.java) + } else { + @Suppress("DEPRECATION") + mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT) as? KeyEvent + } + + if (keyEvent != null) { + // 仅处理按下操作和相关按键 + if (keyEvent.action == KeyEvent.ACTION_DOWN) { + when (keyEvent.keyCode) { + KeyEvent.KEYCODE_HEADSETHOOK, + KeyEvent.KEYCODE_MEDIA_PLAY, + KeyEvent.KEYCODE_MEDIA_PAUSE, + KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> { + FileLogger.d(TAG, "接收到相关媒体按钮: keyCode=${keyEvent.keyCode}") + handleDoubleClick() + return true + } + } + } + FileLogger.d(TAG, "忽略不相关媒体按钮: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}") + return false + } + + FileLogger.d(TAG, "收到无按键的媒体按钮事件") + return false } override fun onPlay() { @@ -650,10 +674,8 @@ class VoiceInteractionService : Service() { if (keyEvent != null) { FileLogger.d(TAG, "从Intent中解析到按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}") + // 使用统一的按键处理逻辑 handleKeyEvent(keyEvent) - } else { - FileLogger.d(TAG, "Intent中没有按键事件,直接处理双击") - handleDoubleClick() } } else if (intent?.action == ACTION_PAUSE_VOICE_INTERACTION) { // 处理来自 Flutter 的暂停请求 @@ -663,7 +685,7 @@ class VoiceInteractionService : Service() { FileLogger.d(TAG, "收到其他Intent: action=${intent?.action}") } - // 让 MediaSession 处理 Intent + // 让 MediaSession 处理 Intent,MediaSession将通过callback处理事件 try { MediaButtonReceiver.handleIntent(mediaSession, intent) FileLogger.d(TAG, "MediaButtonReceiver处理Intent完成") @@ -680,14 +702,13 @@ class VoiceInteractionService : Service() { private fun handleKeyEvent(keyEvent: KeyEvent) { FileLogger.d(TAG, "处理按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}") + // 只处理按下操作和相关媒体按键 if (keyEvent.action == KeyEvent.ACTION_DOWN) { when (keyEvent.keyCode) { - KeyEvent.KEYCODE_MEDIA_PLAY -> { - FileLogger.d(TAG, "处理MEDIA_PLAY按键") - handleDoubleClick() - } - KeyEvent.KEYCODE_MEDIA_PAUSE -> { - FileLogger.d(TAG, "处理MEDIA_PAUSE按键") + KeyEvent.KEYCODE_MEDIA_PLAY, + KeyEvent.KEYCODE_MEDIA_PAUSE, + KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> { + FileLogger.d(TAG, "处理标准媒体按键: ${keyEvent.keyCode}") handleDoubleClick() } KeyEvent.KEYCODE_HEADSETHOOK -> { @@ -712,16 +733,12 @@ class VoiceInteractionService : Service() { } lastKeyEventTime = currentTime } - KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> { - FileLogger.d(TAG, "处理MEDIA_PLAY_PAUSE按键") - handleDoubleClick() - } else -> { - FileLogger.d(TAG, "处理其他按键: ${keyEvent.keyCode}") + FileLogger.d(TAG, "忽略不相关的按键: ${keyEvent.keyCode}") } } } else { - FileLogger.d(TAG, "非ACTION_DOWN事件: ${keyEvent.action}") + FileLogger.d(TAG, "忽略非ACTION_DOWN事件: ${keyEvent.action}") } } diff --git a/ios/Runner/AzureAsrHelper.swift b/ios/Runner/AzureAsrHelper.swift index c41974d6e..9222b1321 100644 --- a/ios/Runner/AzureAsrHelper.swift +++ b/ios/Runner/AzureAsrHelper.swift @@ -338,35 +338,19 @@ class AzureAsrHelper: NSObject { _isContinuousRecognitionActive = false do { - try recognizer.stopContinuousRecognition() + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } + do { + try recognizer.stopContinuousRecognition() + } catch { + print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)") + } + } } catch { print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)") } - // // 异步执行停止操作,避免阻塞主线程 - // DispatchQueue.global(qos: .userInitiated).async { [weak self] in - // guard let self = self else { return } - - // do { - // // 在后台线程执行停止操作 - // try recognizer.stopContinuousRecognition() - - // // 主线程回调通知结果 - // DispatchQueue.main.async { - // print("[AzureAsrHelper] 连续识别已停止") - // self.eventHandler("sessionStopped", [:]) - // } - // } catch { - // // 主线程回调通知错误 - // DispatchQueue.main.async { - // print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)") - // // 停止失败,恢复状态 - // self._isContinuousRecognitionActive = true - // self.eventHandler("error", ["error": "停止识别失败: \(error.localizedDescription)"]) - // } - // } - // } // 立即返回,不阻塞调用方 return true diff --git a/lib/data/services/speech_impl/azure_tts_service.dart b/lib/data/services/speech_impl/azure_tts_service.dart index 4a4069356..d9aed08ee 100644 --- a/lib/data/services/speech_impl/azure_tts_service.dart +++ b/lib/data/services/speech_impl/azure_tts_service.dart @@ -94,26 +94,22 @@ class AzureTtsService extends GetxService implements TtsService { return false; } - // 始终优先使用中文作为默认语言 - final String defaultLanguage = 'zh-CN'; + // 更新支持的语音列表(如果提供) - if (supportedLanguages != null && supportedLanguages.isNotEmpty) { - // 如果支持中文,优先使用中文,否则使用提供的第一种语言 - String language = supportedLanguages.contains(defaultLanguage) - ? defaultLanguage - : supportedLanguages.first; + final String language = supportedLanguages?.first ?? 'zh-CN'; + final result = await _channel.invokeMethod('initialize', { 'subscriptionKey': _subscriptionKey, 'region': _serviceRegion, 'language': language, }); + - _isInitialized = result; + _isInitialized = true; return result; - } - return true; + } catch (e) { Logger.error('初始化失败: $e'); return false; @@ -180,7 +176,7 @@ class AzureTtsService extends GetxService implements TtsService { } catch (e) { // 发生错误时重置状态 _speakingCache = false; - Logger.error('语音合成失败: $e'); + Logger.error('1语音合成失败: $e'); return false; } } diff --git a/lib/modules/chat/controllers/chat_controller.dart b/lib/modules/chat/controllers/chat_controller.dart index 083ac2494..f3efa2e69 100644 --- a/lib/modules/chat/controllers/chat_controller.dart +++ b/lib/modules/chat/controllers/chat_controller.dart @@ -15,8 +15,8 @@ import '../../../data/services/voice_interaction_service.dart'; class ChatController extends GetxController { // 服务 final VolcanoAIService _aiService = Get.find(); - late TtsService _ttsService; - late AsrService _asrService; + final TtsService _ttsService = Get.find(); + final AsrService _asrService = Get.find(); final ChatHistoryService _historyService = Get.find(); final VoiceInteractionService _voiceInteractionService = Get.find(); @@ -83,8 +83,8 @@ class ChatController extends GetxController { agent = foundAgent; - _ttsService = Get.find(); - _asrService = Get.find(); + _ttsService.initialize(); + _asrService.initialize(); // 设置语音交互模式 _isVoiceInteractionMode = args['isVoiceInteraction'] == true; diff --git a/lib/modules/translation/bindings/translation_binding.dart b/lib/modules/translation/bindings/translation_binding.dart index a31ed7a5b..b9071e619 100644 --- a/lib/modules/translation/bindings/translation_binding.dart +++ b/lib/modules/translation/bindings/translation_binding.dart @@ -1,19 +1,10 @@ import 'package:get/get.dart'; import '../controllers/translation_controller.dart'; -import '../../../data/services/speech_impl/azure_asr_service.dart'; -import '../../../data/services/speech_impl/azure_tts_service.dart'; -import '../../../data/services/asr_service.dart'; -import '../../../data/services/tts_service.dart'; -import '../../../data/services/volcano_translation_service.dart'; -import '../../../data/services/language_manager.dart'; + class TranslationBinding implements Bindings { @override void dependencies() { - Get.put(LanguageManager(), permanent: true); - Get.lazyPut(() => AzureAsrService(), fenix: true); - Get.lazyPut(() => AzureTtsService(), fenix: true); - Get.put(VolcanoTranslationService(), permanent: true); Get.put(TranslationController()); } } \ No newline at end of file