From 6bf13b6f57c65f4f780dcd301dabf07e6996d53d Mon Sep 17 00:00:00 2001 From: wolfplus Date: Tue, 25 Feb 2025 19:56:55 +0000 Subject: [PATCH] finish --- .../services/background_agent_service.dart | 171 ++++++++++++++---- 1 file changed, 137 insertions(+), 34 deletions(-) diff --git a/lib/data/services/background_agent_service.dart b/lib/data/services/background_agent_service.dart index 7ad62fe1a..b2bb3cf95 100644 --- a/lib/data/services/background_agent_service.dart +++ b/lib/data/services/background_agent_service.dart @@ -49,6 +49,12 @@ class BackgroundAgentService extends GetxService { // 添加一个订阅,用于监听 TTS 状态变化 StreamSubscription? _ttsSpeakingSubscription; + // 添加一个变量来跟踪当前的AI响应流订阅 + StreamSubscription? _aiResponseSubscription; + + // 添加一个标志,表示是否应该取消当前的AI响应 + bool _shouldCancelAiResponse = false; + BackgroundAgentService() : _aiService = VolcanoAIService(), _ttsService = Get.find(), @@ -76,6 +82,12 @@ class BackgroundAgentService extends GetxService { _shouldContinueInteraction = true; try { + // 确保之前的语音识别已经停止 + if (_isListening) { + print('交互开始前确保语音识别已停止'); + await stopVoiceRecognition(); + } + // 循环进行交互,直到用户 10 秒没有说话或手动停止 while (_shouldContinueInteraction) { await _processSingleInteraction(systemPrompt); @@ -85,6 +97,14 @@ class BackgroundAgentService extends GetxService { if (_isListening) { await stopVoiceRecognition(); } + + // 重置语音识别服务 + try { + print('交互结束,重置语音识别服务'); + await _voiceRecognitionService.initialize(); + } catch (e) { + print('重置语音识别服务失败: $e'); + } } } @@ -131,6 +151,12 @@ class BackgroundAgentService extends GetxService { String userInput = ''; try { + // 确保之前的语音识别已经停止 + if (_isListening) { + print('检测到上一次语音识别未正确停止,先停止它'); + await stopVoiceRecognition(); + } + // 尝试启动语音识别 await startVoiceRecognition(); recognitionStarted = true; @@ -175,6 +201,15 @@ class BackgroundAgentService extends GetxService { print('语音识别过程出错: $e'); // 如果语音识别失败,尝试使用默认问候语 userInput = '你好,请帮我回答一个问题'; + + // 尝试重置语音识别服务 + try { + await stopVoiceRecognition(); + await Future.delayed(const Duration(milliseconds: 500)); + await _voiceRecognitionService.initialize(); + } catch (resetError) { + print('重置语音识别服务失败: $resetError'); + } } finally { // 清理资源,但保持语音识别状态 _recognitionCompleter = null; @@ -216,51 +251,91 @@ class BackgroundAgentService extends GetxService { String fullResponse = ''; try { - await for (final chunk in _aiService.sendMessageStream( + // 重置取消标志 + _shouldCancelAiResponse = false; + + // 创建一个本地变量来跟踪是否已取消 + bool isCancelled = false; + + // 获取AI响应流 + final responseStream = _aiService.sendMessageStream( messages: messages, systemPrompt: systemPrompt, - )) { - fullResponse += chunk; - - // 累积文本并处理TTS - _pendingTtsText += chunk; - if (_ttsService.isEnabled.value) { - if (_pendingTtsText.length >= _minTtsLength) { - int lastSentenceEnd = _findLastSentenceEnd(_pendingTtsText); - if (lastSentenceEnd > 0) { - String textToSpeak = _pendingTtsText.substring(0, lastSentenceEnd + 1); + ); + + // 创建一个订阅来处理响应流 + _aiResponseSubscription = responseStream.listen( + (chunk) { + // 如果已经设置了取消标志,则不处理这个块 + if (_shouldCancelAiResponse) { + isCancelled = true; + return; + } + + fullResponse += chunk; + + // 累积文本并处理TTS + _pendingTtsText += chunk; + if (_ttsService.isEnabled.value) { + if (_pendingTtsText.length >= _minTtsLength) { + int lastSentenceEnd = _findLastSentenceEnd(_pendingTtsText); + if (lastSentenceEnd > 0) { + String textToSpeak = _pendingTtsText.substring(0, lastSentenceEnd + 1); + try { + _ttsService.speak(textToSpeak); + } catch (e) { + print('播放TTS失败: $e'); + } + _pendingTtsText = _pendingTtsText.substring(lastSentenceEnd + 1); + } + } + } + }, + onError: (e) { + print('AI响应流错误: $e'); + // 清理订阅 + _aiResponseSubscription = null; + }, + onDone: () { + // 如果已取消,不处理剩余的文本 + if (!isCancelled && !_shouldCancelAiResponse) { + // 处理剩余的文本 + if (_ttsService.isEnabled.value && _pendingTtsText.isNotEmpty) { try { - await _ttsService.speak(textToSpeak); + _ttsService.speak(_pendingTtsText); } catch (e) { - print('播放TTS失败: $e'); + print('播放剩余TTS失败: $e'); } - _pendingTtsText = _pendingTtsText.substring(lastSentenceEnd + 1); } } + _pendingTtsText = ''; + _aiResponseSubscription = null; } - } + ); + + // 等待响应流完成 + await _aiResponseSubscription!.asFuture(); + } catch (e) { print('AI响应生成失败: $e'); // 如果AI响应失败,使用默认回复 fullResponse = '抱歉,我现在无法回答您的问题。请稍后再试。'; + } finally { + // 清理资源 + _aiResponseSubscription?.cancel(); + _aiResponseSubscription = null; + _shouldCancelAiResponse = false; } - // 处理剩余的文本 - if (_ttsService.isEnabled.value && _pendingTtsText.isNotEmpty) { - try { - await _ttsService.speak(_pendingTtsText); - } catch (e) { - print('播放剩余TTS失败: $e'); - } + // 如果响应被取消,不保存到历史记录 + if (!_shouldCancelAiResponse && fullResponse.isNotEmpty) { + // 保存助手回复到历史记录 + _messageHistory.add(Message( + role: 'assistant', + content: fullResponse, + timestamp: DateTime.now(), + )); } - _pendingTtsText = ''; - - // 保存助手回复到历史记录 - _messageHistory.add(Message( - role: 'assistant', - content: fullResponse, - timestamp: DateTime.now(), - )); // 限制历史记录长度 if (_messageHistory.length > 20) { @@ -291,12 +366,20 @@ class BackgroundAgentService extends GetxService { // 开始语音识别 Future startVoiceRecognition() async { - if (_isListening) return; + if (_isListening) { + print('已经在监听中,先停止当前监听'); + await stopVoiceRecognition(); + } try { // 确保语音识别服务已初始化 if (!await _voiceRecognitionService.initialize()) { - throw Exception('无法初始化语音识别服务'); + print('语音识别服务初始化失败,尝试重新初始化'); + // 尝试重新初始化 + await Future.delayed(const Duration(milliseconds: 500)); + if (!await _voiceRecognitionService.initialize()) { + throw Exception('无法初始化语音识别服务'); + } } // 开始连续识别 @@ -330,10 +413,20 @@ class BackgroundAgentService extends GetxService { _hasRecognizedSpeech = true; _lastSpeechTime = DateTime.now(); - // 如果系统正在播放TTS,检测到用户开始说话时立即中断TTS播放 + // 如果系统正在播放TTS或接收AI响应,检测到用户开始说话时立即中断 if (_isSpeaking && event.text.trim().isNotEmpty) { - print('检测到用户开始说话,中断TTS播放'); + print('检测到用户开始说话,中断TTS播放和AI响应'); _ttsService.stop(); // 停止当前TTS播放 + + // 设置标志,表示应该取消当前的AI响应 + _shouldCancelAiResponse = true; + + // 取消当前的AI响应流订阅 + _aiResponseSubscription?.cancel(); + _aiResponseSubscription = null; + + // 清空待处理的TTS文本 + _pendingTtsText = ''; } // 取消之前的静默计时器 @@ -380,6 +473,8 @@ class BackgroundAgentService extends GetxService { if (!_isListening) return ''; try { + print('停止语音识别...'); + // 取消静默计时器 _silenceTimer?.cancel(); _silenceTimer = null; @@ -402,11 +497,18 @@ class BackgroundAgentService extends GetxService { _isListening = false; isListening.value = false; + print('语音识别已停止'); return result; } catch (e) { print('停止语音识别失败: $e'); _isListening = false; isListening.value = false; + + // 尝试强制重置语音识别服务 + try { + await _voiceRecognitionService.initialize(); + } catch (_) {} + return recognizedText.value; // 返回当前已识别的文本 } } @@ -436,6 +538,7 @@ class BackgroundAgentService extends GetxService { _silenceTimer?.cancel(); _noSpeechTimer?.cancel(); _ttsSpeakingSubscription?.cancel(); + _aiResponseSubscription?.cancel(); _shouldContinueInteraction = false; super.onClose(); }