File size: 4,662 Bytes
a5c86e8
9883968
 
6bca271
 
 
328d70f
f31c7bc
edf2a53
6bca271
f31c7bc
 
 
328d70f
 
 
 
6bca271
328d70f
 
 
6bca271
328d70f
 
 
 
6bca271
 
328d70f
6bca271
328d70f
 
 
 
6bca271
328d70f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bca271
328d70f
 
 
 
 
6bca271
 
328d70f
 
 
 
6bca271
 
 
328d70f
6bca271
328d70f
6bca271
 
328d70f
 
6bca271
 
 
328d70f
6bca271
 
 
 
328d70f
6bca271
 
 
 
328d70f
6bca271
c6e52e2
6bca271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c6e52e2
6bca271
 
 
 
328d70f
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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)