dramaling-app/apps/mobile/lib/shared/providers/voice_recognition_provider....

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)';
}
}