VSPAN commited on
Commit
3a70757
·
verified ·
1 Parent(s): 89df75e

Delete style.css

Browse files
Files changed (1) hide show
  1. style.css +0 -250
style.css DELETED
@@ -1,250 +0,0 @@
1
- import gradio as gr
2
- import edge_tts
3
- import asyncio
4
- import tempfile
5
- import re
6
- import emoji
7
- from flask import Flask, request, jsonify, render_template_string, send_from_directory
8
- import os
9
-
10
- app = Flask(__name__)
11
-
12
- # Функция для очистки текста от нежелательных символов и эмодзи
13
- def clean_text(text):
14
- # Удаление указанных символов
15
- text = re.sub(r'[*_~><]', '', text)
16
- # Удаление эмодзи
17
- text = emoji.replace_emoji(text, replace='')
18
- return text
19
-
20
- # Get all available voices
21
- async def get_voices():
22
- voices = await edge_tts.list_voices()
23
- return {f"{v['ShortName']} - {v['Locale']} ({v['Gender']})": v['ShortName'] for v in voices}
24
-
25
- # Text-to-speech function
26
- async def text_to_speech(text, voice, rate, pitch):
27
- if not text.strip():
28
- return None, "Пожалуйста, введите текст для озвучки."
29
- if not voice:
30
- return None, "Пожалуйста, выберите голос."
31
-
32
- # Очистка текста
33
- text = clean_text(text)
34
-
35
- voice_short_name = voice.split(" - ")[0]
36
- rate_str = f"{rate:+d}%"
37
- pitch_str = f"{pitch:+d}Hz"
38
- communicate = edge_tts.Communicate(text, voice_short_name, rate=rate_str, pitch=pitch_str)
39
- with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
40
- tmp_path = tmp_file.name
41
- try:
42
- await communicate.save(tmp_path)
43
- except Exception as e:
44
- return None, f"Произошла ошибка при конвертации текста в речь: {str(e)}"
45
- return tmp_path, None
46
-
47
- # HTML шаблон
48
- HTML_TEMPLATE = """
49
- <!DOCTYPE html>
50
- <html lang="ru">
51
- <head>
52
- <meta charset="UTF-8">
53
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
54
- <title>Озвучка с музыкальной атмосферой</title>
55
- <style>
56
- body {
57
- background-color: white;
58
- color: #FF6347; /* Томатный оранжевый */
59
- font-family: Arial, sans-serif;
60
- margin: 0;
61
- padding: 0;
62
- }
63
-
64
- header {
65
- background-color: #FF6347;
66
- color: white;
67
- padding: 10px 20px;
68
- text-align: center;
69
- }
70
-
71
- .container {
72
- padding: 20px;
73
- }
74
-
75
- .audio-control {
76
- position: fixed;
77
- bottom: 20px;
78
- left: 20px;
79
- background-color: white;
80
- border: 1px solid #FF6347;
81
- padding: 10px;
82
- border-radius: 5px;
83
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
84
- }
85
-
86
- button {
87
- background-color: #FF6347;
88
- color: white;
89
- border: none;
90
- padding: 10px 20px;
91
- border-radius: 5px;
92
- cursor: pointer;
93
- margin-top: 10px;
94
- }
95
-
96
- button:hover {
97
- background-color: #FF4500; /* Темный томатный оранжевый */
98
- }
99
- </style>
100
- </head>
101
- <body>
102
- <header>
103
- <h1>Озвучка с музыкальной атмосферой</h1>
104
- </header>
105
- <div class="container">
106
- <textarea id="text-input" rows="5" placeholder="Введите текст для озвучки"></textarea>
107
- <br>
108
- <select id="voice-select">
109
- <!-- Опции будут заполнены через JavaScript -->
110
- </select>
111
- <br>
112
- <label for="rate-slider">Скорость озвучки:</label>
113
- <input type="range" id="rate-slider" min="-50" max="50" value="0" step="1">
114
- <br>
115
- <label for="pitch-slider">Тон озвучки:</label>
116
- <input type="range" id="pitch-slider" min="-20" max="20" value="0" step="1">
117
- <br>
118
- <button onclick="generateAudio()">Озвучить</button>
119
- <br>
120
- <audio id="audio-player" controls style="display:none;"></audio>
121
- </div>
122
- <div class="audio-control">
123
- <label for="atmosphere-select">Атмосфера:</label>
124
- <select id="atmosphere-select">
125
- <option value="dynamic">Динамичная</option>
126
- <option value="calm">Спокойная</option>
127
- </select>
128
- <br>
129
- <button onclick="toggleMusic()">Выключить музыку</button>
130
- <audio id="background-music" loop></audio>
131
- </div>
132
- <script>
133
- let voices = [];
134
- let currentMusic = null;
135
-
136
- document.addEventListener('DOMContentLoaded', () => {
137
- fetch('/get_voices')
138
- .then(response => response.json())
139
- .then(data => {
140
- voices = data;
141
- const voiceSelect = document.getElementById('voice-select');
142
- Object.keys(voices).forEach(key => {
143
- const option = document.createElement('option');
144
- option.value = voices[key];
145
- option.textContent = key;
146
- voiceSelect.appendChild(option);
147
- });
148
- });
149
-
150
- const atmosphereSelect = document.getElementById('atmosphere-select');
151
- atmosphereSelect.addEventListener('change', () => {
152
- changeMusic(atmosphereSelect.value);
153
- });
154
-
155
- changeMusic(atmosphereSelect.value); // Устанавливаем музыку по умолчанию
156
- });
157
-
158
- function generateAudio() {
159
- const text = document.getElementById('text-input').value;
160
- const voice = document.getElementById('voice-select').value;
161
- const rate = document.getElementById('rate-slider').value;
162
- const pitch = document.getElementById('pitch-slider').value;
163
-
164
- if (!text.trim()) {
165
- alert('Пожалуйста, введите текст для озвучки.');
166
- return;
167
- }
168
- if (!voice) {
169
- alert('Пожалуйста, выберите голос.');
170
- return;
171
- }
172
-
173
- fetch('/tts', {
174
- method: 'POST',
175
- headers: {
176
- 'Content-Type': 'application/json'
177
- },
178
- body: JSON.stringify({ text, voice, rate, pitch })
179
- })
180
- .then(response => response.json())
181
- .then(data => {
182
- if (data.warning) {
183
- alert(data.warning);
184
- } else {
185
- const audioPlayer = document.getElementById('audio-player');
186
- audioPlayer.src = data.audio;
187
- audioPlayer.style.display = 'block';
188
- audioPlayer.play();
189
- audioPlayer.addEventListener('ended', () => {
190
- document.getElementById('background-music').play();
191
- });
192
- }
193
- });
194
- }
195
-
196
- function changeMusic(atmosphere) {
197
- const backgroundMusic = document.getElementById('background-music');
198
- backgroundMusic.src = `/music/${atmosphere}.mp3`;
199
- backgroundMusic.play();
200
- currentMusic = atmosphere;
201
- }
202
-
203
- function toggleMusic() {
204
- const backgroundMusic = document.getElementById('background-music');
205
- if (backgroundMusic.paused) {
206
- backgroundMusic.play();
207
- document.querySelector('.audio-control button').textContent = 'Выключить музыку';
208
- } else {
209
- backgroundMusic.pause();
210
- document.querySelector('.audio-control button').textContent = 'Включить музыку';
211
- }
212
- }
213
- </script>
214
- </body>
215
- </html>
216
- """
217
-
218
- @app.route('/get_voices', methods=['GET'])
219
- async def get_voices_route():
220
- voices = await get_voices()
221
- return jsonify(voices)
222
-
223
- @app.route('/tts', methods=['POST'])
224
- async def tts_route():
225
- data = request.get_json()
226
- text = data.get('text', '')
227
- voice = data.get('voice', '')
228
- rate = data.get('rate', 0)
229
- pitch = data.get('pitch', 0)
230
-
231
- audio, warning = await text_to_speech(text, voice, rate, pitch)
232
- if warning:
233
- return jsonify({'warning': warning})
234
- else:
235
- return jsonify({'audio': audio})
236
-
237
- @app.route('/')
238
- def index():
239
- return render_template_string(HTML_TEMPLATE)
240
-
241
- @app.route('/music/<path:path>')
242
- def serve_music(path):
243
- music_path = os.path.join('music', path)
244
- if os.path.exists(music_path):
245
- return send_from_directory('music', path)
246
- else:
247
- return "Файл не найден", 404
248
-
249
- if __name__ == "__main__":
250
- app.run(debug=True)