Spaces:
Sleeping
Sleeping
import subprocess | |
import gradio as gr | |
from TTS.api import TTS | |
import os | |
import time | |
# Initialisation du modèle TTS | |
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2", gpu=False) | |
# Dossier pour les fichiers audio générés | |
output_folder = "output_audio" | |
os.makedirs(output_folder, exist_ok=True) | |
def create_project(project_name, speaker, agree): | |
if not agree: | |
raise gr.Error("Veuillez accepter les conditions d'utilisation.") | |
project_folder = os.path.join(output_folder, project_name) | |
os.makedirs(project_folder, exist_ok=True) | |
return project_folder | |
def generate_audio(prompt, speaker, project_folder, section_name): | |
speaker_wav_paths = [os.path.join("examples", f) for f in os.listdir("examples") if f.startswith(speaker) and f.endswith(".wav")] | |
if not speaker_wav_paths: | |
raise gr.Error(f"Aucun fichier audio trouvé pour le speaker : {speaker}") | |
output_path = os.path.join(project_folder, f"{section_name}.wav") | |
tts.tts_to_file( | |
text=prompt, | |
file_path=output_path, | |
speaker_wav=speaker_wav_paths, | |
language="fr" | |
) | |
return output_path | |
custom_css = """ | |
.gradio-container { | |
font-family: 'Roboto', sans-serif; | |
background-color: #f7f9fc; | |
} | |
.gr-form { | |
background-color: white; | |
border-radius: 15px; | |
padding: 30px; | |
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); | |
} | |
.gr-button { | |
background-color: #4a90e2; | |
border: none; | |
color: white; | |
font-weight: bold; | |
transition: all 0.3s ease; | |
} | |
.gr-button:hover { | |
background-color: #3a7bc8; | |
transform: translateY(-2px); | |
} | |
.gr-input, .gr-dropdown { | |
border: 1px solid #e0e0e0; | |
border-radius: 8px; | |
padding: 10px; | |
} | |
.gr-checkbox { | |
margin-top: 10px; | |
} | |
.gr-form > div { | |
margin-bottom: 20px; | |
} | |
""" | |
title = "🎙️ Synthèse Vocale XTTS" | |
description = """ | |
<h3 style='text-align: center; margin-bottom: 1em;'>Bienvenue sur notre outil de synthèse vocale XTTS !</h3> | |
<p style='text-align: center;'>Générez une voix naturelle à partir de votre texte en français. Créez un projet et ajoutez des sections pour votre script.</p> | |
""" | |
available_speakers = list(set([f.split('_')[0] for f in os.listdir("examples") if f.endswith(".wav")])) | |
with gr.Blocks(css=custom_css) as demo: | |
# Étape 1 : Création du Projet | |
gr.Markdown(f"<h1 style='text-align: center; color: #4a90e2;'>{title}</h1>") | |
gr.Markdown(description) | |
with gr.Row(): | |
project_name = gr.Textbox(label="Nom du projet", placeholder="Entrez le nom du projet") | |
speaker = gr.Dropdown(label="Voix", choices=available_speakers, value=available_speakers[0] if available_speakers else None) | |
agree = gr.Checkbox(label="J'accepte les conditions d'utilisation", value=False) | |
create_project_btn = gr.Button("Créer le Projet", variant="primary") | |
# Étape 2 : Gestion des Sections | |
sections = [] | |
def add_section(): | |
section_name = f"Section {len(sections) + 1}" | |
sections.append({"name": section_name, "text": ""}) | |
return sections | |
def remove_section(index): | |
if index < len(sections): | |
sections.pop(index) | |
return sections | |
def update_section_text(index, text): | |
if index < len(sections): | |
sections[index]["text"] = text | |
return sections | |
section_outputs = [] | |
with gr.Column(): | |
section_list = gr.State(value=sections) | |
def render_sections(sections): | |
return [gr.Row([ | |
gr.Textbox(label=f"Texte pour {section['name']}", value=section['text'], lines=5).change(update_section_text, inputs=[sections.index(section)], outputs=None), | |
gr.Textbox(label="Nom du fichier", value=section['name'], interactive=False), | |
gr.Button("Régénérer", variant="secondary").click(generate_audio, inputs=[section['text'], speaker, project_folder, section['name']], outputs=[gr.Audio(label=f"Audio {section['name']}")]) | |
]) for section in sections] | |
with gr.Row(): | |
add_section_btn = gr.Button("+ Ajouter une section") | |
remove_section_btn = gr.Button("- Supprimer la dernière section") | |
add_section_btn.click(add_section, outputs=section_list) | |
remove_section_btn.click(remove_section, inputs=[len(sections)-1], outputs=section_list) | |
section_output_area = gr.Column() | |
# Dynamically render sections | |
with section_output_area: | |
for section in render_sections(sections): | |
section_output_area.append(section) | |
demo.launch(debug=True) | |