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.
128 lines
3.1 KiB
128 lines
3.1 KiB
import 'package:get/get.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import '../../../data/services/voice_recognition_service.dart';
|
|
|
|
class VoiceInputController extends GetxController {
|
|
final VoiceRecognitionService _recognitionService;
|
|
|
|
// Observable states
|
|
final isConnecting = true.obs;
|
|
final isMuted = false.obs;
|
|
final isRecording = false.obs;
|
|
final recognizedText = ''.obs;
|
|
|
|
// Callbacks
|
|
final Function(String) onRecordingResult;
|
|
final VoidCallback onClosePanel;
|
|
final Function(String) onRecognizing;
|
|
|
|
VoiceInputController({
|
|
required this.onRecordingResult,
|
|
required this.onClosePanel,
|
|
required this.onRecognizing,
|
|
}) : _recognitionService = Get.find<VoiceRecognitionService>();
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
_setupRecognitionCallbacks();
|
|
_initializeRecognition();
|
|
}
|
|
|
|
void _setupRecognitionCallbacks() {
|
|
_recognitionService.onRecognitionResult = (result) {
|
|
if (isMuted.value) return;
|
|
recognizedText.value = result;
|
|
onRecognizing(result);
|
|
};
|
|
|
|
_recognitionService.onError = (error) {
|
|
Get.snackbar(
|
|
'Error',
|
|
'语音识别失败: $error',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
stopRecording();
|
|
};
|
|
|
|
_recognitionService.onRecognitionComplete = () {
|
|
stopRecording();
|
|
if (!isMuted.value && recognizedText.value.isNotEmpty) {
|
|
onRecordingResult(recognizedText.value);
|
|
recognizedText.value = '';
|
|
startRecording();
|
|
}
|
|
};
|
|
}
|
|
|
|
Future<void> _initializeRecognition() async {
|
|
try {
|
|
isConnecting.value = true;
|
|
await _recognitionService.startRecognition();
|
|
isConnecting.value = false;
|
|
} catch (e) {
|
|
Get.snackbar(
|
|
'Error',
|
|
'初始化语音识别失败: $e',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
onClosePanel();
|
|
}
|
|
}
|
|
|
|
Future<void> startRecording() async {
|
|
try {
|
|
await _recognitionService.startRecognition();
|
|
isRecording.value = true;
|
|
recognizedText.value = '';
|
|
} catch (e) {
|
|
Get.snackbar(
|
|
'Error',
|
|
'启动语音识别失败: $e',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> stopRecording() async {
|
|
if (!isRecording.value) return;
|
|
|
|
try {
|
|
await _recognitionService.stopRecognition();
|
|
} catch (e) {
|
|
debugPrint('Error stopping recording: $e');
|
|
} finally {
|
|
isRecording.value = false;
|
|
}
|
|
}
|
|
|
|
void toggleMute() {
|
|
isMuted.value = !isMuted.value;
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
// 停止录音
|
|
stopRecording();
|
|
|
|
// 清理回调
|
|
_recognitionService.onRecognitionResult = null;
|
|
_recognitionService.onError = null;
|
|
_recognitionService.onRecognitionComplete = null;
|
|
|
|
// 重置状态
|
|
isConnecting.value = false;
|
|
isMuted.value = false;
|
|
isRecording.value = false;
|
|
recognizedText.value = '';
|
|
|
|
// 确保语音识别服务停止
|
|
try {
|
|
_recognitionService.stopRecognition();
|
|
} catch (e) {
|
|
debugPrint('Error stopping recognition service: $e');
|
|
}
|
|
|
|
super.onClose();
|
|
}
|
|
}
|