Browse Source

finish

weicu
wolfplus 2 years ago
parent
commit
6bf13b6f57
  1. 171
      lib/data/services/background_agent_service.dart

171
lib/data/services/background_agent_service.dart

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

Loading…
Cancel
Save