Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -4,7 +4,6 @@ import asyncio
|
|
4 |
import tempfile
|
5 |
import re
|
6 |
import emoji
|
7 |
-
|
8 |
# Функция для очистки текста от нежелательных символов и эмодзи
|
9 |
def clean_text(text):
|
10 |
# Удаление указанных символов
|
@@ -12,12 +11,10 @@ def clean_text(text):
|
|
12 |
# Удаление эмодзи
|
13 |
text = emoji.replace_emoji(text, replace='')
|
14 |
return text
|
15 |
-
|
16 |
# Get all available voices
|
17 |
async def get_voices():
|
18 |
voices = await edge_tts.list_voices()
|
19 |
return {f"{v['ShortName']} - {v['Locale']} ({v['Gender']})": v['ShortName'] for v in voices}
|
20 |
-
|
21 |
# Text-to-speech function
|
22 |
async def text_to_speech(text, voice, rate, pitch):
|
23 |
if not text.strip():
|
@@ -39,7 +36,6 @@ async def text_to_speech(text, voice, rate, pitch):
|
|
39 |
except Exception as e:
|
40 |
return None, f"An error occurred during text-to-speech conversion: {str(e)}"
|
41 |
return tmp_path, None
|
42 |
-
|
43 |
# Gradio interface function
|
44 |
def tts_interface(*args):
|
45 |
loop = asyncio.new_event_loop()
|
@@ -49,13 +45,10 @@ def tts_interface(*args):
|
|
49 |
if warning:
|
50 |
return None, gr.update(value=f"<span style='color:red;'>{warning}</span>", visible=True)
|
51 |
return audio, gr.update(visible=False)
|
52 |
-
|
53 |
# Custom CSS
|
54 |
custom_css = """
|
55 |
-
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css');
|
56 |
-
|
57 |
body {
|
58 |
-
background: linear-gradient(
|
59 |
animation: gradient 15s ease infinite;
|
60 |
font-family: 'Arial', sans-serif;
|
61 |
}
|
@@ -66,105 +59,42 @@ body {
|
|
66 |
}
|
67 |
.gradio-container {
|
68 |
background-color: rgba(255, 255, 255, 0.1);
|
69 |
-
border-radius:
|
70 |
-
box-shadow: 0 8px
|
71 |
-
padding:
|
72 |
-
max-width: 600px;
|
73 |
-
margin: 0 auto;
|
74 |
}
|
75 |
button {
|
76 |
-
background: linear-gradient(
|
77 |
border: none;
|
78 |
color: white;
|
79 |
-
padding:
|
80 |
text-align: center;
|
81 |
text-decoration: none;
|
82 |
display: inline-block;
|
83 |
-
font-size:
|
84 |
-
margin:
|
85 |
cursor: pointer;
|
86 |
-
border-radius:
|
87 |
-
transition: background 0.3s
|
88 |
}
|
89 |
button:hover {
|
90 |
-
background: linear-gradient(
|
91 |
-
transform: scale(1.05);
|
92 |
}
|
93 |
textarea, select, input[type="range"] {
|
94 |
background-color: rgba(255, 255, 255, 0.2);
|
95 |
border: 1px solid rgba(255, 255, 255, 0.3);
|
96 |
color: white;
|
97 |
-
padding:
|
98 |
-
border-radius:
|
99 |
-
|
100 |
-
box-sizing: border-box;
|
101 |
-
transition: background 0.3s, transform 0.2s;
|
102 |
}
|
103 |
textarea:focus, select:focus, input[type="range"]:focus {
|
104 |
background-color: rgba(255, 255, 255, 0.3);
|
105 |
-
transform: scale(1.02);
|
106 |
-
}
|
107 |
-
input[type="range"]::-webkit-slider-thumb {
|
108 |
-
-webkit-appearance: none;
|
109 |
-
appearance: none;
|
110 |
-
width: 20px;
|
111 |
-
height: 20px;
|
112 |
-
background: linear-gradient(135deg, #ff7e5f, #feb47b);
|
113 |
-
border-radius: 50%;
|
114 |
-
cursor: pointer;
|
115 |
-
transition: background 0.3s;
|
116 |
-
}
|
117 |
-
input[type="range"]::-webkit-slider-thumb:hover {
|
118 |
-
background: linear-gradient(135deg, #feb47b, #ff7e5f);
|
119 |
-
}
|
120 |
-
input[type="range"]::-moz-range-thumb {
|
121 |
-
width: 20px;
|
122 |
-
height: 20px;
|
123 |
-
background: linear-gradient(135deg, #ff7e5f, #feb47b);
|
124 |
-
border-radius: 50%;
|
125 |
-
cursor: pointer;
|
126 |
-
transition: background 0.3s;
|
127 |
-
}
|
128 |
-
input[type="range"]::-moz-range-thumb:hover {
|
129 |
-
background: linear-gradient(135deg, #feb47b, #ff7e5f);
|
130 |
}
|
131 |
.warning {
|
132 |
color: red;
|
133 |
-
margin-top: 10px;
|
134 |
-
}
|
135 |
-
.audio-controls {
|
136 |
-
display: flex;
|
137 |
-
align-items: center;
|
138 |
-
justify-content: center;
|
139 |
-
margin-top: 20px;
|
140 |
-
}
|
141 |
-
.audio-controls button {
|
142 |
-
margin: 0 10px;
|
143 |
-
padding: 15px;
|
144 |
-
border-radius: 50%;
|
145 |
-
width: 50px;
|
146 |
-
height: 50px;
|
147 |
-
display: flex;
|
148 |
-
align-items: center;
|
149 |
-
justify-content: center;
|
150 |
-
transition: background 0.3s, transform 0.2s;
|
151 |
-
font-size: 20px;
|
152 |
-
}
|
153 |
-
.audio-controls button:hover {
|
154 |
-
background: linear-gradient(135deg, #feb47b, #ff7e5f);
|
155 |
-
transform: scale(1.1);
|
156 |
-
}
|
157 |
-
.audio-controls .play-icon {
|
158 |
-
font-size: 24px;
|
159 |
-
}
|
160 |
-
.audio-controls .pause-icon {
|
161 |
-
font-size: 24px;
|
162 |
-
}
|
163 |
-
.audio-controls .volume-icon {
|
164 |
-
font-size: 24px;
|
165 |
}
|
166 |
"""
|
167 |
-
|
168 |
# Create Gradio application
|
169 |
async def create_demo():
|
170 |
voices = await get_voices()
|
@@ -194,7 +124,6 @@ async def create_demo():
|
|
194 |
css=custom_css
|
195 |
)
|
196 |
return demo
|
197 |
-
|
198 |
# Run the application
|
199 |
if __name__ == "__main__":
|
200 |
demo = asyncio.run(create_demo())
|
|
|
4 |
import tempfile
|
5 |
import re
|
6 |
import emoji
|
|
|
7 |
# Функция для очистки текста от нежелательных символов и эмодзи
|
8 |
def clean_text(text):
|
9 |
# Удаление указанных символов
|
|
|
11 |
# Удаление эмодзи
|
12 |
text = emoji.replace_emoji(text, replace='')
|
13 |
return text
|
|
|
14 |
# Get all available voices
|
15 |
async def get_voices():
|
16 |
voices = await edge_tts.list_voices()
|
17 |
return {f"{v['ShortName']} - {v['Locale']} ({v['Gender']})": v['ShortName'] for v in voices}
|
|
|
18 |
# Text-to-speech function
|
19 |
async def text_to_speech(text, voice, rate, pitch):
|
20 |
if not text.strip():
|
|
|
36 |
except Exception as e:
|
37 |
return None, f"An error occurred during text-to-speech conversion: {str(e)}"
|
38 |
return tmp_path, None
|
|
|
39 |
# Gradio interface function
|
40 |
def tts_interface(*args):
|
41 |
loop = asyncio.new_event_loop()
|
|
|
45 |
if warning:
|
46 |
return None, gr.update(value=f"<span style='color:red;'>{warning}</span>", visible=True)
|
47 |
return audio, gr.update(visible=False)
|
|
|
48 |
# Custom CSS
|
49 |
custom_css = """
|
|
|
|
|
50 |
body {
|
51 |
+
background: linear-gradient(45deg, #ff7e5f, #feb47b);
|
52 |
animation: gradient 15s ease infinite;
|
53 |
font-family: 'Arial', sans-serif;
|
54 |
}
|
|
|
59 |
}
|
60 |
.gradio-container {
|
61 |
background-color: rgba(255, 255, 255, 0.1);
|
62 |
+
border-radius: 10px;
|
63 |
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
64 |
+
padding: 20px;
|
|
|
|
|
65 |
}
|
66 |
button {
|
67 |
+
background: linear-gradient(45deg, #ff7e5f, #feb47b);
|
68 |
border: none;
|
69 |
color: white;
|
70 |
+
padding: 10px 20px;
|
71 |
text-align: center;
|
72 |
text-decoration: none;
|
73 |
display: inline-block;
|
74 |
+
font-size: 16px;
|
75 |
+
margin: 4px 2px;
|
76 |
cursor: pointer;
|
77 |
+
border-radius: 5px;
|
78 |
+
transition: background 0.3s;
|
79 |
}
|
80 |
button:hover {
|
81 |
+
background: linear-gradient(45deg, #feb47b, #ff7e5f);
|
|
|
82 |
}
|
83 |
textarea, select, input[type="range"] {
|
84 |
background-color: rgba(255, 255, 255, 0.2);
|
85 |
border: 1px solid rgba(255, 255, 255, 0.3);
|
86 |
color: white;
|
87 |
+
padding: 10px;
|
88 |
+
border-radius: 5px;
|
89 |
+
transition: background 0.3s;
|
|
|
|
|
90 |
}
|
91 |
textarea:focus, select:focus, input[type="range"]:focus {
|
92 |
background-color: rgba(255, 255, 255, 0.3);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
}
|
94 |
.warning {
|
95 |
color: red;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
"""
|
|
|
98 |
# Create Gradio application
|
99 |
async def create_demo():
|
100 |
voices = await get_voices()
|
|
|
124 |
css=custom_css
|
125 |
)
|
126 |
return demo
|
|
|
127 |
# Run the application
|
128 |
if __name__ == "__main__":
|
129 |
demo = asyncio.run(create_demo())
|