import gradio as gr import edge_tts import asyncio from typing import Dict async def generate_speech(text: str, voice: str) -> str: """Generate speech from text using the specified voice""" try: communicate = edge_tts.Communicate(text, voice) output_file = "output.mp3" await communicate.save(output_file) return output_file except Exception as e: print(f"Error: {e}") return None # List of voices VOICES: Dict[str, str] = { # Afrikaans "Willem (Male, ZA)": "af-ZA-WillemNeural", "Adri (Female, ZA)": "af-ZA-AdriNeural", # Amharic "Ameha (Male, ET)": "am-ET-AmehaNeural", "Mekdes (Female, ET)": "am-ET-MekdesNeural", # Arabic "Hamdan (Male, AE)": "ar-AE-HamdanNeural", "Ali (Male, BH)": "ar-BH-AliNeural", "Ismael (Male, DZ)": "ar-DZ-IsmaelNeural", "Shakir (Male, EG)": "ar-EG-ShakirNeural", "Bassel (Male, IQ)": "ar-IQ-BasselNeural", "Taim (Male, JO)": "ar-JO-TaimNeural", "Fahed (Male, KW)": "ar-KW-FahedNeural", "Rami (Male, LB)": "ar-LB-RamiNeural", "Omar (Male, LY)": "ar-LY-OmarNeural", "Jamal (Male, MA)": "ar-MA-JamalNeural", "Abdullah (Male, OM)": "ar-OM-AbdullahNeural", "Moaz (Male, QA)": "ar-QA-MoazNeural", "Hamed (Male, SA)": "ar-SA-HamedNeural", "Laith (Male, SY)": "ar-SY-LaithNeural", "Hedi (Male, TN)": "ar-TN-HediNeural", "Saleh (Male, YE)": "ar-YE-SalehNeural", "Fatima (Female, AE)": "ar-AE-FatimaNeural", "Laila (Female, BH)": "ar-BH-LailaNeural", "Amina (Female, DZ)": "ar-DZ-AminaNeural", "Salma (Female, EG)": "ar-EG-SalmaNeural", "Rana (Female, IQ)": "ar-IQ-RanaNeural", "Sana (Female, JO)": "ar-JO-SanaNeural", "Noura (Female, KW)": "ar-KW-NouraNeural", "Layla (Female, LB)": "ar-LB-LaylaNeural", "Iman (Female, LY)": "ar-LY-ImanNeural", "Mouna (Female, MA)": "ar-MA-MounaNeural", "Aysha (Female, OM)": "ar-OM-AyshaNeural", "Amal (Female, QA)": "ar-QA-AmalNeural", "Zariyah (Female, SA)": "ar-SA-ZariyahNeural", "Amany (Female, SY)": "ar-SY-AmanyNeural", "Reem (Female, TN)": "ar-TN-ReemNeural", "Maryam (Female, YE)": "ar-YE-MaryamNeural", # Azerbaijani "Babek (Male, AZ)": "az-AZ-BabekNeural", "Banu (Female, AZ)": "az-AZ-BanuNeural", # Bulgarian "Borislav (Male, BG)": "bg-BG-BorislavNeural", "Kalina (Female, BG)": "bg-BG-KalinaNeural", # Bengali "Pradeep (Male, BD)": "bn-BD-PradeepNeural", "Bashkar (Male, IN)": "bn-IN-BashkarNeural", "Nabanita (Female, BD)": "bn-BD-NabanitaNeural", "Tanishaa (Female, IN)": "bn-IN-TanishaaNeural", # Bosnian "Goran (Male, BA)": "bs-BA-GoranNeural", "Vesna (Female, BA)": "bs-BA-VesnaNeural", # Catalan "Enric (Male, ES)": "ca-ES-EnricNeural", "Joana (Female, ES)": "ca-ES-JoanaNeural", # Czech "Antonin (Male, CZ)": "cs-CZ-AntoninNeural", "Vlasta (Female, CZ)": "cs-CZ-VlastaNeural", # Welsh "Aled (Male, GB)": "cy-GB-AledNeural", "Nia (Female, GB)": "cy-GB-NiaNeural", # Danish "Jeppe (Male, DK)": "da-DK-JeppeNeural", "Christel (Female, DK)": "da-DK-ChristelNeural", # German "Jonas (Male, AT)": "de-AT-JonasNeural", "Jan (Male, CH)": "de-CH-JanNeural", "Conrad (Male, DE)": "de-DE-ConradNeural", "Florian (Male, DE)": "de-DE-FlorianMultilingualNeural", "Killian (Male, DE)": "de-DE-KillianNeural", "Ingrid (Female, AT)": "de-AT-IngridNeural", "Leni (Female, CH)": "de-CH-LeniNeural", "Amala (Female, DE)": "de-DE-AmalaNeural", "Katja (Female, DE)": "de-DE-KatjaNeural", "Seraphina (Female, DE)": "de-DE-SeraphinaMultilingualNeural", # Modern Greek "Nestoras (Male, GR)": "el-GR-NestorasNeural", "Athina (Female, GR)": "el-GR-AthinaNeural", # English "William (Male, AU)": "en-AU-WilliamNeural", "Liam (Male, CA)": "en-CA-LiamNeural", "Ryan (Male, GB)": "en-GB-RyanNeural", "Thomas (Male, GB)": "en-GB-ThomasNeural", "Sam (Male, HK)": "en-HK-SamNeural", "Connor (Male, IE)": "en-IE-ConnorNeural", "Prabhat (Male, IN)": "en-IN-PrabhatNeural", "Chilemba (Male, KE)": "en-KE-ChilembaNeural", "Abeo (Male, NG)": "en-NG-AbeoNeural", "Mitchell (Male, NZ)": "en-NZ-MitchellNeural", "James (Male, PH)": "en-PH-JamesNeural", "Wayne (Male, SG)": "en-SG-WayneNeural", "Elimu (Male, TZ)": "en-TZ-ElimuNeural", "Andrew (Male, US)": "en-US-AndrewNeural", "Andrew Multilingual (Male, US)": "en-US-AndrewMultilingualNeural", "Brian (Male, US)": "en-US-BrianNeural", "Brian Multilingual (Male, US)": "en-US-BrianMultilingualNeural", "Christopher (Male, US)": "en-US-ChristopherNeural", "Eric (Male, US)": "en-US-EricNeural", "Guy (Male, US)": "en-US-GuyNeural", "Roger (Male, US)": "en-US-RogerNeural", "Steffan (Male, US)": "en-US-SteffanNeural", "Luke (Male, ZA)": "en-ZA-LukeNeural", "Natasha (Female, AU)": "en-AU-NatashaNeural", "Clara (Female, CA)": "en-CA-ClaraNeural", "Libby (Female, GB)": "en-GB-LibbyNeural", "Maisie (Female, GB)": "en-GB-MaisieNeural", "Sonia (Female, GB)": "en-GB-SoniaNeural", "Yan (Female, HK)": "en-HK-YanNeural", "Emily (Female, IE)": "en-IE-EmilyNeural", "Neerja (Female, IN)": "en-IN-NeerjaNeural", "Neerja Expressive (Female, IN)": "en-IN-NeerjaExpressiveNeural", "Asilia (Female, KE)": "en-KE-AsiliaNeural", "Ezinne (Female, NG)": "en-NG-EzinneNeural", "Molly (Female, NZ)": "en-NZ-MollyNeural", "Rosa (Female, PH)": "en-PH-RosaNeural", "Luna (Female, SG)": "en-SG-LunaNeural", "Imani (Female, TZ)": "en-TZ-ImaniNeural", "Ana (Female, US)": "en-US-AnaNeural", "Aria (Female, US)": "en-US-AriaNeural", "Ava (Female, US)": "en-US-AvaNeural", "Ava Multilingual (Female, US)": "en-US-AvaMultilingualNeural", "Emma (Female, US)": "en-US-EmmaNeural", "Emma Multilingual (Female, US)": "en-US-EmmaMultilingualNeural", "Jenny (Female, US)": "en-US-JennyNeural", "Michelle (Female, US)": "en-US-MichelleNeural", "Leah (Female, ZA)": "en-ZA-LeahNeural", # Spanish "Tomas (Male, AR)": "es-AR-TomasNeural", "Marcelo (Male, BO)": "es-BO-MarceloNeural", "Lorenzo (Male, CL)": "es-CL-LorenzoNeural", "Gonzalo (Male, CO)": "es-CO-GonzaloNeural", "Juan (Male, CR)": "es-CR-JuanNeural", "Manuel (Male, CU)": "es-CU-ManuelNeural", "Emilio (Male, DO)": "es-DO-EmilioNeural", "Luis (Male, EC)": "es-EC-LuisNeural", "Alvaro (Male, ES)": "es-ES-AlvaroNeural", "Javier (Male, GQ)": "es-GQ-JavierNeural", "Andres (Male, GT)": "es-GT-AndresNeural", "Carlos (Male, HN)": "es-HN-CarlosNeural", "Jorge (Male, MX)": "es-MX-JorgeNeural", "Federico (Male, NI)": "es-NI-FedericoNeural", "Roberto (Male, PA)": "es-PA-RobertoNeural", "Alex (Male, PE)": "es-PE-AlexNeural", "Victor (Male, PR)": "es-PR-VictorNeural", "Mario (Male, PY)": "es-PY-MarioNeural", "Rodrigo (Male, SV)": "es-SV-RodrigoNeural", "Alonso (Male, US)": "es-US-AlonsoNeural", "Mateo (Male, UY)": "es-UY-MateoNeural", "Sebastian (Male, VE)": "es-VE-SebastianNeural", "Elena (Female, AR)": "es-AR-ElenaNeural", "Sofia (Female, BO)": "es-BO-SofiaNeural", "Catalina (Female, CL)": "es-CL-CatalinaNeural", "Salome (Female, CO)": "es-CO-SalomeNeural", "Maria (Female, CR)": "es-CR-MariaNeural", "Belkys (Female, CU)": "es-CU-BelkysNeural", "Ramona (Female, DO)": "es-DO-RamonaNeural", "Andrea (Female, EC)": "es-EC-AndreaNeural", "Elvira (Female, ES)": "es-ES-ElviraNeural", "Ximena (Female, ES)": "es-ES-XimenaNeural", "Teresa (Female, GQ)": "es-GQ-TeresaNeural", "Marta (Female, GT)": "es-GT-MartaNeural", "Karla (Female, HN)": "es-HN-KarlaNeural", "Dalia (Female, MX)": "es-MX-DaliaNeural", "Yolanda (Female, NI)": "es-NI-YolandaNeural", "Margarita (Female, PA)": "es-PA-MargaritaNeural", "Camila (Female, PE)": "es-PE-CamilaNeural", "Karina (Female, PR)": "es-PR-KarinaNeural", "Tania (Female, PY)": "es-PY-TaniaNeural", "Lorena (Female, SV)": "es-SV-LorenaNeural", "Paloma (Female, US)": "es-US-PalomaNeural", "Valentina (Female, UY)": "es-UY-ValentinaNeural", "Paola (Female, VE)": "es-VE-PaolaNeural", # Estonian "Kert (Male, EE)": "et-EE-KertNeural", "Anu (Female, EE)": "et-EE-AnuNeural", # Persian "Farid (Male, IR)": "fa-IR-FaridNeural", "Dilara (Female, IR)": "fa-IR-DilaraNeural", # Finnish "Harri (Male, FI)": "fi-FI-HarriNeural", "Noora (Female, FI)": "fi-FI-NooraNeural", # Filipino "Angelo (Male, PH)": "fil-PH-AngeloNeural", "Blessica (Female, PH)": "fil-PH-BlessicaNeural", # French "Gerard (Male, BE)": "fr-BE-GerardNeural", "Antoine (Male, CA)": "fr-CA-AntoineNeural", "Jean (Male, CA)": "fr-CA-JeanNeural", "Thierry (Male, CA)": "fr-CA-ThierryNeural", "Fabrice (Male, CH)": "fr-CH-FabriceNeural", "Henri (Male, FR)": "fr-FR-HenriNeural", "Remy (Male, FR)": "fr-FR-RemyMultilingualNeural", "Charline (Female, BE)": "fr-BE-CharlineNeural", "Sylvie (Female, CA)": "fr-CA-SylvieNeural", "Ariane (Female, CH)": "fr-CH-ArianeNeural", "Denise (Female, FR)": "fr-FR-DeniseNeural", "Eloise (Female, FR)": "fr-FR-EloiseNeural", "Vivienne (Female, FR)": "fr-FR-VivienneMultilingualNeural", # Irish "Colm (Male, IE)": "ga-IE-ColmNeural", "Orla (Female, IE)": "ga-IE-OrlaNeural", # Galician "Roi (Male, ES)": "gl-ES-RoiNeural", "Sabela (Female, ES)": "gl-ES-SabelaNeural", # Gujarati "Niranjan (Male, IN)": "gu-IN-NiranjanNeural", "Dhwani (Female, IN)": "gu-IN-DhwaniNeural", # Hebrew "Avri (Male, IL)": "he-IL-AvriNeural", "Hila (Female, IL)": "he-IL-HilaNeural", # Hindi "Madhur (Male, IN)": "hi-IN-MadhurNeural", "Swara (Female, IN)": "hi-IN-SwaraNeural", # Croatian "Srecko (Male, HR)": "hr-HR-SreckoNeural", "Gabrijela (Female, HR)": "hr-HR-GabrijelaNeural", # Hungarian "Tamas (Male, HU)": "hu-HU-TamasNeural", "Noemi (Female, HU)": "hu-HU-NoemiNeural", # Indonesian "Ardi (Male, ID)": "id-ID-ArdiNeural", "Gadis (Female, ID)": "id-ID-GadisNeural", # Icelandic "Gunnar (Male, IS)": "is-IS-GunnarNeural", "Gudrun (Female, IS)": "is-IS-GudrunNeural", # Italian "Diego (Male, IT)": "it-IT-DiegoNeural", "Giuseppe (Male, IT)": "it-IT-GiuseppeMult RichterNeural", "Elsa (Female, IT)": "it-IT-ElsaNeural", "Isabella (Female, IT)": "it-IT-IsabellaNeural", # Inuktitut "Taqqiq Cans (Male, CA)": "iu-Cans-CA-TaqqiqNeural", "Taqqiq Latn (Male, CA)": "iu-Latn-CA-TaqqiqNeural", "Siqiniq Cans (Female, CA)": "iu-Cans-CA-SiqiniqNeural", "Siqiniq Latn (Female, CA)": "iu-Latn-CA-SiqiniqNeural", # Japanese "Keita (Male, JP)": "ja-JP-KeitaNeural", "Nanami (Female, JP)": "ja-JP-NanamiNeural", # Javanese "Dimas (Male, ID)": "jv-ID-DimasNeural", "Siti (Female, ID)": "jv-ID-SitiNeural", # Georgian "Giorgi (Male, GE)": "ka-GE-GiorgiNeural", "Eka (Female, GE)": "ka-GE-EkaNeural", # Kazakh "Daulet (Male, KZ)": "kk-KZ-DauletNeural", "Aigul (Female, KZ)": "kk-KZ-AigulNeural", # Khmer "Piseth (Male, KH)": "km-KH-PisethNeural", "Sreymom (Female, KH)": "km-KH-SreymomNeural", # Kannada "Gagan (Male, IN)": "kn-IN-GaganNeural", "Sapna (Female, IN)": "kn-IN-SapnaNeural", # Korean "Hyunsu (Male, KR)": "ko-KR-HyunsuMultilingualNeural", "InJoon (Male, KR)": "ko-KR-InJoonNeural", "SunHi (Female, KR)": "ko-KR-SunHiNeural", # Lao "Chanthavong (Male, LA)": "lo-LA-ChanthavongNeural", "Keomany (Female, LA)": "lo-LA-KeomanyNeural", # Lithuanian "Leonas (Male, LT)": "lt-LT-LeonasNeural", "Ona (Female, LT)": "lt-LT-OnaNeural", # Latvian "Nils (Male, LV)": "lv-LV-NilsNeural", "Everita (Female, LV)": "lv-LV-EveritaNeural", # Macedonian "Aleksandar (Male, MK)": "mk-MK-AleksandarNeural", "Marija (Female, MK)": "mk-MK-MarijaNeural", # Malayalam "Midhun (Male, IN)": "ml-IN-MidhunNeural", "Sobhana (Female, IN)": "ml-IN-SobhanaNeural", # Mongolian "Bataa (Male, MN)": "mn-MN-BataaNeural", "Yesui (Female, MN)": "mn-MN-YesuiNeural", # Marathi "Manohar (Male, IN)": "mr-IN-ManoharNeural", "Aarohi (Female, IN)": "mr-IN-AarohiNeural", # Malay "Osman (Male, MY)": "ms-MY-OsmanNeural", "Yasmin (Female, MY)": "ms-MY-YasminNeural", # Maltese "Joseph (Male, MT)": "mt-MT-JosephNeural", "Grace (Female, MT)": "mt-MT-GraceNeural", # Burmese "Thiha (Male, MM)": "my-MM-ThihaNeural", "Nilar (Female, MM)": "my-MM-NilarNeural", # Norwegian Bokmål "Finn (Male, NO)": "nb-NO-FinnNeural", "Pernille (Female, NO)": "nb-NO-PernilleNeural", # Nepali "Sagar (Male, NP)": "ne-NP-SagarNeural", "Hemkala (Female, NP)": "ne-NP-HemkalaNeural", # Dutch "Arnaud (Male, BE)": "nl-BE-ArnaudNeural", "Maarten (Male, NL)": "nl-NL-MaartenNeural", "Dena (Female, BE)": "nl-BE-DenaNeural", "Colette (Female, NL)": "nl-NL-ColetteNeural", "Fenna (Female, NL)": "nl-NL-FennaNeural", # Polish "Marek (Male, PL)": "pl-PL-MarekNeural", "Zofia (Female, PL)": "pl-PL-ZofiaNeural", # Pushto "GulNawaz (Male, AF)": "ps-AF-GulNawazNeural", "Latifa (Female, AF)": "ps-AF-LatifaNeural", # Portuguese "Antonio (Male, BR)": "pt-BR-AntonioNeural", "Duarte (Male, PT)": "pt-PT-DuarteNeural", "Francisca (Female, BR)": "pt-BR-FranciscaNeural", "Thalita (Female, BR)": "pt-BR-ThalitaMultilingualNeural", "Raquel (Female, PT)": "pt-PT-RaquelNeural", # Romanian "Emil (Male, RO)": "ro-RO-EmilNeural", "Alina (Female, RO)": "ro-RO-AlinaNeural", # Russian "Dmitry (Male, RU)": "ru-RU-DmitryNeural", "Svetlana (Female, RU)": "ru-RU-SvetlanaNeural", # Sinhala "Sameera (Male, LK)": "si-LK-SameeraNeural", "Thilini (Female, LK)": "si-LK-ThiliniNeural", # Slovak "Lukas (Male, SK)": "sk-SK-LukasNeural", "Viktoria (Female, SK)": "sk-SK-ViktoriaNeural", # Slovenian "Rok (Male, SI)": "sl-SI-RokNeural", "Petra (Female, SI)": "sl-SI-PetraNeural", # Somali "Muuse (Male, SO)": "so-SO-MuuseNeural", "Ubax (Female, SO)": "so-SO-UbaxNeural", # Albanian "Ilir (Male, AL)": "sq-AL-IlirNeural", "Anila (Female, AL)": "sq-AL-AnilaNeural", # Serbian "Nicholas (Male, RS)": "sr-RS-NicholasNeural", "Sophie (Female, RS)": "sr-RS-SophieNeural", # Sundanese "Jajang (Male, ID)": "su-ID-JajangNeural", "Tuti (Female, ID)": "su-ID-TutiNeural", # Swedish "Mattias (Male, SE)": "sv-SE-MattiasNeural", "Sofie (Female, SE)": "sv-SE-SofieNeural", # Swahili "Rafiki (Male, KE)": "sw-KE-RafikiNeural", "Daudi (Male, TZ)": "sw-TZ-DaudiNeural", "Zuri (Female, KE)": "sw-KE-ZuriNeural", "Rehema (Female, TZ)": "sw-TZ-RehemaNeural", # Tamil "Valluvar (Male, IN)": "ta-IN-ValluvarNeural", "Kumar (Male, LK)": "ta-LK-KumarNeural", "Surya (Male, MY)": "ta-MY-SuryaNeural", "Anbu (Male, SG)": "ta-SG-AnbuNeural", "Pallavi (Female, IN)": "ta-IN-PallaviNeural", "Saranya (Female, LK)": "ta-LK-SaranyaNeural", "Kani (Female, MY)": "ta-MY-KaniNeural", "Venba (Female, SG)": "ta-SG-VenbaNeural", # Telugu "Mohan (Male, IN)": "te-IN-MohanNeural", "Shruti (Female, IN)": "te-IN-ShrutiNeural", # Thai "Niwat (Male, TH)": "th-TH-NiwatNeural", "Premwadee (Female, TH)": "th-TH-PremwadeeNeural", # Turkish "Ahmet (Male, TR)": "tr-TR-AhmetNeural", "Emel (Female, TR)": "tr-TR-EmelNeural", # Ukrainian "Ostap (Male, UA)": "uk-UA-OstapNeural", "Polina (Female, UA)": "uk-UA-PolinaNeural", # Urdu "Salman (Male, IN)": "ur-IN-SalmanNeural", "Asad (Male, PK)": "ur-PK-AsadNeural", "Gul (Female, IN)": "ur-IN-GulNeural", "Uzma (Female, PK)": "ur-PK-UzmaNeural", # Uzbek "Sardor (Male, UZ)": "uz-UZ-SardorNeural", "Madina (Female, UZ)": "uz-UZ-MadinaNeural", # Vietnamese "NamMinh (Male, VN)": "vi-VN-NamMinhNeural", "HoaiMy (Female, VN)": "vi-VN-HoaiMyNeural", # Chinese "Yunjian (Male, CN)": "zh-CN-YunjianNeural", "Yunxi (Male, CN)": "zh-CN-YunxiNeural", "Yunxia (Male, CN)": "zh-CN-YunxiaNeural", "Yunyang (Male, CN)": "zh-CN-YunyangNeural", "WanLung (Male, HK)": "zh-HK-WanLungNeural", "YunJhe (Male, TW)": "zh-TW-YunJheNeural", "Xiaoxiao (Female, CN)": "zh-CN-XiaoxiaoNeural", "Xiaoyi (Female, CN)": "zh-CN-XiaoyiNeural", "Xiaobei (Female, Liaoning, CN)": "zh-CN-liaoning-XiaobeiNeural", "Xiaoni (Female, Shaanxi, CN)": "zh-CN-shaanxi-XiaoniNeural", "HiuGaai (Female, HK)": "zh-HK-HiuGaaiNeural", "HiuMaan (Female, HK)": "zh-HK-HiuMaanNeural", "HsiaoChen (Female, TW)": "zh-TW-HsiaoChenNeural", "HsiaoYu (Female, TW)": "zh-TW-HsiaoYuNeural", # Zulu "Themba (Male, ZA)": "zu-ZA-ThembaNeural", "Thando (Female, ZA)": "zu-ZA-ThandoNeural", } def text_to_speech(text: str, voice: str) -> str: """Wrapper function to run async code and return audio file""" if not text or not voice: return None return asyncio.run(generate_speech(text, VOICES.get(voice, VOICES["Jenny (Female, US)"]))) with gr.Blocks(title="Text-to-Speech", theme="soft") as demo: gr.Markdown("## Text-to-Speech Converter") text_input = gr.Textbox( label="Enter your text", placeholder="Type or paste your text here...", lines=5, max_lines=10 ) voice_dropdown = gr.Dropdown( choices=list(VOICES.keys()), label="Select Voice", value="Jenny (Female, US)" ) generate_btn = gr.Button("Generate Speech", variant="primary") audio_output = gr.Audio(label="Listen to Speech", autoplay=True) generate_btn.click( fn=text_to_speech, inputs=[text_input, voice_dropdown], outputs=audio_output ) if __name__ == "__main__": demo.launch(share=True) # Set share=True for public link (remove for local only)