ernestmindres commited on
Commit
919124a
·
verified ·
1 Parent(s): ffdf9c3

Update tts_engine.py

Browse files
Files changed (1) hide show
  1. tts_engine.py +48 -85
tts_engine.py CHANGED
@@ -1,99 +1,62 @@
1
- # tts_engine.py
2
-
3
- import pyttsx3
4
  import os
5
  import sys
 
 
 
6
 
7
- _engine = None
 
8
 
9
  def get_tts_engine():
10
- """Initialise et retourne le moteur pyttsx3."""
11
- global _engine
12
-
13
- if _engine is not None:
14
- return _engine
15
-
16
- try:
17
- print("-> [TTS Engine] Tentative d'initialisation de pyttsx3...", file=sys.stderr, flush=True)
18
-
19
- # 1. MODIFICATION : Initialisation la plus simple possible (parfois suffit)
20
- # On force toujours 'espeak', mais on retire la 'rate' et 'voice' initiales pour l'instant
21
- # Le but est de laisser pyttsx3.init() réussir, puis appliquer les propriétés.
22
- _engine = pyttsx3.init('espeak')
23
-
24
- # 2. SÉLECTION EXPLICITE DE LA VOIX:
25
- voices = _engine.getProperty('voices')
26
-
27
- if not voices:
28
- raise Exception("Aucune voix eSpeak trouvée. Vérifiez votre installation système eSpeak.")
29
-
30
- # On applique la rate *après* l'initialisation réussie
31
- _engine.setProperty('rate', 150)
32
-
33
- # CORRECTION : On définit explicitement la première voix disponible
34
- _engine.setProperty('voice', voices[0].id)
35
-
36
- print("-> [TTS Engine] ✅ Initialisation réussie. Voix initiale définie sur:", voices[0].id, file=sys.stderr, flush=True)
37
-
38
- except Exception as e:
39
- # L'erreur est maintenant plus propre ou l'échec de init('espeak') si les données eSpeak manquent.
40
- print(f"!!! FATAL ERROR: pyttsx3 initialization failed. Erreur: {e}", file=sys.stderr, flush=True)
41
- _engine = None
42
-
43
- return _engine
44
 
45
  def reset_tts_engine():
46
- """Force la réinitialisation du moteur TTS. À utiliser après un fork."""
47
- global _engine
48
- if _engine is not None:
49
- print("-> [TTS Engine] Arrêt de l'ancien moteur.", file=sys.stderr, flush=True)
50
- _engine.stop()
51
- _engine = None
52
-
53
- def get_available_languages():
54
- """Récupère la liste des langues/voix disponibles."""
55
- engine = get_tts_engine()
56
- if not engine:
57
- return {}
58
-
59
- voices = engine.getProperty('voices')
60
- languages = {}
61
 
62
- # On essaie de mapper la voix eSpeak à un code de langue/nom
63
- for voice in voices:
64
- # L'ID de la voix eSpeak contient souvent le code de langue (ex: 'french', 'en-us')
65
- voice_id = voice.id.split('+')[0].replace(' ', '').lower()
66
-
67
- if 'en' in voice_id or 'english' in voice.name.lower():
68
- languages['English'] = voice.id
69
- elif 'fr' in voice_id or 'french' in voice.name.lower():
70
- languages['Français'] = voice.id
71
- elif 'es' in voice_id or 'spanish' in voice.name.lower():
72
- languages['Español'] = voice.id
73
-
74
- # Ajout d'une entrée par défaut pour chaque voix, si non déjà mappée
75
- if voice.name not in languages and voice.name != 'default':
76
- languages[voice.name] = voice.id
77
 
78
- # S'assurer d'avoir au moins une option si le mapping est faible
79
- if not languages and voices:
80
- languages['Default'] = voices[0].id
81
-
82
- return languages
 
 
 
 
 
 
 
 
83
 
84
  def text_to_audio_file(text, voice_id, output_path="output.wav"):
85
- """Convertit le texte en fichier audio avec la voix spécifiée."""
86
- engine = get_tts_engine()
87
- if not engine:
88
- raise Exception("Moteur TTS non initialisé.")
89
-
90
- # 1. Sélection de la voix
91
- engine.setProperty('voice', voice_id)
 
 
 
92
 
93
- # 2. Sauvegarde du fichier
94
- engine.save_to_file(text, output_path)
95
- engine.runAndWait()
 
 
 
 
 
 
 
 
 
 
 
96
 
97
- # NOTE: eSpeak génère par défaut un fichier .wav.
98
- return os.path.abspath(output_path)
99
 
 
 
 
 
 
1
  import os
2
  import sys
3
+ import subprocess # NOUVEL IMPORT
4
+
5
+ # Remplacer pyttsx3 par une fonction qui utilise directement la commande espeak
6
 
7
+ # --- Fonctions de compatibilité (non utilisées avec subprocess) ---
8
+ # Elles sont maintenues pour que gunicorn.conf.py ne génère pas d'erreur.
9
 
10
  def get_tts_engine():
11
+ """Puisque nous utilisons subprocess, il n'y a pas de moteur à initialiser."""
12
+ return True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  def reset_tts_engine():
15
+ """Ne fait rien, car il n'y a pas de moteur à réinitialiser."""
16
+ pass
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ # --- Logique de Langues/Voix ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ def get_available_languages():
21
+ """Retourne une liste des langues courantes eSpeak (sans pyttsx3, nous hardcodons)."""
22
+ # Ce sont les codes de voix utilisés directement par eSpeak
23
+ return {
24
+ 'Anglais (US)': 'en-us',
25
+ 'Français': 'fr',
26
+ 'Espagnol': 'es',
27
+ 'Allemand': 'de',
28
+ 'Italien': 'it',
29
+ 'Default (English)': 'en'
30
+ }
31
+
32
+ # --- Logique de Génération Audio ---
33
 
34
  def text_to_audio_file(text, voice_id, output_path="output.wav"):
35
+ """Convertit le texte en fichier audio .wav en utilisant la commande 'espeak'."""
36
+
37
+ # Construction de la commande eSpeak:
38
+ # espeak -v [VOIX] -w [OUTPUT_PATH] "[TEXTE]"
39
+ command = [
40
+ "espeak",
41
+ "-v", voice_id, # Sélectionne la voix
42
+ "-w", output_path, # Spécifie le fichier de sortie (.wav par défaut)
43
+ text # Le texte à parler
44
+ ]
45
 
46
+ try:
47
+ # Exécution de la commande
48
+ # Nous utilisons `check=True` pour lever une exception si la commande échoue
49
+ result = subprocess.run(command, check=True, capture_output=True, text=True)
50
+
51
+ # Le fichier audio a été généré avec succès
52
+ return os.path.abspath(output_path)
53
+
54
+ except subprocess.CalledProcessError as e:
55
+ # Erreur si espeak échoue (mauvaise voix, etc.)
56
+ raise Exception(f"La commande eSpeak a échoué. Erreur: {e.stderr}")
57
+ except FileNotFoundError:
58
+ # Erreur si la commande 'espeak' n'est pas trouvée (problème Dockerfile)
59
+ raise Exception("Le programme 'espeak' est introuvable. Vérifiez votre installation dans le Dockerfile.")
60
 
 
 
61
 
62
+ # Note: Le moteur n'est plus initialisé/stocké, donc les appels post_fork réussiront