Spaces:
Sleeping
Sleeping
import subprocess | |
import os | |
import time | |
import gradio as gr | |
from TTS.api import TTS | |
# Initialisation du modèle TTS | |
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2", gpu=False) | |
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.strip()) | |
os.makedirs(project_folder, exist_ok=True) | |
return project_folder | |
def generate_audio_section(text, section_name, project_folder, speaker): | |
file_name = f"{section_name.strip()}.wav" | |
output_path = os.path.join(project_folder, file_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}") | |
tts.tts_to_file( | |
text=text, | |
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. Choisissez une voix, entrez votre texte, et écoutez le résultat ! 🎤</p> | |
""" | |
article = """ | |
<div style='margin: 20px auto; text-align: center; padding: 10px; background-color: #e8f0fe; border-radius: 10px;'> | |
<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> | |
</div> | |
""" | |
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: | |
gr.Markdown(f"<h1 style='text-align: center; color: #4a90e2;'>{title}</h1>") | |
gr.Markdown(description) | |
with gr.Row(): | |
with gr.Column(scale=1): | |
project_name = gr.Textbox( | |
label="🗂️ Nom du projet", | |
placeholder="Entrez le nom du projet", | |
lines=1 | |
) | |
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") | |
project_folder_output = gr.State() | |
def on_create_project(name, spkr, agr): | |
folder_path = create_project(name, spkr, agr) | |
return folder_path | |
create_project_btn.click( | |
on_create_project, | |
inputs=[project_name, speaker, agree], | |
outputs=[project_folder_output] | |
) | |
section_textboxes = [] | |
def add_section(): | |
section_textbox = gr.Textbox( | |
label=f"✏️ Texte de la section {len(section_textboxes) + 1}", | |
placeholder="Entrez le texte pour cette section", | |
lines=5 | |
) | |
section_name_textbox = gr.Textbox( | |
label=f"📝 Nom de la section {len(section_textboxes) + 1}", | |
placeholder="Entrez le nom du fichier pour cette section", | |
lines=1 | |
) | |
section_textboxes.append((section_textbox, section_name_textbox)) | |
return section_textbox, section_name_textbox | |
add_section_btn = gr.Button("➕ Ajouter une section") | |
def remove_section(): | |
if section_textboxes: | |
removed_section = section_textboxes.pop() | |
return removed_section[0], removed_section[1] | |
remove_section_btn = gr.Button("➖ Supprimer une section") | |
add_section_btn.click(add_section) | |
remove_section_btn.click(remove_section) | |
generate_audio_btn = gr.Button("🎶 Générer l'audio") | |
def generate_all_sections(sections_data, proj_folder): | |
audio_outputs = [] | |
for text_box, name_box in sections_data: | |
text = text_box.value | |
name = name_box.value | |
audio_path = generate_audio_section(text, name.strip(), proj_folder.value, speaker.value) | |
audio_outputs.append(audio_path) | |
return audio_outputs | |
audio_outputs_display = [gr.Audio(label=f"🔊 Audio Section {i+1}") for i in range(len(section_textboxes))] | |
generate_audio_btn.click( | |
generate_all_sections, | |
inputs=[section_textboxes, project_folder_output], | |
outputs=audio_outputs_display | |
) | |
demo.launch(debug=True) | |