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.
154 lines
4.8 KiB
154 lines
4.8 KiB
import 'dart:async';
|
|
import 'package:get/get.dart';
|
|
import '../../../data/services/flutter_asr_service.dart';
|
|
import '../../../core/utils/logger.dart';
|
|
|
|
/// Flutter ASR测试控制器,演示如何使用FlutterAsrService
|
|
class FlutterAsrTestController extends GetxController {
|
|
// 获取ASR服务实例
|
|
final FlutterAsrService _asrService = Get.find<FlutterAsrService>();
|
|
|
|
// 当前ASR状态 - 使用Rx包装以便UI可以响应变化
|
|
final Rx<AsrState> _asrState = AsrState.notInitialized.obs;
|
|
AsrState get asrState => _asrState.value;
|
|
|
|
// 当前识别的文本 - 使用Rx包装以便UI可以响应变化
|
|
final RxString _recognizedText = ''.obs;
|
|
String get recognizedText => _recognizedText.value;
|
|
|
|
// 识别准确度 - 使用Rx包装以便UI可以响应变化
|
|
final RxDouble _confidence = 0.0.obs;
|
|
double get confidence => _confidence.value;
|
|
|
|
// 是否正在监听 - 计算属性
|
|
bool get isListening => asrState == AsrState.listening;
|
|
|
|
// 是否可用 - 使用Rx包装以便UI可以响应变化
|
|
final RxBool _isAvailable = false.obs;
|
|
bool get isAvailable => _isAvailable.value;
|
|
|
|
// 可用的语言列表 - 使用Rx包装以便UI可以响应变化
|
|
final RxList<dynamic> _locales = <dynamic>[].obs;
|
|
List<dynamic> get locales => _locales;
|
|
|
|
// 当前选择的语言 - 使用Rx包装以便UI可以响应变化
|
|
final RxString _currentLocale = ''.obs;
|
|
String get currentLocale => _currentLocale.value;
|
|
|
|
// 历史记录 - 使用Rx包装以便UI可以响应变化
|
|
final RxList<String> _history = <String>[].obs;
|
|
List<String> get history => _history;
|
|
|
|
// 连续识别模式 - 使用Rx包装以便UI可以响应变化
|
|
final RxBool _continuousMode = false.obs;
|
|
bool get continuousMode => _continuousMode.value;
|
|
set continuousMode(bool value) => _continuousMode.value = value;
|
|
|
|
// 定时器,用于定期更新状态
|
|
late Timer _updateTimer;
|
|
|
|
// 识别结果订阅
|
|
StreamSubscription<String>? _resultSubscription;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
|
|
// 初始化状态
|
|
_updateState();
|
|
|
|
// 设置定时器,每300毫秒更新一次状态,确保UI能够及时反映服务状态变化
|
|
_updateTimer = Timer.periodic(const Duration(milliseconds: 300), (_) {
|
|
_updateState();
|
|
|
|
// 如果启用了连续模式,且当前不在监听状态,且ASR已初始化,则自动重新开始监听
|
|
if (_continuousMode.value &&
|
|
_asrState.value != AsrState.listening &&
|
|
_asrState.value != AsrState.notInitialized &&
|
|
_asrState.value != AsrState.error &&
|
|
_isAvailable.value) {
|
|
_restartListening();
|
|
}
|
|
});
|
|
|
|
// 订阅识别结果流
|
|
_resultSubscription = _asrService.recognitionResults.listen(_onFinalResult);
|
|
}
|
|
|
|
/// 更新控制器状态,从服务获取最新状态
|
|
void _updateState() {
|
|
_asrState.value = _asrService.asrState;
|
|
_recognizedText.value = _asrService.lastWords;
|
|
_confidence.value = _asrService.confidence;
|
|
_isAvailable.value = _asrService.isAvailable;
|
|
_locales.assignAll(_asrService.locales);
|
|
_currentLocale.value = _asrService.currentLocale;
|
|
}
|
|
|
|
/// 开始语音识别
|
|
Future<bool> startListening() async {
|
|
return await _asrService.startListening();
|
|
}
|
|
|
|
/// 停止语音识别
|
|
Future<void> stopListening() async {
|
|
await _asrService.stopListening();
|
|
}
|
|
|
|
/// 取消语音识别
|
|
Future<void> cancelListening() async {
|
|
await _asrService.cancelListening();
|
|
}
|
|
|
|
/// 切换连续识别模式
|
|
void toggleContinuousMode() {
|
|
_continuousMode.value = !_continuousMode.value;
|
|
Logger.info('连续识别模式: ${_continuousMode.value ? '开启' : '关闭'}');
|
|
|
|
// 如果开启连续模式且当前未在监听,则开始监听
|
|
if (_continuousMode.value && !isListening && _isAvailable.value) {
|
|
startListening();
|
|
}
|
|
}
|
|
|
|
/// 重新开始监听(用于连续模式)
|
|
Future<void> _restartListening() async {
|
|
// 添加小延迟,避免过于频繁的重启
|
|
await Future.delayed(const Duration(milliseconds: 300));
|
|
if (_continuousMode.value && !isListening && _isAvailable.value) {
|
|
Logger.info('连续模式: 重新开始监听');
|
|
await startListening();
|
|
}
|
|
}
|
|
|
|
/// 设置语言
|
|
void setLocale(String localeId) {
|
|
_asrService.setLocale(localeId);
|
|
_currentLocale.value = localeId;
|
|
}
|
|
|
|
/// 处理最终识别结果
|
|
void _onFinalResult(String result) {
|
|
if (result.isNotEmpty) {
|
|
// 添加到历史记录
|
|
_history.insert(0, result);
|
|
|
|
// 限制历史记录数量
|
|
if (_history.length > 10) {
|
|
_history.removeLast();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 清空历史记录
|
|
void clearHistory() {
|
|
_history.clear();
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
_updateTimer.cancel();
|
|
_resultSubscription?.cancel();
|
|
super.onClose();
|
|
}
|
|
}
|