Woziii commited on
Commit
549ef14
·
verified ·
1 Parent(s): bc681ea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +121 -152
app.py CHANGED
@@ -1,168 +1,137 @@
1
  import subprocess
2
  import os
3
- import time
4
  import gradio as gr
5
  from TTS.api import TTS
6
 
7
- # Initialisation du modèle TTS
8
  tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2", gpu=False)
9
 
 
10
  output_folder = "output_audio"
11
  os.makedirs(output_folder, exist_ok=True)
12
 
13
- def create_project(project_name, speaker, agree):
14
- if not agree:
15
- raise gr.Error("🚨 Veuillez accepter les conditions d'utilisation.")
16
-
17
- project_folder = os.path.join(output_folder, project_name.strip())
18
- os.makedirs(project_folder, exist_ok=True)
19
- return project_folder
20
-
21
- def generate_audio_section(text, section_name, project_folder, speaker):
22
- file_name = f"{section_name.strip()}.wav"
23
- output_path = os.path.join(project_folder, file_name)
24
-
25
- speaker_wav_paths = [os.path.join("examples", f) for f in os.listdir("examples") if f.startswith(speaker) and f.endswith(".wav")]
26
- if not speaker_wav_paths:
27
- raise gr.Error(f"🚨 Aucun fichier audio trouvé pour le speaker : {speaker}")
28
-
29
- tts.tts_to_file(
30
- text=text,
31
- file_path=output_path,
32
- speaker_wav=speaker_wav_paths,
33
- language="fr"
34
- )
 
35
 
36
- return output_path
37
-
38
- custom_css = """
39
- .gradio-container {
40
- font-family: 'Roboto', sans-serif;
41
- background-color: #f7f9fc;
42
- }
43
- .gr-form {
44
- background-color: white;
45
- border-radius: 15px;
46
- padding: 30px;
47
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
48
- }
49
- .gr-button {
50
- background-color: #4a90e2;
51
- border: none;
52
- color: white;
53
- font-weight: bold;
54
- transition: all 0.3s ease;
55
- }
56
- .gr-button:hover {
57
- background-color: #3a7bc8;
58
- transform: translateY(-2px);
59
- }
60
- .gr-input, .gr-dropdown {
61
- border: 1px solid #e0e0e0;
62
- border-radius: 8px;
63
- padding: 10px;
64
- }
65
- .gr-checkbox {
66
- margin-top: 10px;
67
- }
68
- .gr-form > div {
69
- margin-bottom: 20px;
70
- }
71
- """
72
-
73
- title = "🎙️ Synthèse Vocale XTTS"
74
- description = """
75
- <h3 style='text-align: center; margin-bottom: 1em;'>Bienvenue sur notre outil de synthèse vocale XTTS ! 🌟</h3>
76
- <p style='text-align: center;'>Générez une voix naturelle à partir de votre texte en français. Choisissez une voix, entrez votre texte, et écoutez le résultat ! 🎤</p>
77
- """
78
- article = """
79
- <div style='margin: 20px auto; text-align: center; padding: 10px; background-color: #e8f0fe; border-radius: 10px;'>
80
- <p>En utilisant cette démo, vous acceptez les <a href='https://coqui.ai/cpml' target='_blank' style='color: #4a90e2; text-decoration: none;'>conditions d'utilisation du modèle Coqui Public</a> 📜</p>
81
- </div>
82
- """
83
-
84
- available_speakers = list(set([f.split('_')[0] for f in os.listdir("examples") if f.endswith(".wav")]))
85
-
86
- with gr.Blocks(css=custom_css) as demo:
87
- gr.Markdown(f"<h1 style='text-align: center; color: #4a90e2;'>{title}</h1>")
88
- gr.Markdown(description)
89
-
90
- with gr.Row():
91
- with gr.Column(scale=1):
92
- project_name = gr.Textbox(
93
- label="🗂️ Nom du projet",
94
- placeholder="Entrez le nom du projet",
95
- lines=1
96
- )
97
- speaker = gr.Dropdown(
98
- label="🎤 Voix",
99
- choices=available_speakers,
100
- value=available_speakers[0] if available_speakers else None
101
- )
102
- agree = gr.Checkbox(
103
- label="✅ J'accepte les conditions d'utilisation",
104
- value=False
105
- )
106
- create_project_btn = gr.Button("🔨 Créer le projet", variant="primary")
107
-
108
- project_folder_output = gr.State()
109
-
110
- def on_create_project(name, spkr, agr):
111
- folder_path = create_project(name, spkr, agr)
112
- return folder_path
113
-
114
- create_project_btn.click(
115
- on_create_project,
116
  inputs=[project_name, speaker, agree],
117
- outputs=[project_folder_output]
118
  )
119
 
120
- section_textboxes = []
121
-
122
- def add_section():
123
- section_textbox = gr.Textbox(
124
- label=f"✏️ Texte de la section {len(section_textboxes) + 1}",
125
- placeholder="Entrez le texte pour cette section",
126
- lines=5
127
- )
128
- section_name_textbox = gr.Textbox(
129
- label=f"📝 Nom de la section {len(section_textboxes) + 1}",
130
- placeholder="Entrez le nom du fichier pour cette section",
131
- lines=1
132
- )
133
- section_textboxes.append((section_textbox, section_name_textbox))
134
- return [textbox for textbox_pair in section_textboxes for textbox in textbox_pair]
135
-
136
- add_section_btn = gr.Button("➕ Ajouter une section")
137
-
138
- def remove_section():
139
- if section_textboxes:
140
- removed_section = section_textboxes.pop()
141
- return [textbox for textbox_pair in section_textboxes for textbox in textbox_pair]
142
- return []
143
-
144
- remove_section_btn = gr.Button("➖ Supprimer une section")
145
-
146
- add_section_btn.click(add_section)
147
- remove_section_btn.click(remove_section)
148
-
149
- generate_audio_btn = gr.Button("🎶 Générer l'audio")
150
-
151
- audio_outputs_display = []
152
-
153
- def generate_all_sections(sections_data, proj_folder):
154
- audio_outputs = []
155
- for text_box, name_box in sections_data:
156
- text = text_box.value
157
- name = name_box.value
158
- audio_path = generate_audio_section(text, name.strip(), proj_folder.value, speaker.value)
159
- audio_outputs.append(audio_path)
160
- return audio_outputs
161
-
162
- generate_audio_btn.click(
163
- generate_all_sections,
164
- inputs=[section_textboxes, project_folder_output],
165
- outputs=audio_outputs_display
166
  )
167
 
168
- demo.launch(debug=True)
 
 
 
 
 
 
1
  import subprocess
2
  import os
 
3
  import gradio as gr
4
  from TTS.api import TTS
5
 
6
+ # Initialisation du modèle TTS avec GPU désactivé
7
  tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2", gpu=False)
8
 
9
+ # Répertoire de sortie pour tous les fichiers audio
10
  output_folder = "output_audio"
11
  os.makedirs(output_folder, exist_ok=True)
12
 
13
+ # Fonction pour générer un fichier audio à partir d'une section
14
+ def generate_section_audio(project_name, section_name, text, speaker):
15
+ try:
16
+ # Création du sous-dossier pour le projet
17
+ project_path = os.path.join(output_folder, project_name)
18
+ os.makedirs(project_path, exist_ok=True)
19
+
20
+ # Définir le chemin de sortie pour cette section
21
+ file_name = f"{section_name}.wav"
22
+ output_path = os.path.join(project_path, file_name)
23
+
24
+ # Vérifier la disponibilité des fichiers audio pour le speaker
25
+ speaker_wav_paths = [os.path.join("examples", f) for f in os.listdir("examples") if f.startswith(speaker) and f.endswith(".wav")]
26
+ if not speaker_wav_paths:
27
+ raise ValueError(f"Aucun fichier audio trouvé pour le speaker : {speaker}")
28
+
29
+ # Génération de l'audio
30
+ tts.tts_to_file(
31
+ text=text,
32
+ file_path=output_path,
33
+ speaker_wav=speaker_wav_paths,
34
+ language="fr"
35
+ )
36
 
37
+ return output_path # Retourne le chemin de l'audio généré
38
+ except Exception as e:
39
+ return str(e) # Retourne l'erreur pour gestion dans l'interface
40
+
41
+ # Fonction pour gérer la visibilité des étapes
42
+ def update_steps(current_step, target_step):
43
+ return {"visible": target_step == 1}, {"visible": target_step == 2}, {"visible": target_step == 3}
44
+
45
+ # Interface Gradio
46
+ with gr.Blocks() as demo:
47
+ # État global pour gérer les sections
48
+ sections = gr.State(value=[])
49
+
50
+ # Introduction générale
51
+ gr.Markdown("""
52
+ # 🎙️ Synthèse Vocale Margaux
53
+ ## 👋 Bienvenue sur Margaux - Votre outil de synthèse vocale avancée
54
+ Margaux vous permet de générer des voix off naturelles à partir de textes, structurées par sections pour une meilleure qualité audio.
55
+ **Étapes principales :**
56
+ 1. 🛠️ **Créer un projet** : Définissez le nom du projet et choisissez la voix.
57
+ 2. ✍️ **Ajouter des sections** : Divisez votre texte en parties claires, chacune avec un nom unique.
58
+ 3. 🎧 **Générer les audios** : Chaque section est transformée en fichier audio individuel.
59
+ 4. 📁 **Sauvegardez le projet** : Finalisez et récupérez les fichiers validés.
60
+ """)
61
+
62
+ # Étape 1 : Création du Projet
63
+ with gr.Row(visible=True) as step1:
64
+ gr.Markdown("### 🛠️ Étape 1 : Création du Projet")
65
+ project_name = gr.Textbox(label="Nom du Projet", placeholder="Exemple : Capsule_Video_PLU")
66
+ speaker = gr.Dropdown(label="Voix 🎙️", choices=["Margaux"], value="Margaux") # Liste de voix
67
+ agree = gr.Checkbox(label="✅ J'accepte les conditions d'utilisation")
68
+ project_message = gr.Markdown(value="", visible=False) # Composant pour afficher les messages
69
+ next_btn_1 = gr.Button("Suivant ➡️")
70
+
71
+ # Étape 2 : Gestion des Sections
72
+ with gr.Row(visible=False) as step2:
73
+ gr.Markdown("### ✍️ Étape 2 : Ajoutez vos Sections")
74
+ sections_list = gr.Column() # Conteneur pour afficher les sections ajoutées
75
+ add_section_btn = gr.Button("+ Ajouter une Section ➕")
76
+ remove_section_btn = gr.Button("- Supprimer la dernière Section ➖")
77
+ prev_btn_2 = gr.Button("⬅️ Précédent")
78
+ next_btn_2 = gr.Button("Suivant ➡️")
79
+
80
+ # Étape 3 : Génération des Audios
81
+ with gr.Row(visible=False) as step3:
82
+ gr.Markdown("### 🎧 Étape 3 : Génération des Audios")
83
+ results_output = gr.Column() # Conteneur pour afficher les résultats
84
+ generate_btn = gr.Button("Générer les Audios ▶️")
85
+ prev_btn_3 = gr.Button("⬅️ Précédent")
86
+ save_project_btn = gr.Button("Sauvegarder le Projet ✅")
87
+
88
+ # Actions des Boutons
89
+ def create_project(project_name, speaker, agree):
90
+ if not agree:
91
+ return "❗ Veuillez accepter les conditions d'utilisation.", False, False
92
+ if not project_name:
93
+ return "❗ Le nom du projet est obligatoire.", False, False
94
+ os.makedirs(os.path.join(output_folder, project_name), exist_ok=True)
95
+ return f" Projet '{project_name}' créé avec succès !", True, False
96
+
97
+ next_btn_1.click(
98
+ create_project,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  inputs=[project_name, speaker, agree],
100
+ outputs=[project_message, step1, step2],
101
  )
102
 
103
+ def add_section(sections):
104
+ section = {"name": f"Section_{len(sections) + 1}", "text": ""}
105
+ sections.append(section)
106
+ return sections
107
+
108
+ add_section_btn.click(add_section, inputs=[sections], outputs=[sections_list])
109
+
110
+ def remove_section(sections):
111
+ if sections:
112
+ sections.pop()
113
+ return sections
114
+
115
+ remove_section_btn.click(remove_section, inputs=[sections], outputs=[sections_list])
116
+
117
+ def generate_audios(project_name, sections, speaker):
118
+ results = []
119
+ for section in sections:
120
+ name = section["name"]
121
+ text = section["text"]
122
+ audio_path = generate_section_audio(project_name, name, text, speaker)
123
+ results.append(audio_path)
124
+ return results
125
+
126
+ generate_btn.click(
127
+ generate_audios,
128
+ inputs=[project_name, sections, speaker],
129
+ outputs=[results_output],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  )
131
 
132
+ prev_btn_2.click(lambda: (True, False), inputs=None, outputs=[step1, step2])
133
+ next_btn_2.click(lambda: (False, True), inputs=None, outputs=[step2, step3])
134
+ prev_btn_3.click(lambda: (True, False), inputs=None, outputs=[step2, step3])
135
+
136
+ # Lancement de l'interface
137
+ demo.launch(debug=True)