105 lines
3.2 KiB
Dart
105 lines
3.2 KiB
Dart
import 'package:flutter_tts/flutter_tts.dart';
|
|
import 'package:em2rp/utils/debug_log.dart';
|
|
|
|
/// Service de synthèse vocale pour lire des textes à haute voix
|
|
class TextToSpeechService {
|
|
static final FlutterTts _tts = FlutterTts();
|
|
static bool _isInitialized = false;
|
|
|
|
/// Initialiser le service TTS
|
|
static Future<void> initialize() async {
|
|
if (_isInitialized) return;
|
|
|
|
try {
|
|
await _tts.setLanguage('fr-FR');
|
|
await _tts.setSpeechRate(0.7); // Vitesse normale
|
|
await _tts.setVolume(1.0);
|
|
await _tts.setPitch(0.7); // Pitch plus bas pour une voix masculine
|
|
|
|
// Tenter de sélectionner une voix masculine si disponible
|
|
try {
|
|
final voices = await _tts.getVoices;
|
|
if (voices != null && voices is List) {
|
|
// Chercher une voix française masculine
|
|
final maleVoice = voices.firstWhere(
|
|
(voice) {
|
|
final voiceMap = voice as Map;
|
|
final name = voiceMap['name']?.toString().toLowerCase() ?? '';
|
|
final locale = voiceMap['locale']?.toString().toLowerCase() ?? '';
|
|
|
|
// Rechercher des voix françaises masculines
|
|
return locale.startsWith('fr') &&
|
|
(name.contains('male') || name.contains('homme') ||
|
|
name.contains('thomas') || name.contains('paul'));
|
|
},
|
|
orElse: () => null,
|
|
);
|
|
|
|
if (maleVoice != null) {
|
|
final voiceMap = maleVoice as Map;
|
|
await _tts.setVoice({
|
|
'name': voiceMap['name'],
|
|
'locale': voiceMap['locale'],
|
|
});
|
|
DebugLog.info('[TextToSpeechService] Voix masculine sélectionnée: ${voiceMap['name']}');
|
|
}
|
|
}
|
|
} catch (e) {
|
|
DebugLog.info('[TextToSpeechService] Impossible de sélectionner une voix spécifique, utilisation de la voix par défaut');
|
|
}
|
|
|
|
_isInitialized = true;
|
|
DebugLog.info('[TextToSpeechService] Service initialisé avec voix masculine');
|
|
} catch (e) {
|
|
DebugLog.error('[TextToSpeechService] Erreur lors de l\'initialisation', e);
|
|
}
|
|
}
|
|
|
|
/// Lire un texte à haute voix
|
|
static Future<void> speak(String text) async {
|
|
if (!_isInitialized) {
|
|
await initialize();
|
|
}
|
|
|
|
try {
|
|
// Arrêter toute lecture en cours
|
|
await _tts.stop();
|
|
|
|
// Lire le nouveau texte
|
|
await _tts.speak(text);
|
|
DebugLog.info('[TextToSpeechService] Lecture: $text');
|
|
} catch (e) {
|
|
DebugLog.error('[TextToSpeechService] Erreur lors de la lecture', e);
|
|
}
|
|
}
|
|
|
|
/// Arrêter la lecture en cours
|
|
static Future<void> stop() async {
|
|
try {
|
|
await _tts.stop();
|
|
} catch (e) {
|
|
DebugLog.error('[TextToSpeechService] Erreur lors de l\'arrêt', e);
|
|
}
|
|
}
|
|
|
|
/// Vérifier si le service est en train de lire
|
|
static Future<bool> isSpeaking() async {
|
|
try {
|
|
// FlutterTts ne fournit pas directement cette info, on retourne false par défaut
|
|
return false;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// Nettoyer les ressources
|
|
static Future<void> dispose() async {
|
|
try {
|
|
await _tts.stop();
|
|
} catch (e) {
|
|
DebugLog.error('[TextToSpeechService] Erreur lors du nettoyage', e);
|
|
}
|
|
}
|
|
}
|
|
|