import 'dart:async'; import 'package:get/get.dart'; import 'package:flutter/foundation.dart'; import '../../../data/services/voice_recognition_service.dart'; class VoiceInputController extends GetxController { // Observable states final isConnecting = true.obs; final isMuted = false.obs; final isRecording = false.obs; final recognizedText = ''.obs; // 语音识别服务 late final VoiceRecognitionService _voiceService; // 连续识别相关 StreamSubscription? _recognitionSubscription; // Callbacks final Function(String) onRecordingResult; final VoidCallback onClosePanel; final Function(String) onRecognizing; VoiceInputController({ required this.onRecordingResult, required this.onClosePanel, required this.onRecognizing, }); @override void onInit() { super.onInit(); _initializeVoiceService(); } Future _initializeVoiceService() async { try { // 创建语音识别服务实例 _voiceService = VoiceRecognitionService(); // 初始化语音识别服务 await _voiceService.initialize(); // 初始化完成后更新状态 isConnecting.value = false; // 自动开始连续语音识别 await startContinuousRecognition(); } catch (e) { print('初始化语音识别服务失败: $e'); Get.snackbar( 'Error', '初始化语音识别服务失败: $e', snackPosition: SnackPosition.BOTTOM, ); } } Future startContinuousRecognition() async { if (isConnecting.value || isMuted.value) return; if (isRecording.value) return; // 已经在录音中 try { isRecording.value = true; recognizedText.value = ''; // 开始连续语音识别 final stream = await _voiceService.startContinuousRecognition(); // 订阅识别事件流 _recognitionSubscription = stream.listen((event) { switch (event.type) { case RecognitionEventType.intermediateResult: // 更新中间识别结果 recognizedText.value = event.text; // 调用识别中回调 onRecognizing(event.text); break; case RecognitionEventType.finalResult: // 更新最终识别结果 if (event.text.isNotEmpty) { recognizedText.value = event.text; // 调用最终结果回调,发送识别到的句子 onRecordingResult(event.text); // 清空识别文本,准备下一句 recognizedText.value = ''; // 不停止录音,继续监听下一句 } break; case RecognitionEventType.error: case RecognitionEventType.canceled: // 处理错误 print('语音识别错误: ${event.error}'); Get.snackbar( 'Error', '语音识别错误: ${event.error}', snackPosition: SnackPosition.BOTTOM, ); // 尝试重新启动识别 restartRecognition(); break; case RecognitionEventType.sessionStopped: // 会话结束,尝试重新启动 isRecording.value = false; restartRecognition(); break; default: break; } }, onError: (error) { print('语音识别流错误: $error'); Get.snackbar( 'Error', '语音识别流错误: $error', snackPosition: SnackPosition.BOTTOM, ); isRecording.value = false; // 尝试重新启动识别 restartRecognition(); }); } catch (e) { print('语音识别失败: $e'); Get.snackbar( 'Error', '启动语音识别失败: $e', snackPosition: SnackPosition.BOTTOM, ); isRecording.value = false; } } // 重新启动识别 Future restartRecognition() async { if (isMuted.value) return; try { // 先停止当前识别 await stopRecording(); // 延迟一下再重新启动 await Future.delayed(const Duration(milliseconds: 500)); // 重新启动连续识别 await startContinuousRecognition(); } catch (e) { print('重新启动语音识别失败: $e'); } } Future stopRecording() async { if (!isRecording.value) return; try { // 取消事件订阅 await _recognitionSubscription?.cancel(); _recognitionSubscription = null; // 停止连续识别 if (_voiceService.isContinuousRecognitionActive()) { await _voiceService.stopContinuousRecognition(); } isRecording.value = false; } catch (e) { print('停止语音识别失败: $e'); isRecording.value = false; } } void toggleMute() { isMuted.value = !isMuted.value; if (isRecording.value && isMuted.value) { stopRecording(); } else if (!isMuted.value && !isRecording.value) { // 如果取消静音,自动开始识别 startContinuousRecognition(); } } // 手动开始录音(用户点击按钮) void startRecording() { if (!isRecording.value) { startContinuousRecognition(); } } @override void onClose() { // 停止录音 stopRecording(); // 重置状态 isConnecting.value = false; isMuted.value = false; isRecording.value = false; recognizedText.value = ''; super.onClose(); } }