import 'dart:async'; import 'package:get/get.dart'; import '../../../data/services/volcano_asr_api_service.dart'; import '../../../core/utils/logger.dart'; class VolcanoAsrTestController extends GetxController { // Observable variables final isListening = false.obs; final errorMessage = ''.obs; final recognitionResults = [].obs; final isContinuous = false.obs; final connectionStatus = 'Disconnected'.obs; // 当前识别中的文本 final currentRecognizingText = ''.obs; // 当前识别的索引 int _currentRecognitionIndex = -1; // Services late final VolcanoAsrApiService _asrService; // Stream subscriptions StreamSubscription? _recognitionSubscription; @override void onInit() { super.onInit(); // Initialize the ASR service _asrService = Get.find(); // Subscribe to recognition stream _recognitionSubscription = _asrService.recognitionStream.listen((event) { switch (event.type) { case RecognitionEventType.started: // 开始新的识别 if (isContinuous.value) { // 如果是连续模式,检查是否需要创建新条目 if (_currentRecognitionIndex == -1 || recognitionResults.isEmpty) { // 如果没有当前识别索引或结果列表为空,添加新条目 recognitionResults.add(''); _currentRecognitionIndex = recognitionResults.length - 1; } } else { // 非连续模式,清空结果并添加新条目 recognitionResults.clear(); recognitionResults.add(''); _currentRecognitionIndex = 0; } currentRecognizingText.value = ''; break; case RecognitionEventType.recognizing: // 实时识别结果 if (event.text.isNotEmpty) { currentRecognizingText.value = event.text; // 确保有一个当前条目可以更新 if (_currentRecognitionIndex == -1 || _currentRecognitionIndex >= recognitionResults.length) { recognitionResults.add(''); _currentRecognitionIndex = recognitionResults.length - 1; } // 更新当前条目 recognitionResults[_currentRecognitionIndex] = event.text; } break; case RecognitionEventType.finalResult: // 最终识别结果 if (event.text.isNotEmpty) { // 确保有一个当前条目可以更新 if (_currentRecognitionIndex == -1 || _currentRecognitionIndex >= recognitionResults.length) { recognitionResults.add(event.text); _currentRecognitionIndex = recognitionResults.length - 1; } else { // 更新当前条目为最终结果 recognitionResults[_currentRecognitionIndex] = event.text; } // 收到最终结果后,重置索引,为新句子做准备 _currentRecognitionIndex = -1; // 清空当前识别文本 currentRecognizingText.value = ''; } break; case RecognitionEventType.error: // 错误处理 if (event.error != null) { errorMessage.value = event.error!; // 如果有错误且正在识别,停止识别 if (isListening.value) { isListening.value = false; connectionStatus.value = 'Disconnected'; // 停止语音识别,不尝试重启 _asrService.stopRecognition(); } } break; // 注意:处理其他事件类型 default: // 其他事件类型不做特殊处理 break; } }); // Update connection status based on service state ever(_asrService.isListening, (bool listening) { isListening.value = listening; connectionStatus.value = listening ? 'Connected' : 'Disconnected'; }); // Update error message from service if (_asrService.errorMessage.isNotEmpty) { errorMessage.value = _asrService.errorMessage; } } @override void onClose() { // Cancel all subscriptions _recognitionSubscription?.cancel(); // Disconnect from the ASR service if still connected if (_asrService.isConnected) { stopListening(); } super.onClose(); } // Start listening for speech Future startListening() async { try { // Clear previous error message errorMessage.value = ''; // 如果是新的识别会话 if (!isListening.value) { currentRecognizingText.value = ''; // 如果不是连续识别模式,则清空结果列表 if (!isContinuous.value) { recognitionResults.clear(); _currentRecognitionIndex = -1; } } // 使用麦克风录音功能 final success = await _asrService.startRecognition( sampleRate: 16000, bitsPerSample: 16, channels: 1, format: 'pcm', codec: 'raw', enablePunc: true, ); if (success) { isListening.value = true; connectionStatus.value = 'Connected'; } else { errorMessage.value = _asrService.errorMessage; Logger.error('Failed to start recognition: ${_asrService.errorMessage}'); } } catch (e) { errorMessage.value = e.toString(); Logger.error('Error starting recognition: $e'); } } // 重新开始识别(用于连续识别模式) Future _restartRecognition() async { // 短暂延迟,确保上一次识别完全结束 await Future.delayed(const Duration(milliseconds: 500)); // 如果仍处于监听状态且是连续识别模式,则开始新的识别 if (isListening.value && isContinuous.value) { startListening(); } } // Stop listening for speech void stopListening() { try { connectionStatus.value = 'Disconnecting...'; // 停止麦克风录音 _asrService.stopRecognition().then((_) { isListening.value = false; connectionStatus.value = 'Disconnected'; // 重置当前识别索引 _currentRecognitionIndex = -1; }).catchError((e) { errorMessage.value = e.toString(); Logger.error('Error stopping recognition: $e'); }); } catch (e) { errorMessage.value = e.toString(); Logger.error('Error stopping recognition: $e'); } } // Clear recognition results void clearResults() { recognitionResults.clear(); currentRecognizingText.value = ''; _currentRecognitionIndex = -1; } }