| import subprocess | |
| import gradio as gr | |
| from TTS.api import TTS | |
| import os | |
| import time | |
| import torch | |
| tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2", gpu=True) | |
| output_folder = "output_audio" | |
| os.makedirs(output_folder, exist_ok=True) | |
| def predict(prompt, speaker, agree, subfolder_name, file_name): | |
| if not agree: | |
| raise gr.Error("Veuillez accepter les conditions d'utilisation.") | |
| subfolder_name = subfolder_name.strip() or f"session_{int(time.time())}" | |
| session_folder = os.path.join(output_folder, subfolder_name) | |
| os.makedirs(session_folder, exist_ok=True) | |
| file_name = file_name.strip() or "output.wav" | |
| if not file_name.endswith(".wav"): | |
| file_name += ".wav" | |
| output_path = os.path.join(session_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=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. 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=2): | |
| prompt = gr.Textbox( | |
| label="Texte pour la synthèse vocale", | |
| info="Une ou deux phrases à la fois sont préférables (max : 10)", | |
| placeholder="Bonjour ! Comment allez-vous aujourd'hui ?", | |
| lines=5 | |
| ) | |
| with gr.Column(scale=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 | |
| ) | |
| subfolder_name = gr.Textbox( | |
| label="Nom du sous-dossier (facultatif)", | |
| placeholder="Nom du sous-dossier pour stocker l'audio" | |
| ) | |
| file_name = gr.Textbox( | |
| label="Nom du fichier (facultatif)", | |
| placeholder="Nom du fichier audio généré" | |
| ) | |
| generate_btn = gr.Button("Générer la voix", variant="primary") | |
| audio_output = gr.Audio(label="Audio généré") | |
| generate_btn.click( | |
| predict, | |
| inputs=[prompt, speaker, agree, subfolder_name, file_name], | |
| outputs=[audio_output] | |
| ) | |
| gr.Markdown(article) | |
| demo.launch(debug=True) |