snackshell commited on
Commit
4d15203
·
verified ·
1 Parent(s): e8ac110

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -104
app.py CHANGED
@@ -1,105 +1,110 @@
1
- import tempfile
2
- import edge_tts
3
- import gradio as gr
4
- import asyncio
5
-
6
- # --- Final, VERIFIED Language & Voice Configuration ---
7
- language_dict = {
8
- "English": {
9
- "Jenny (Female, US)": "en-US-JennyNeural",
10
- "Andrew (Male, US)": "en-US-AndrewNeural",
11
- "Sonia (Female, UK)": "en-GB-SoniaNeural",
12
- "Ryan (Male, UK)": "en-GB-RyanNeural"
13
- },
14
- "Amharic": {
15
- "Mekdes (Female)": "am-ET-MekdesNeural",
16
- "Ameha (Male)": "am-ET-AmehaNeural"
17
- },
18
- "Tigrinya": {
19
- # WORKAROUND: Using Amharic voices as a fallback for Tigrinya.
20
- "Lulia (Female)": "am-ET-MekdesNeural",
21
- "Birhane (Male)": "am-ET-AmehaNeural"
22
- },
23
- "Arabic": {
24
- "Zariyah (Female, KSA)": "ar-SA-ZariyahNeural",
25
- "Hamed (Male, KSA)": "ar-SA-HamedNeural"
26
- },
27
- "French": {
28
- "Denise (Female)": "fr-FR-DeniseNeural",
29
- "Henri (Male)": "fr-FR-HenriNeural"
30
- },
31
- "German": {
32
- "Katja (Female)": "de-DE-KatjaNeural",
33
- "Conrad (Male)": "de-DE-ConradNeural"
34
- },
35
- "Italian": {
36
- "Elsa (Female)": "it-IT-ElsaNeural",
37
- "Diego (Male)": "it-IT-DiegoNeural"
38
- },
39
- "Japanese": {
40
- "Nanami (Female)": "ja-JP-NanamiNeural",
41
- "Keita (Male)": "ja-JP-KeitaNeural"
42
- },
43
- "Korean": {
44
- "Sun-Hi (Female)": "ko-KR-SunHiNeural",
45
- "InJoon (Male)": "ko-KR-InJoonNeural"
46
- },
47
- "Chinese (Simplified)": {
48
- "Xiaoxiao (Female)": "zh-CN-XiaoxiaoNeural",
49
- "Yunxi (Male)": "zh-CN-YunxiNeural"
50
- },
51
- "Chinese (Traditional)": {
52
- "HsiaoChen (Female)": "zh-TW-HsiaoChenNeural",
53
- "YunJhe (Male)": "zh-TW-YunJheNeural"
54
- }
55
- }
56
-
57
- async def text_to_speech_edge(text, language, speaker):
58
- try:
59
- voice = language_dict[language][speaker]
60
- except KeyError:
61
- raise gr.Error(f"Error: Voice '{speaker}' not found for {language}.")
62
-
63
- try:
64
- communicate = edge_tts.Communicate(text, voice)
65
- with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
66
- tmp_path = tmp_file.name
67
- await asyncio.wait_for(communicate.save(tmp_path), timeout=60)
68
- return tmp_path
69
-
70
- except asyncio.TimeoutError:
71
- raise gr.Error("Error: Request timed out. Please try again.")
72
- except Exception as e:
73
- raise gr.Error(f"An unexpected error occurred: {str(e)}")
74
-
75
- def update_speakers(language):
76
- speakers = list(language_dict.get(language, []))
77
- return gr.Dropdown(choices=speakers, value=speakers[0] if speakers else None, interactive=True)
78
-
79
- # --- Gradio Interface ---
80
- with gr.Blocks(title="SelamGPT TTS", theme=gr.themes.Soft()) as demo:
81
- gr.Markdown("# SelamGPT Text-to-Speech")
82
-
83
- with gr.Row():
84
- language = gr.Dropdown(
85
- choices=list(language_dict.keys()),
86
- value="Amharic",
87
- label="Language"
88
- )
89
- speaker = gr.Dropdown(
90
- label="Speaker",
91
- choices=list(language_dict["Amharic"].keys()),
92
- value="Mekdes (Female)"
93
- )
94
-
95
- with gr.Column():
96
- input_text = gr.Textbox(label="Input Text", placeholder="Enter text here...")
97
- generate_btn = gr.Button("Generate Audio", variant="primary")
98
-
99
- output_audio = gr.Audio(label="Output Audio", autoplay=True)
100
-
101
- language.change(fn=update_speakers, inputs=language, outputs=speaker)
102
- generate_btn.click(fn=text_to_speech_edge, inputs=[input_text, language, speaker], outputs=output_audio)
103
-
104
- if __name__ == "__main__":
 
 
 
 
 
105
  demo.launch()
 
1
+ import tempfile
2
+ import edge_tts
3
+ import gradio as gr
4
+ import asyncio
5
+
6
+ # --- Final, VERIFIED Language & Voice Configuration ---
7
+ language_dict = {
8
+ "English": {
9
+ "Jenny (Female, US)": "en-US-JennyNeural",
10
+ "Andrew (Male, US)": "en-US-AndrewNeural",
11
+ "Sonia (Female, UK)": "en-GB-SoniaNeural",
12
+ "Ryan (Male, UK)": "en-GB-RyanNeural"
13
+ },
14
+ "Amharic": {
15
+ "Mekdes (Female)": "am-ET-MekdesNeural",
16
+ "Ameha (Male)": "am-ET-AmehaNeural"
17
+ },
18
+ "Tigrinya": {
19
+ # WORKAROUND: Using Amharic voices as a fallback for Tigrinya.
20
+ "Lulia (Female)": "am-ET-MekdesNeural",
21
+ "Birhane (Male)": "am-ET-AmehaNeural"
22
+ },
23
+ "Oromo": {
24
+ # This is a mock-up. It uses Swahili voices as a fallback.
25
+ "Zuri (Female)": "sw-KE-ZuriNeural",
26
+ "Rafiki (Male)": "sw-KE-RafikiNeural"
27
+ },
28
+ "Arabic": {
29
+ "Zariyah (Female, KSA)": "ar-SA-ZariyahNeural",
30
+ "Hamed (Male, KSA)": "ar-SA-HamedNeural"
31
+ },
32
+ "French": {
33
+ "Denise (Female)": "fr-FR-DeniseNeural",
34
+ "Henri (Male)": "fr-FR-HenriNeural"
35
+ },
36
+ "German": {
37
+ "Katja (Female)": "de-DE-KatjaNeural",
38
+ "Conrad (Male)": "de-DE-ConradNeural"
39
+ },
40
+ "Italian": {
41
+ "Elsa (Female)": "it-IT-ElsaNeural",
42
+ "Diego (Male)": "it-IT-DiegoNeural"
43
+ },
44
+ "Japanese": {
45
+ "Nanami (Female)": "ja-JP-NanamiNeural",
46
+ "Keita (Male)": "ja-JP-KeitaNeural"
47
+ },
48
+ "Korean": {
49
+ "Sun-Hi (Female)": "ko-KR-SunHiNeural",
50
+ "InJoon (Male)": "ko-KR-InJoonNeural"
51
+ },
52
+ "Chinese (Simplified)": {
53
+ "Xiaoxiao (Female)": "zh-CN-XiaoxiaoNeural",
54
+ "Yunxi (Male)": "zh-CN-YunxiNeural"
55
+ },
56
+ "Chinese (Traditional)": {
57
+ "HsiaoChen (Female)": "zh-TW-HsiaoChenNeural",
58
+ "YunJhe (Male)": "zh-TW-YunJheNeural"
59
+ }
60
+ }
61
+
62
+ async def text_to_speech_edge(text, language, speaker):
63
+ try:
64
+ voice = language_dict[language][speaker]
65
+ except KeyError:
66
+ raise gr.Error(f"Error: Voice '{speaker}' not found for {language}.")
67
+
68
+ try:
69
+ communicate = edge_tts.Communicate(text, voice)
70
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
71
+ tmp_path = tmp_file.name
72
+ await asyncio.wait_for(communicate.save(tmp_path), timeout=60)
73
+ return tmp_path
74
+
75
+ except asyncio.TimeoutError:
76
+ raise gr.Error("Error: Request timed out. Please try again.")
77
+ except Exception as e:
78
+ raise gr.Error(f"An unexpected error occurred: {str(e)}")
79
+
80
+ def update_speakers(language):
81
+ speakers = list(language_dict.get(language, []))
82
+ return gr.Dropdown(choices=speakers, value=speakers[0] if speakers else None, interactive=True)
83
+
84
+ # --- Gradio Interface ---
85
+ with gr.Blocks(title="SelamGPT TTS", theme=gr.themes.Soft()) as demo:
86
+ gr.Markdown("# SelamGPT Text-to-Speech")
87
+
88
+ with gr.Row():
89
+ language = gr.Dropdown(
90
+ choices=list(language_dict.keys()),
91
+ value="Amharic",
92
+ label="Language"
93
+ )
94
+ speaker = gr.Dropdown(
95
+ label="Speaker",
96
+ choices=list(language_dict["Amharic"].keys()),
97
+ value="Mekdes (Female)"
98
+ )
99
+
100
+ with gr.Column():
101
+ input_text = gr.Textbox(label="Input Text", placeholder="Enter text here...")
102
+ generate_btn = gr.Button("Generate Audio", variant="primary")
103
+
104
+ output_audio = gr.Audio(label="Output Audio", autoplay=True)
105
+
106
+ language.change(fn=update_speakers, inputs=language, outputs=speaker)
107
+ generate_btn.click(fn=text_to_speech_edge, inputs=[input_text, language, speaker], outputs=output_audio)
108
+
109
+ if __name__ == "__main__":
110
  demo.launch()