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.
288 lines
8.6 KiB
288 lines
8.6 KiB
import 'dart:async';
|
|
import 'package:get/get.dart';
|
|
import '../../../data/services/azure_asr_service.dart';
|
|
import '../../../core/utils/logger.dart';
|
|
|
|
// Azure语音识别状态枚举
|
|
enum AzureAsrState {
|
|
notInitialized, // 未初始化
|
|
initialized, // 已初始化
|
|
listening, // 正在监听
|
|
notListening, // 未监听
|
|
error, // 错误
|
|
}
|
|
|
|
class AzureAsrTestController extends GetxController {
|
|
// 服务引用
|
|
final AzureAsrService _azureAsrService = Get.find<AzureAsrService>();
|
|
|
|
// 状态变量
|
|
final RxBool isListening = false.obs;
|
|
final RxString recognizedText = ''.obs;
|
|
final RxString partialText = ''.obs;
|
|
final RxString detectedLanguage = ''.obs;
|
|
final Rx<AzureAsrState> asrState = AzureAsrState.notInitialized.obs;
|
|
|
|
// 语言选项
|
|
final RxString selectedLanguage = 'zh-CN'.obs;
|
|
final List<String> availableLanguages = [
|
|
'zh-CN', // 中文(中国大陆)
|
|
'en-US', // 英语(美国)
|
|
'ja-JP', // 日语
|
|
'ko-KR', // 韩语
|
|
'fr-FR', // 法语
|
|
'de-DE', // 德语
|
|
'es-ES', // 西班牙语
|
|
'it-IT', // 意大利语
|
|
'pt-BR', // 葡萄牙语(巴西)
|
|
'ru-RU', // 俄语
|
|
];
|
|
|
|
// 自动语言检测
|
|
final RxBool isAutoDetectEnabled = false.obs;
|
|
final RxList<String> selectedSupportedLanguages = <String>['zh-CN', 'en-US'].obs;
|
|
|
|
// 订阅
|
|
StreamSubscription? _recognitionSubscription;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
_initializeAsr();
|
|
}
|
|
|
|
// 初始化ASR服务
|
|
Future<void> _initializeAsr() async {
|
|
try {
|
|
final success = await _azureAsrService.initialize(
|
|
language: selectedLanguage.value,
|
|
autoDetectLanguage: isAutoDetectEnabled.value,
|
|
supportedLanguages: selectedSupportedLanguages,
|
|
);
|
|
asrState.value = success ? AzureAsrState.initialized : AzureAsrState.error;
|
|
} catch (e) {
|
|
Logger.error('初始化ASR服务失败: $e');
|
|
asrState.value = AzureAsrState.error;
|
|
}
|
|
}
|
|
|
|
// 开始简单语音识别
|
|
Future<void> startSimpleRecognition() async {
|
|
try {
|
|
if (asrState.value == AzureAsrState.notInitialized) {
|
|
await _initializeAsr();
|
|
}
|
|
|
|
// 如果正在进行连续识别,先停止
|
|
if (_azureAsrService.isContinuousRecognitionActive()) {
|
|
await stopContinuousRecognition();
|
|
}
|
|
|
|
partialText.value = '';
|
|
final result = await _azureAsrService.recognizeSpeech();
|
|
if (result.text.isNotEmpty) {
|
|
recognizedText.value = result.text;
|
|
detectedLanguage.value = result.detectedLanguage;
|
|
}
|
|
} catch (e) {
|
|
Logger.error('开始简单语音识别出错: $e');
|
|
asrState.value = AzureAsrState.error;
|
|
}
|
|
}
|
|
|
|
// 切换连续语音识别
|
|
Future<void> toggleContinuousRecognition() async {
|
|
try {
|
|
if (asrState.value == AzureAsrState.notInitialized) {
|
|
await _initializeAsr();
|
|
}
|
|
|
|
if (_azureAsrService.isContinuousRecognitionActive()) {
|
|
await stopContinuousRecognition();
|
|
} else {
|
|
await startContinuousRecognition();
|
|
}
|
|
} catch (e) {
|
|
Logger.error('切换连续语音识别出错: $e');
|
|
asrState.value = AzureAsrState.error;
|
|
}
|
|
}
|
|
|
|
// 开始连续语音识别
|
|
Future<void> startContinuousRecognition() async {
|
|
try {
|
|
if (_azureAsrService.isContinuousRecognitionActive()) {
|
|
await stopContinuousRecognition();
|
|
}
|
|
|
|
_recognitionSubscription?.cancel();
|
|
_recognitionSubscription = null;
|
|
|
|
isListening.value = true;
|
|
asrState.value = AzureAsrState.listening;
|
|
partialText.value = '';
|
|
|
|
final stream = await _azureAsrService.startContinuousRecognition();
|
|
|
|
_recognitionSubscription = stream.listen(
|
|
(event) {
|
|
switch (event.type) {
|
|
case RecognitionEventType.finalResult:
|
|
if (event.text.isNotEmpty) {
|
|
recognizedText.value = event.text;
|
|
detectedLanguage.value = event.detectedLanguage;
|
|
}
|
|
partialText.value = '';
|
|
break;
|
|
|
|
case RecognitionEventType.intermediateResult:
|
|
if (event.text.isNotEmpty) {
|
|
partialText.value = event.text;
|
|
if (event.detectedLanguage.isNotEmpty) {
|
|
detectedLanguage.value = event.detectedLanguage;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RecognitionEventType.sessionStarted:
|
|
isListening.value = true;
|
|
asrState.value = AzureAsrState.listening;
|
|
break;
|
|
|
|
case RecognitionEventType.sessionStopped:
|
|
isListening.value = false;
|
|
asrState.value = AzureAsrState.notListening;
|
|
partialText.value = '';
|
|
break;
|
|
|
|
case RecognitionEventType.canceled:
|
|
isListening.value = false;
|
|
asrState.value = AzureAsrState.notListening;
|
|
partialText.value = '';
|
|
break;
|
|
|
|
case RecognitionEventType.error:
|
|
asrState.value = AzureAsrState.error;
|
|
isListening.value = false;
|
|
partialText.value = '';
|
|
_initializeAsr();
|
|
break;
|
|
}
|
|
},
|
|
onError: (error) {
|
|
asrState.value = AzureAsrState.error;
|
|
isListening.value = false;
|
|
partialText.value = '';
|
|
},
|
|
onDone: () {
|
|
if (!_azureAsrService.isContinuousRecognitionActive()) {
|
|
isListening.value = false;
|
|
asrState.value = AzureAsrState.notListening;
|
|
}
|
|
},
|
|
);
|
|
} catch (e) {
|
|
Logger.error('开始连续语音识别出错: $e');
|
|
asrState.value = AzureAsrState.error;
|
|
isListening.value = false;
|
|
partialText.value = '';
|
|
}
|
|
}
|
|
|
|
// 停止连续语音识别
|
|
Future<void> stopContinuousRecognition() async {
|
|
try {
|
|
isListening.value = false;
|
|
asrState.value = AzureAsrState.notListening;
|
|
|
|
await _azureAsrService.stopContinuousRecognition();
|
|
|
|
_recognitionSubscription?.cancel();
|
|
_recognitionSubscription = null;
|
|
|
|
partialText.value = '';
|
|
} catch (e) {
|
|
Logger.error('停止连续语音识别出错: $e');
|
|
asrState.value = AzureAsrState.error;
|
|
}
|
|
}
|
|
|
|
// 更改语言
|
|
Future<void> changeLanguage(String language) async {
|
|
try {
|
|
if (selectedLanguage.value == language) return;
|
|
|
|
selectedLanguage.value = language;
|
|
|
|
if (_azureAsrService.isContinuousRecognitionActive()) {
|
|
await stopContinuousRecognition();
|
|
}
|
|
|
|
final success = await _azureAsrService.setRecognitionLanguage(language);
|
|
asrState.value = success ? AzureAsrState.initialized : AzureAsrState.error;
|
|
|
|
recognizedText.value = '';
|
|
partialText.value = '';
|
|
detectedLanguage.value = '';
|
|
} catch (e) {
|
|
Logger.error('更改语言出错: $e');
|
|
asrState.value = AzureAsrState.error;
|
|
}
|
|
}
|
|
|
|
// 切换自动语言检测
|
|
Future<void> toggleAutoDetectLanguage() async {
|
|
try {
|
|
isAutoDetectEnabled.value = !isAutoDetectEnabled.value;
|
|
|
|
if (_azureAsrService.isContinuousRecognitionActive()) {
|
|
await stopContinuousRecognition();
|
|
}
|
|
|
|
final success = await _azureAsrService.enableAutoDetectLanguage(
|
|
isAutoDetectEnabled.value,
|
|
languages: selectedSupportedLanguages,
|
|
);
|
|
|
|
asrState.value = success ? AzureAsrState.initialized : AzureAsrState.error;
|
|
|
|
recognizedText.value = '';
|
|
partialText.value = '';
|
|
detectedLanguage.value = '';
|
|
} catch (e) {
|
|
Logger.error('切换自动语言检测出错: $e');
|
|
asrState.value = AzureAsrState.error;
|
|
}
|
|
}
|
|
|
|
// 更新支持的语言列表
|
|
Future<void> updateSupportedLanguages(List<String> languages) async {
|
|
try {
|
|
if (languages.isEmpty) return;
|
|
|
|
selectedSupportedLanguages.value = languages;
|
|
|
|
if (_azureAsrService.isContinuousRecognitionActive()) {
|
|
await stopContinuousRecognition();
|
|
}
|
|
|
|
final success = await _azureAsrService.setSupportedLanguages(languages);
|
|
asrState.value = success ? AzureAsrState.initialized : AzureAsrState.error;
|
|
} catch (e) {
|
|
Logger.error('更新支持的语言列表出错: $e');
|
|
asrState.value = AzureAsrState.error;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
_recognitionSubscription?.cancel();
|
|
_recognitionSubscription = null;
|
|
|
|
if (_azureAsrService.isContinuousRecognitionActive()) {
|
|
_azureAsrService.stopContinuousRecognition();
|
|
}
|
|
|
|
super.onClose();
|
|
}
|
|
}
|