You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
6.7 KiB

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 = <String>[].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<VolcanoAsrApiService>();
// 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<void> 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<void> _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;
}
}