174 lines
4.8 KiB
Dart
174 lines
4.8 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../../core/services/voice_recognition_service.dart';
|
|
|
|
/// 語音識別服務提供者
|
|
final voiceRecognitionServiceProvider = Provider<VoiceRecognitionService>((ref) {
|
|
return VoiceRecognitionService();
|
|
});
|
|
|
|
/// 語音識別狀態提供者
|
|
final voiceRecognitionStateProvider = StreamProvider<VoiceRecognitionState>((ref) {
|
|
final service = ref.watch(voiceRecognitionServiceProvider);
|
|
return service.stateStream;
|
|
});
|
|
|
|
/// 語音識別結果提供者
|
|
final voiceRecognitionResultProvider = StreamProvider<VoiceRecognitionResult>((ref) {
|
|
final service = ref.watch(voiceRecognitionServiceProvider);
|
|
return service.resultStream;
|
|
});
|
|
|
|
/// 語音音量提供者
|
|
final voiceSoundLevelProvider = StreamProvider<double>((ref) {
|
|
final service = ref.watch(voiceRecognitionServiceProvider);
|
|
return service.soundLevelStream;
|
|
});
|
|
|
|
/// 語音識別控制器提供者
|
|
final voiceRecognitionControllerProvider = StateNotifierProvider<VoiceRecognitionController, VoiceRecognitionControllerState>((ref) {
|
|
final service = ref.watch(voiceRecognitionServiceProvider);
|
|
return VoiceRecognitionController(service);
|
|
});
|
|
|
|
/// 語音識別控制器
|
|
class VoiceRecognitionController extends StateNotifier<VoiceRecognitionControllerState> {
|
|
final VoiceRecognitionService _voiceService;
|
|
|
|
VoiceRecognitionController(this._voiceService) : super(VoiceRecognitionControllerState.initial()) {
|
|
_init();
|
|
}
|
|
|
|
/// 初始化
|
|
Future<void> _init() async {
|
|
final success = await _voiceService.initialize();
|
|
state = state.copyWith(
|
|
isInitialized: success,
|
|
isAvailable: _voiceService.isAvailable,
|
|
);
|
|
}
|
|
|
|
/// 開始語音識別
|
|
Future<void> startListening({
|
|
String languageId = 'zh-TW',
|
|
Duration timeout = const Duration(seconds: 30),
|
|
bool partialResults = true,
|
|
}) async {
|
|
if (!state.isInitialized || !state.isAvailable) {
|
|
return;
|
|
}
|
|
|
|
state = state.copyWith(isProcessing: true);
|
|
|
|
final success = await _voiceService.startListening(
|
|
languageId: languageId,
|
|
timeout: timeout,
|
|
partialResults: partialResults,
|
|
);
|
|
|
|
state = state.copyWith(
|
|
isProcessing: false,
|
|
isListening: success,
|
|
currentLanguage: languageId,
|
|
);
|
|
}
|
|
|
|
/// 停止語音識別
|
|
Future<void> stopListening() async {
|
|
if (!state.isListening) return;
|
|
|
|
state = state.copyWith(isProcessing: true);
|
|
await _voiceService.stopListening();
|
|
state = state.copyWith(
|
|
isProcessing: false,
|
|
isListening: false,
|
|
lastResult: null,
|
|
);
|
|
}
|
|
|
|
/// 取消語音識別
|
|
Future<void> cancel() async {
|
|
if (!state.isListening) return;
|
|
|
|
state = state.copyWith(isProcessing: true);
|
|
await _voiceService.cancel();
|
|
state = state.copyWith(
|
|
isProcessing: false,
|
|
isListening: false,
|
|
lastResult: null,
|
|
);
|
|
}
|
|
|
|
/// 更新最後的識別結果
|
|
void updateLastResult(VoiceRecognitionResult result) {
|
|
state = state.copyWith(lastResult: result);
|
|
}
|
|
|
|
/// 更新語言
|
|
void setLanguage(String languageId) {
|
|
state = state.copyWith(currentLanguage: languageId);
|
|
}
|
|
|
|
/// 重新初始化
|
|
Future<void> reinitialize() async {
|
|
state = VoiceRecognitionControllerState.initial();
|
|
await _init();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_voiceService.dispose();
|
|
super.dispose();
|
|
}
|
|
}
|
|
|
|
/// 語音識別控制器狀態
|
|
class VoiceRecognitionControllerState {
|
|
final bool isInitialized;
|
|
final bool isAvailable;
|
|
final bool isListening;
|
|
final bool isProcessing;
|
|
final String currentLanguage;
|
|
final VoiceRecognitionResult? lastResult;
|
|
|
|
VoiceRecognitionControllerState({
|
|
required this.isInitialized,
|
|
required this.isAvailable,
|
|
required this.isListening,
|
|
required this.isProcessing,
|
|
required this.currentLanguage,
|
|
this.lastResult,
|
|
});
|
|
|
|
factory VoiceRecognitionControllerState.initial() {
|
|
return VoiceRecognitionControllerState(
|
|
isInitialized: false,
|
|
isAvailable: false,
|
|
isListening: false,
|
|
isProcessing: false,
|
|
currentLanguage: 'zh-TW',
|
|
);
|
|
}
|
|
|
|
VoiceRecognitionControllerState copyWith({
|
|
bool? isInitialized,
|
|
bool? isAvailable,
|
|
bool? isListening,
|
|
bool? isProcessing,
|
|
String? currentLanguage,
|
|
VoiceRecognitionResult? lastResult,
|
|
}) {
|
|
return VoiceRecognitionControllerState(
|
|
isInitialized: isInitialized ?? this.isInitialized,
|
|
isAvailable: isAvailable ?? this.isAvailable,
|
|
isListening: isListening ?? this.isListening,
|
|
isProcessing: isProcessing ?? this.isProcessing,
|
|
currentLanguage: currentLanguage ?? this.currentLanguage,
|
|
lastResult: lastResult ?? this.lastResult,
|
|
);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return 'VoiceRecognitionControllerState(initialized: $isInitialized, available: $isAvailable, listening: $isListening, processing: $isProcessing, language: $currentLanguage)';
|
|
}
|
|
} |