hamza2923 commited on
Commit
9afca09
·
verified ·
1 Parent(s): a6b7fd9

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +474 -0
app.py ADDED
@@ -0,0 +1,474 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify, send_file, Response
2
+ import edge_tts
3
+ import asyncio
4
+ import io
5
+ from typing import Dict
6
+
7
+ app = Flask(__name__)
8
+
9
+ # List of voices (same as in your original code)
10
+ VOICES: Dict[str, str] = {
11
+ # Afrikaans
12
+ "Willem (Male, ZA)": "af-ZA-WillemNeural",
13
+ "Adri (Female, ZA)": "af-ZA-AdriNeural",
14
+ # Amharic
15
+ "Ameha (Male, ET)": "am-ET-AmehaNeural",
16
+ "Mekdes (Female, ET)": "am-ET-MekdesNeural",
17
+ # Arabic
18
+ "Hamdan (Male, AE)": "ar-AE-HamdanNeural",
19
+ "Ali (Male, BH)": "ar-BH-AliNeural",
20
+ "Ismael (Male, DZ)": "ar-DZ-IsmaelNeural",
21
+ "Shakir (Male, EG)": "ar-EG-ShakirNeural",
22
+ "Bassel (Male, IQ)": "ar-IQ-BasselNeural",
23
+ "Taim (Male, JO)": "ar-JO-TaimNeural",
24
+ "Fahed (Male, KW)": "ar-KW-FahedNeural",
25
+ "Rami (Male, LB)": "ar-LB-RamiNeural",
26
+ "Omar (Male, LY)": "ar-LY-OmarNeural",
27
+ "Jamal (Male, MA)": "ar-MA-JamalNeural",
28
+ "Abdullah (Male, OM)": "ar-OM-AbdullahNeural",
29
+ "Moaz (Male, QA)": "ar-QA-MoazNeural",
30
+ "Hamed (Male, SA)": "ar-SA-HamedNeural",
31
+ "Laith (Male, SY)": "ar-SY-LaithNeural",
32
+ "Hedi (Male, TN)": "ar-TN-HediNeural",
33
+ "Saleh (Male, YE)": "ar-YE-SalehNeural",
34
+ "Fatima (Female, AE)": "ar-AE-FatimaNeural",
35
+ "Laila (Female, BH)": "ar-BH-LailaNeural",
36
+ "Amina (Female, DZ)": "ar-DZ-AminaNeural",
37
+ "Salma (Female, EG)": "ar-EG-SalmaNeural",
38
+ "Rana (Female, IQ)": "ar-IQ-RanaNeural",
39
+ "Sana (Female, JO)": "ar-JO-SanaNeural",
40
+ "Noura (Female, KW)": "ar-KW-NouraNeural",
41
+ "Layla (Female, LB)": "ar-LB-LaylaNeural",
42
+ "Iman (Female, LY)": "ar-LY-ImanNeural",
43
+ "Mouna (Female, MA)": "ar-MA-MounaNeural",
44
+ "Aysha (Female, OM)": "ar-OM-AyshaNeural",
45
+ "Amal (Female, QA)": "ar-QA-AmalNeural",
46
+ "Zariyah (Female, SA)": "ar-SA-ZariyahNeural",
47
+ "Amany (Female, SY)": "ar-SY-AmanyNeural",
48
+ "Reem (Female, TN)": "ar-TN-ReemNeural",
49
+ "Maryam (Female, YE)": "ar-YE-MaryamNeural",
50
+ # Azerbaijani
51
+ "Babek (Male, AZ)": "az-AZ-BabekNeural",
52
+ "Banu (Female, AZ)": "az-AZ-BanuNeural",
53
+ # Bulgarian
54
+ "Borislav (Male, BG)": "bg-BG-BorislavNeural",
55
+ "Kalina (Female, BG)": "bg-BG-KalinaNeural",
56
+ # Bengali
57
+ "Pradeep (Male, BD)": "bn-BD-PradeepNeural",
58
+ "Bashkar (Male, IN)": "bn-IN-BashkarNeural",
59
+ "Nabanita (Female, BD)": "bn-BD-NabanitaNeural",
60
+ "Tanishaa (Female, IN)": "bn-IN-TanishaaNeural",
61
+ # Bosnian
62
+ "Goran (Male, BA)": "bs-BA-GoranNeural",
63
+ "Vesna (Female, BA)": "bs-BA-VesnaNeural",
64
+ # Catalan
65
+ "Enric (Male, ES)": "ca-ES-EnricNeural",
66
+ "Joana (Female, ES)": "ca-ES-JoanaNeural",
67
+ # Czech
68
+ "Antonin (Male, CZ)": "cs-CZ-AntoninNeural",
69
+ "Vlasta (Female, CZ)": "cs-CZ-VlastaNeural",
70
+ # Welsh
71
+ "Aled (Male, GB)": "cy-GB-AledNeural",
72
+ "Nia (Female, GB)": "cy-GB-NiaNeural",
73
+ # Danish
74
+ "Jeppe (Male, DK)": "da-DK-JeppeNeural",
75
+ "Christel (Female, DK)": "da-DK-ChristelNeural",
76
+ # German
77
+ "Jonas (Male, AT)": "de-AT-JonasNeural",
78
+ "Jan (Male, CH)": "de-CH-JanNeural",
79
+ "Conrad (Male, DE)": "de-DE-ConradNeural",
80
+ "Florian (Male, DE)": "de-DE-FlorianMultilingualNeural",
81
+ "Killian (Male, DE)": "de-DE-KillianNeural",
82
+ "Ingrid (Female, AT)": "de-AT-IngridNeural",
83
+ "Leni (Female, CH)": "de-CH-LeniNeural",
84
+ "Amala (Female, DE)": "de-DE-AmalaNeural",
85
+ "Katja (Female, DE)": "de-DE-KatjaNeural",
86
+ "Seraphina (Female, DE)": "de-DE-SeraphinaMultilingualNeural",
87
+ # Modern Greek
88
+ "Nestoras (Male, GR)": "el-GR-NestorasNeural",
89
+ "Athina (Female, GR)": "el-GR-AthinaNeural",
90
+ # English
91
+ "William (Male, AU)": "en-AU-WilliamNeural",
92
+ "Liam (Male, CA)": "en-CA-LiamNeural",
93
+ "Ryan (Male, GB)": "en-GB-RyanNeural",
94
+ "Thomas (Male, GB)": "en-GB-ThomasNeural",
95
+ "Sam (Male, HK)": "en-HK-SamNeural",
96
+ "Connor (Male, IE)": "en-IE-ConnorNeural",
97
+ "Prabhat (Male, IN)": "en-IN-PrabhatNeural",
98
+ "Chilemba (Male, KE)": "en-KE-ChilembaNeural",
99
+ "Abeo (Male, NG)": "en-NG-AbeoNeural",
100
+ "Mitchell (Male, NZ)": "en-NZ-MitchellNeural",
101
+ "James (Male, PH)": "en-PH-JamesNeural",
102
+ "Wayne (Male, SG)": "en-SG-WayneNeural",
103
+ "Elimu (Male, TZ)": "en-TZ-ElimuNeural",
104
+ "Andrew (Male, US)": "en-US-AndrewNeural",
105
+ "Andrew Multilingual (Male, US)": "en-US-AndrewMultilingualNeural",
106
+ "Brian (Male, US)": "en-US-BrianNeural",
107
+ "Brian Multilingual (Male, US)": "en-US-BrianMultilingualNeural",
108
+ "Christopher (Male, US)": "en-US-ChristopherNeural",
109
+ "Eric (Male, US)": "en-US-EricNeural",
110
+ "Guy (Male, US)": "en-US-GuyNeural",
111
+ "Roger (Male, US)": "en-US-RogerNeural",
112
+ "Steffan (Male, US)": "en-US-SteffanNeural",
113
+ "Luke (Male, ZA)": "en-ZA-LukeNeural",
114
+ "Natasha (Female, AU)": "en-AU-NatashaNeural",
115
+ "Clara (Female, CA)": "en-CA-ClaraNeural",
116
+ "Libby (Female, GB)": "en-GB-LibbyNeural",
117
+ "Maisie (Female, GB)": "en-GB-MaisieNeural",
118
+ "Sonia (Female, GB)": "en-GB-SoniaNeural",
119
+ "Yan (Female, HK)": "en-HK-YanNeural",
120
+ "Emily (Female, IE)": "en-IE-EmilyNeural",
121
+ "Neerja (Female, IN)": "en-IN-NeerjaNeural",
122
+ "Neerja Expressive (Female, IN)": "en-IN-NeerjaExpressiveNeural",
123
+ "Asilia (Female, KE)": "en-KE-AsiliaNeural",
124
+ "Ezinne (Female, NG)": "en-NG-EzinneNeural",
125
+ "Molly (Female, NZ)": "en-NZ-MollyNeural",
126
+ "Rosa (Female, PH)": "en-PH-RosaNeural",
127
+ "Luna (Female, SG)": "en-SG-LunaNeural",
128
+ "Imani (Female, TZ)": "en-TZ-ImaniNeural",
129
+ "Ana (Female, US)": "en-US-AnaNeural",
130
+ "Aria (Female, US)": "en-US-AriaNeural",
131
+ "Ava (Female, US)": "en-US-AvaNeural",
132
+ "Ava Multilingual (Female, US)": "en-US-AvaMultilingualNeural",
133
+ "Emma (Female, US)": "en-US-EmmaNeural",
134
+ "Emma Multilingual (Female, US)": "en-US-EmmaMultilingualNeural",
135
+ "Jenny (Female, US)": "en-US-JennyNeural",
136
+ "Michelle (Female, US)": "en-US-MichelleNeural",
137
+ "Leah (Female, ZA)": "en-ZA-LeahNeural",
138
+ # Spanish
139
+ "Tomas (Male, AR)": "es-AR-TomasNeural",
140
+ "Marcelo (Male, BO)": "es-BO-MarceloNeural",
141
+ "Lorenzo (Male, CL)": "es-CL-LorenzoNeural",
142
+ "Gonzalo (Male, CO)": "es-CO-GonzaloNeural",
143
+ "Juan (Male, CR)": "es-CR-JuanNeural",
144
+ "Manuel (Male, CU)": "es-CU-ManuelNeural",
145
+ "Emilio (Male, DO)": "es-DO-EmilioNeural",
146
+ "Luis (Male, EC)": "es-EC-LuisNeural",
147
+ "Alvaro (Male, ES)": "es-ES-AlvaroNeural",
148
+ "Javier (Male, GQ)": "es-GQ-JavierNeural",
149
+ "Andres (Male, GT)": "es-GT-AndresNeural",
150
+ "Carlos (Male, HN)": "es-HN-CarlosNeural",
151
+ "Jorge (Male, MX)": "es-MX-JorgeNeural",
152
+ "Federico (Male, NI)": "es-NI-FedericoNeural",
153
+ "Roberto (Male, PA)": "es-PA-RobertoNeural",
154
+ "Alex (Male, PE)": "es-PE-AlexNeural",
155
+ "Victor (Male, PR)": "es-PR-VictorNeural",
156
+ "Mario (Male, PY)": "es-PY-MarioNeural",
157
+ "Rodrigo (Male, SV)": "es-SV-RodrigoNeural",
158
+ "Alonso (Male, US)": "es-US-AlonsoNeural",
159
+ "Mateo (Male, UY)": "es-UY-MateoNeural",
160
+ "Sebastian (Male, VE)": "es-VE-SebastianNeural",
161
+ "Elena (Female, AR)": "es-AR-ElenaNeural",
162
+ "Sofia (Female, BO)": "es-BO-SofiaNeural",
163
+ "Catalina (Female, CL)": "es-CL-CatalinaNeural",
164
+ "Salome (Female, CO)": "es-CO-SalomeNeural",
165
+ "Maria (Female, CR)": "es-CR-MariaNeural",
166
+ "Belkys (Female, CU)": "es-CU-BelkysNeural",
167
+ "Ramona (Female, DO)": "es-DO-RamonaNeural",
168
+ "Andrea (Female, EC)": "es-EC-AndreaNeural",
169
+ "Elvira (Female, ES)": "es-ES-ElviraNeural",
170
+ "Ximena (Female, ES)": "es-ES-XimenaNeural",
171
+ "Teresa (Female, GQ)": "es-GQ-TeresaNeural",
172
+ "Marta (Female, GT)": "es-GT-MartaNeural",
173
+ "Karla (Female, HN)": "es-HN-KarlaNeural",
174
+ "Dalia (Female, MX)": "es-MX-DaliaNeural",
175
+ "Yolanda (Female, NI)": "es-NI-YolandaNeural",
176
+ "Margarita (Female, PA)": "es-PA-MargaritaNeural",
177
+ "Camila (Female, PE)": "es-PE-CamilaNeural",
178
+ "Karina (Female, PR)": "es-PR-KarinaNeural",
179
+ "Tania (Female, PY)": "es-PY-TaniaNeural",
180
+ "Lorena (Female, SV)": "es-SV-LorenaNeural",
181
+ "Paloma (Female, US)": "es-US-PalomaNeural",
182
+ "Valentina (Female, UY)": "es-UY-ValentinaNeural",
183
+ "Paola (Female, VE)": "es-VE-PaolaNeural",
184
+ # Estonian
185
+ "Kert (Male, EE)": "et-EE-KertNeural",
186
+ "Anu (Female, EE)": "et-EE-AnuNeural",
187
+ # Persian
188
+ "Farid (Male, IR)": "fa-IR-FaridNeural",
189
+ "Dilara (Female, IR)": "fa-IR-DilaraNeural",
190
+ # Finnish
191
+ "Harri (Male, FI)": "fi-FI-HarriNeural",
192
+ "Noora (Female, FI)": "fi-FI-NooraNeural",
193
+ # Filipino
194
+ "Angelo (Male, PH)": "fil-PH-AngeloNeural",
195
+ "Blessica (Female, PH)": "fil-PH-BlessicaNeural",
196
+ # French
197
+ "Gerard (Male, BE)": "fr-BE-GerardNeural",
198
+ "Antoine (Male, CA)": "fr-CA-AntoineNeural",
199
+ "Jean (Male, CA)": "fr-CA-JeanNeural",
200
+ "Thierry (Male, CA)": "fr-CA-ThierryNeural",
201
+ "Fabrice (Male, CH)": "fr-CH-FabriceNeural",
202
+ "Henri (Male, FR)": "fr-FR-HenriNeural",
203
+ "Remy (Male, FR)": "fr-FR-RemyMultilingualNeural",
204
+ "Charline (Female, BE)": "fr-BE-CharlineNeural",
205
+ "Sylvie (Female, CA)": "fr-CA-SylvieNeural",
206
+ "Ariane (Female, CH)": "fr-CH-ArianeNeural",
207
+ "Denise (Female, FR)": "fr-FR-DeniseNeural",
208
+ "Eloise (Female, FR)": "fr-FR-EloiseNeural",
209
+ "Vivienne (Female, FR)": "fr-FR-VivienneMultilingualNeural",
210
+ # Irish
211
+ "Colm (Male, IE)": "ga-IE-ColmNeural",
212
+ "Orla (Female, IE)": "ga-IE-OrlaNeural",
213
+ # Galician
214
+ "Roi (Male, ES)": "gl-ES-RoiNeural",
215
+ "Sabela (Female, ES)": "gl-ES-SabelaNeural",
216
+ # Gujarati
217
+ "Niranjan (Male, IN)": "gu-IN-NiranjanNeural",
218
+ "Dhwani (Female, IN)": "gu-IN-DhwaniNeural",
219
+ # Hebrew
220
+ "Avri (Male, IL)": "he-IL-AvriNeural",
221
+ "Hila (Female, IL)": "he-IL-HilaNeural",
222
+ # Hindi
223
+ "Madhur (Male, IN)": "hi-IN-MadhurNeural",
224
+ "Swara (Female, IN)": "hi-IN-SwaraNeural",
225
+ # Croatian
226
+ "Srecko (Male, HR)": "hr-HR-SreckoNeural",
227
+ "Gabrijela (Female, HR)": "hr-HR-GabrijelaNeural",
228
+ # Hungarian
229
+ "Tamas (Male, HU)": "hu-HU-TamasNeural",
230
+ "Noemi (Female, HU)": "hu-HU-NoemiNeural",
231
+ # Indonesian
232
+ "Ardi (Male, ID)": "id-ID-ArdiNeural",
233
+ "Gadis (Female, ID)": "id-ID-GadisNeural",
234
+ # Icelandic
235
+ "Gunnar (Male, IS)": "is-IS-GunnarNeural",
236
+ "Gudrun (Female, IS)": "is-IS-GudrunNeural",
237
+ # Italian
238
+ "Diego (Male, IT)": "it-IT-DiegoNeural",
239
+ "Giuseppe (Male, IT)": "it-IT-GiuseppeMult RichterNeural",
240
+ "Elsa (Female, IT)": "it-IT-ElsaNeural",
241
+ "Isabella (Female, IT)": "it-IT-IsabellaNeural",
242
+ # Inuktitut
243
+ "Taqqiq Cans (Male, CA)": "iu-Cans-CA-TaqqiqNeural",
244
+ "Taqqiq Latn (Male, CA)": "iu-Latn-CA-TaqqiqNeural",
245
+ "Siqiniq Cans (Female, CA)": "iu-Cans-CA-SiqiniqNeural",
246
+ "Siqiniq Latn (Female, CA)": "iu-Latn-CA-SiqiniqNeural",
247
+ # Japanese
248
+ "Keita (Male, JP)": "ja-JP-KeitaNeural",
249
+ "Nanami (Female, JP)": "ja-JP-NanamiNeural",
250
+ # Javanese
251
+ "Dimas (Male, ID)": "jv-ID-DimasNeural",
252
+ "Siti (Female, ID)": "jv-ID-SitiNeural",
253
+ # Georgian
254
+ "Giorgi (Male, GE)": "ka-GE-GiorgiNeural",
255
+ "Eka (Female, GE)": "ka-GE-EkaNeural",
256
+ # Kazakh
257
+ "Daulet (Male, KZ)": "kk-KZ-DauletNeural",
258
+ "Aigul (Female, KZ)": "kk-KZ-AigulNeural",
259
+ # Khmer
260
+ "Piseth (Male, KH)": "km-KH-PisethNeural",
261
+ "Sreymom (Female, KH)": "km-KH-SreymomNeural",
262
+ # Kannada
263
+ "Gagan (Male, IN)": "kn-IN-GaganNeural",
264
+ "Sapna (Female, IN)": "kn-IN-SapnaNeural",
265
+ # Korean
266
+ "Hyunsu (Male, KR)": "ko-KR-HyunsuMultilingualNeural",
267
+ "InJoon (Male, KR)": "ko-KR-InJoonNeural",
268
+ "SunHi (Female, KR)": "ko-KR-SunHiNeural",
269
+ # Lao
270
+ "Chanthavong (Male, LA)": "lo-LA-ChanthavongNeural",
271
+ "Keomany (Female, LA)": "lo-LA-KeomanyNeural",
272
+ # Lithuanian
273
+ "Leonas (Male, LT)": "lt-LT-LeonasNeural",
274
+ "Ona (Female, LT)": "lt-LT-OnaNeural",
275
+ # Latvian
276
+ "Nils (Male, LV)": "lv-LV-NilsNeural",
277
+ "Everita (Female, LV)": "lv-LV-EveritaNeural",
278
+ # Macedonian
279
+ "Aleksandar (Male, MK)": "mk-MK-AleksandarNeural",
280
+ "Marija (Female, MK)": "mk-MK-MarijaNeural",
281
+ # Malayalam
282
+ "Midhun (Male, IN)": "ml-IN-MidhunNeural",
283
+ "Sobhana (Female, IN)": "ml-IN-SobhanaNeural",
284
+ # Mongolian
285
+ "Bataa (Male, MN)": "mn-MN-BataaNeural",
286
+ "Yesui (Female, MN)": "mn-MN-YesuiNeural",
287
+ # Marathi
288
+ "Manohar (Male, IN)": "mr-IN-ManoharNeural",
289
+ "Aarohi (Female, IN)": "mr-IN-AarohiNeural",
290
+ # Malay
291
+ "Osman (Male, MY)": "ms-MY-OsmanNeural",
292
+ "Yasmin (Female, MY)": "ms-MY-YasminNeural",
293
+ # Maltese
294
+ "Joseph (Male, MT)": "mt-MT-JosephNeural",
295
+ "Grace (Female, MT)": "mt-MT-GraceNeural",
296
+ # Burmese
297
+ "Thiha (Male, MM)": "my-MM-ThihaNeural",
298
+ "Nilar (Female, MM)": "my-MM-NilarNeural",
299
+ # Norwegian Bokmål
300
+ "Finn (Male, NO)": "nb-NO-FinnNeural",
301
+ "Pernille (Female, NO)": "nb-NO-PernilleNeural",
302
+ # Nepali
303
+ "Sagar (Male, NP)": "ne-NP-SagarNeural",
304
+ "Hemkala (Female, NP)": "ne-NP-HemkalaNeural",
305
+ # Dutch
306
+ "Arnaud (Male, BE)": "nl-BE-ArnaudNeural",
307
+ "Maarten (Male, NL)": "nl-NL-MaartenNeural",
308
+ "Dena (Female, BE)": "nl-BE-DenaNeural",
309
+ "Colette (Female, NL)": "nl-NL-ColetteNeural",
310
+ "Fenna (Female, NL)": "nl-NL-FennaNeural",
311
+ # Polish
312
+ "Marek (Male, PL)": "pl-PL-MarekNeural",
313
+ "Zofia (Female, PL)": "pl-PL-ZofiaNeural",
314
+ # Pushto
315
+ "GulNawaz (Male, AF)": "ps-AF-GulNawazNeural",
316
+ "Latifa (Female, AF)": "ps-AF-LatifaNeural",
317
+ # Portuguese
318
+ "Antonio (Male, BR)": "pt-BR-AntonioNeural",
319
+ "Duarte (Male, PT)": "pt-PT-DuarteNeural",
320
+ "Francisca (Female, BR)": "pt-BR-FranciscaNeural",
321
+ "Thalita (Female, BR)": "pt-BR-ThalitaMultilingualNeural",
322
+ "Raquel (Female, PT)": "pt-PT-RaquelNeural",
323
+ # Romanian
324
+ "Emil (Male, RO)": "ro-RO-EmilNeural",
325
+ "Alina (Female, RO)": "ro-RO-AlinaNeural",
326
+ # Russian
327
+ "Dmitry (Male, RU)": "ru-RU-DmitryNeural",
328
+ "Svetlana (Female, RU)": "ru-RU-SvetlanaNeural",
329
+ # Sinhala
330
+ "Sameera (Male, LK)": "si-LK-SameeraNeural",
331
+ "Thilini (Female, LK)": "si-LK-ThiliniNeural",
332
+ # Slovak
333
+ "Lukas (Male, SK)": "sk-SK-LukasNeural",
334
+ "Viktoria (Female, SK)": "sk-SK-ViktoriaNeural",
335
+ # Slovenian
336
+ "Rok (Male, SI)": "sl-SI-RokNeural",
337
+ "Petra (Female, SI)": "sl-SI-PetraNeural",
338
+ # Somali
339
+ "Muuse (Male, SO)": "so-SO-MuuseNeural",
340
+ "Ubax (Female, SO)": "so-SO-UbaxNeural",
341
+ # Albanian
342
+ "Ilir (Male, AL)": "sq-AL-IlirNeural",
343
+ "Anila (Female, AL)": "sq-AL-AnilaNeural",
344
+ # Serbian
345
+ "Nicholas (Male, RS)": "sr-RS-NicholasNeural",
346
+ "Sophie (Female, RS)": "sr-RS-SophieNeural",
347
+ # Sundanese
348
+ "Jajang (Male, ID)": "su-ID-JajangNeural",
349
+ "Tuti (Female, ID)": "su-ID-TutiNeural",
350
+ # Swedish
351
+ "Mattias (Male, SE)": "sv-SE-MattiasNeural",
352
+ "Sofie (Female, SE)": "sv-SE-SofieNeural",
353
+ # Swahili
354
+ "Rafiki (Male, KE)": "sw-KE-RafikiNeural",
355
+ "Daudi (Male, TZ)": "sw-TZ-DaudiNeural",
356
+ "Zuri (Female, KE)": "sw-KE-ZuriNeural",
357
+ "Rehema (Female, TZ)": "sw-TZ-RehemaNeural",
358
+ # Tamil
359
+ "Valluvar (Male, IN)": "ta-IN-ValluvarNeural",
360
+ "Kumar (Male, LK)": "ta-LK-KumarNeural",
361
+ "Surya (Male, MY)": "ta-MY-SuryaNeural",
362
+ "Anbu (Male, SG)": "ta-SG-AnbuNeural",
363
+ "Pallavi (Female, IN)": "ta-IN-PallaviNeural",
364
+ "Saranya (Female, LK)": "ta-LK-SaranyaNeural",
365
+ "Kani (Female, MY)": "ta-MY-KaniNeural",
366
+ "Venba (Female, SG)": "ta-SG-VenbaNeural",
367
+ # Telugu
368
+ "Mohan (Male, IN)": "te-IN-MohanNeural",
369
+ "Shruti (Female, IN)": "te-IN-ShrutiNeural",
370
+ # Thai
371
+ "Niwat (Male, TH)": "th-TH-NiwatNeural",
372
+ "Premwadee (Female, TH)": "th-TH-PremwadeeNeural",
373
+ # Turkish
374
+ "Ahmet (Male, TR)": "tr-TR-AhmetNeural",
375
+ "Emel (Female, TR)": "tr-TR-EmelNeural",
376
+ # Ukrainian
377
+ "Ostap (Male, UA)": "uk-UA-OstapNeural",
378
+ "Polina (Female, UA)": "uk-UA-PolinaNeural",
379
+ # Urdu
380
+ "Salman (Male, IN)": "ur-IN-SalmanNeural",
381
+ "Asad (Male, PK)": "ur-PK-AsadNeural",
382
+ "Gul (Female, IN)": "ur-IN-GulNeural",
383
+ "Uzma (Female, PK)": "ur-PK-UzmaNeural",
384
+ # Uzbek
385
+ "Sardor (Male, UZ)": "uz-UZ-SardorNeural",
386
+ "Madina (Female, UZ)": "uz-UZ-MadinaNeural",
387
+ # Vietnamese
388
+ "NamMinh (Male, VN)": "vi-VN-NamMinhNeural",
389
+ "HoaiMy (Female, VN)": "vi-VN-HoaiMyNeural",
390
+ # Chinese
391
+ "Yunjian (Male, CN)": "zh-CN-YunjianNeural",
392
+ "Yunxi (Male, CN)": "zh-CN-YunxiNeural",
393
+ "Yunxia (Male, CN)": "zh-CN-YunxiaNeural",
394
+ "Yunyang (Male, CN)": "zh-CN-YunyangNeural",
395
+ "WanLung (Male, HK)": "zh-HK-WanLungNeural",
396
+ "YunJhe (Male, TW)": "zh-TW-YunJheNeural",
397
+ "Xiaoxiao (Female, CN)": "zh-CN-XiaoxiaoNeural",
398
+ "Xiaoyi (Female, CN)": "zh-CN-XiaoyiNeural",
399
+ "Xiaobei (Female, Liaoning, CN)": "zh-CN-liaoning-XiaobeiNeural",
400
+ "Xiaoni (Female, Shaanxi, CN)": "zh-CN-shaanxi-XiaoniNeural",
401
+ "HiuGaai (Female, HK)": "zh-HK-HiuGaaiNeural",
402
+ "HiuMaan (Female, HK)": "zh-HK-HiuMaanNeural",
403
+ "HsiaoChen (Female, TW)": "zh-TW-HsiaoChenNeural",
404
+ "HsiaoYu (Female, TW)": "zh-TW-HsiaoYuNeural",
405
+ # Zulu
406
+ "Themba (Male, ZA)": "zu-ZA-ThembaNeural",
407
+ "Thando (Female, ZA)": "zu-ZA-ThandoNeural",
408
+ }
409
+
410
+ async def generate_speech_bytes(text: str, voice: str) -> bytes:
411
+ """Generate speech from text and return as bytes"""
412
+ try:
413
+ communicate = edge_tts.Communicate(text, voice)
414
+ output = io.BytesIO()
415
+ await communicate.save(output)
416
+ return output.getvalue()
417
+ except Exception as e:
418
+ print(f"Error: {e}")
419
+ return None
420
+
421
+ @app.route('/api/tts/file', methods=['POST'])
422
+ def text_to_speech_file():
423
+ """Endpoint that returns an audio file"""
424
+ data = request.get_json()
425
+ text = data.get('text', '')
426
+ voice_name = data.get('voice', 'Jenny (Female, US)')
427
+
428
+ if not text:
429
+ return jsonify({"error": "Text is required"}), 400
430
+
431
+ voice = VOICES.get(voice_name, VOICES["Jenny (Female, US)"])
432
+ audio_bytes = asyncio.run(generate_speech_bytes(text, voice))
433
+
434
+ if not audio_bytes:
435
+ return jsonify({"error": "Failed to generate speech"}), 500
436
+
437
+ return send_file(
438
+ io.BytesIO(audio_bytes),
439
+ mimetype='audio/mpeg',
440
+ as_attachment=True,
441
+ download_name='speech.mp3'
442
+ )
443
+
444
+ @app.route('/api/tts/stream', methods=['POST'])
445
+ def text_to_speech_stream():
446
+ """Endpoint that returns audio as a byte stream"""
447
+ data = request.get_json()
448
+ text = data.get('text', '')
449
+ voice_name = data.get('voice', 'Jenny (Female, US)')
450
+
451
+ if not text:
452
+ return jsonify({"error": "Text is required"}), 400
453
+
454
+ voice = VOICES.get(voice_name, VOICES["Jenny (Female, US)"])
455
+ audio_bytes = asyncio.run(generate_speech_bytes(text, voice))
456
+
457
+ if not audio_bytes:
458
+ return jsonify({"error": "Failed to generate speech"}), 500
459
+
460
+ return Response(
461
+ io.BytesIO(audio_bytes),
462
+ mimetype='audio/mpeg'
463
+ )
464
+
465
+ @app.route('/api/voices', methods=['GET'])
466
+ def get_voices():
467
+ """Endpoint to get available voices"""
468
+ return jsonify({
469
+ "voices": list(VOICES.keys()),
470
+ "default": "Jenny (Female, US)"
471
+ })
472
+
473
+ if __name__ == '__main__':
474
+ app.run(host='0.0.0.0', port=7860)