Abhisksks commited on
Commit
ff16eb0
·
verified ·
1 Parent(s): 14b66dc

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +180 -0
  2. requirements.txt +1 -0
app.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import edge_tts
3
+ import asyncio
4
+ from flask import Flask, render_template, request, send_from_directory, jsonify
5
+ app = Flask(__name__)
6
+ AUDIO_DIR = os.path.join(os.getcwd(), 'generated_audio')
7
+ os.makedirs(AUDIO_DIR, exist_ok=True)
8
+
9
+ voices = {
10
+ 'Multilingual': {
11
+ 'Andrew': {'voice_id': 'en-US-AndrewMultilingualNeural', 'styles': ['default']},
12
+ 'Ava': {'voice_id': 'en-US-AvaMultilingualNeural', 'styles': ['default']},
13
+ 'Brian': {'voice_id': 'en-US-BrianMultilingualNeural', 'styles': ['default']},
14
+ 'Emma': {'voice_id': 'en-US-EmmaMultilingualNeural', 'styles': ['default']},
15
+ 'Florian': {'voice_id': 'de-DE-FlorianMultilingualNeural', 'styles': ['default']},
16
+ 'Giuseppe': {'voice_id': 'it-IT-GiuseppeMultilingualNeural', 'styles': ['default']},
17
+ 'Hyunsu': {'voice_id': 'ko-KR-HyunsuMultilingualNeural', 'styles': ['default']},
18
+ 'Remy': {'voice_id': 'fr-FR-RemyMultilingualNeural', 'styles': ['default']},
19
+ 'Seraphina': {'voice_id': 'de-DE-SeraphinaMultilingualNeural', 'styles': ['default']},
20
+ 'Thalita': {'voice_id': 'pt-BR-ThalitaMultilingualNeural', 'styles': ['default']},
21
+ 'Vivienne': {'voice_id': 'fr-FR-VivienneMultilingualNeural', 'styles': ['default']}
22
+ },
23
+ 'Arabic': {
24
+ 'Fatima': {'voice_id': 'ar-AE-FatimaNeural', 'styles': ['default']},
25
+ 'Hamdan': {'voice_id': 'ar-AE-HamdanNeural', 'styles': ['default']},
26
+ 'Ali': {'voice_id': 'ar-BH-AliNeural', 'styles': ['default']},
27
+ 'Laila': {'voice_id': 'ar-BH-LailaNeural', 'styles': ['default']},
28
+ 'Salma': {'voice_id': 'ar-EG-SalmaNeural', 'styles': ['default']},
29
+ 'Shakir': {'voice_id': 'ar-EG-ShakirNeural', 'styles': ['default']}
30
+ },
31
+ 'Chinese': {
32
+ 'Xiaoxiao': {'voice_id': 'zh-CN-XiaoxiaoNeural', 'styles': ['default']},
33
+ 'Xiaoyi': {'voice_id': 'zh-CN-XiaoyiNeural', 'styles': ['default']},
34
+ 'Yunjian': {'voice_id': 'zh-CN-YunjianNeural', 'styles': ['default']},
35
+ 'Yunxi': {'voice_id': 'zh-CN-YunxiNeural', 'styles': ['default']},
36
+ 'Yunxia': {'voice_id': 'zh-CN-YunxiaNeural', 'styles': ['default']},
37
+ 'Yunyang': {'voice_id': 'zh-CN-YunyangNeural', 'styles': ['default']}
38
+ },
39
+ 'English': {
40
+ 'Ana': {'voice_id': 'en-US-AnaNeural', 'styles': ['default']},
41
+ 'Andrew': {'voice_id': 'en-US-AndrewNeural', 'styles': ['default']},
42
+ 'Aria': {'voice_id': 'en-US-AriaNeural', 'styles': ['default']},
43
+ 'Ava': {'voice_id': 'en-US-AvaNeural', 'styles': ['default']},
44
+ 'Brian': {'voice_id': 'en-US-BrianNeural', 'styles': ['default']},
45
+ 'Christopher': {'voice_id': 'en-US-ChristopherNeural', 'styles': ['default']},
46
+ 'Emma': {'voice_id': 'en-US-EmmaNeural', 'styles': ['default']},
47
+ 'Eric': {'voice_id': 'en-US-EricNeural', 'styles': ['default']},
48
+ 'Guy': {'voice_id': 'en-US-GuyNeural', 'styles': ['default']},
49
+ 'Jenny': {'voice_id': 'en-US-JennyNeural', 'styles': ['default']},
50
+ 'Michelle': {'voice_id': 'en-US-MichelleNeural', 'styles': ['default']},
51
+ 'Roger': {'voice_id': 'en-US-RogerNeural', 'styles': ['default']},
52
+ 'Steffan': {'voice_id': 'en-US-SteffanNeural', 'styles': ['default']}
53
+ },
54
+ 'French': {
55
+ 'Denise': {'voice_id': 'fr-FR-DeniseNeural', 'styles': ['default']},
56
+ 'Eloise': {'voice_id': 'fr-FR-EloiseNeural', 'styles': ['default']},
57
+ 'Henri': {'voice_id': 'fr-FR-HenriNeural', 'styles': ['default']},
58
+ 'Charline': {'voice_id': 'fr-BE-CharlineNeural', 'styles': ['default']},
59
+ 'Gerard': {'voice_id': 'fr-BE-GerardNeural', 'styles': ['default']},
60
+ 'Antoine': {'voice_id': 'fr-CA-AntoineNeural', 'styles': ['default']},
61
+ 'Jean': {'voice_id': 'fr-CA-JeanNeural', 'styles': ['default']},
62
+ 'Sylvie': {'voice_id': 'fr-CA-SylvieNeural', 'styles': ['default']},
63
+ 'Thierry': {'voice_id': 'fr-CA-ThierryNeural', 'styles': ['default']}
64
+ },
65
+ 'German': {
66
+ 'Amala': {'voice_id': 'de-DE-AmalaNeural', 'styles': ['default']},
67
+ 'Conrad': {'voice_id': 'de-DE-ConradNeural', 'styles': ['default']},
68
+ 'Katja': {'voice_id': 'de-DE-KatjaNeural', 'styles': ['default']},
69
+ 'Killian': {'voice_id': 'de-DE-KillianNeural', 'styles': ['default']}
70
+ },
71
+ 'Hindi': {
72
+ 'Madhur': {'voice_id': 'hi-IN-MadhurNeural', 'styles': ['default']},
73
+ 'Swara': {'voice_id': 'hi-IN-SwaraNeural', 'styles': ['default']}
74
+ },
75
+ 'Italian': {
76
+ 'Diego': {'voice_id': 'it-IT-DiegoNeural', 'styles': ['default']},
77
+ 'Elsa': {'voice_id': 'it-IT-ElsaNeural', 'styles': ['default']},
78
+ 'Isabella': {'voice_id': 'it-IT-IsabellaNeural', 'styles': ['default']}
79
+ },
80
+ 'Japanese': {
81
+ 'Keita': {'voice_id': 'ja-JP-KeitaNeural', 'styles': ['default']},
82
+ 'Nanami': {'voice_id': 'ja-JP-NanamiNeural', 'styles': ['default']}
83
+ },
84
+ 'Korean': {
85
+ 'InJoon': {'voice_id': 'ko-KR-InJoonNeural', 'styles': ['default']},
86
+ 'SunHi': {'voice_id': 'ko-KR-SunHiNeural', 'styles': ['default']}
87
+ },
88
+ 'Portuguese': {
89
+ 'Antonio': {'voice_id': 'pt-BR-AntonioNeural', 'styles': ['default']},
90
+ 'Francisca': {'voice_id': 'pt-BR-FranciscaNeural', 'styles': ['default']},
91
+ 'Duarte': {'voice_id': 'pt-PT-DuarteNeural', 'styles': ['default']},
92
+ 'Raquel': {'voice_id': 'pt-PT-RaquelNeural', 'styles': ['default']}
93
+ },
94
+ 'Russian': {
95
+ 'Dmitry': {'voice_id': 'ru-RU-DmitryNeural', 'styles': ['default']},
96
+ 'Svetlana': {'voice_id': 'ru-RU-SvetlanaNeural', 'styles': ['default']}
97
+ },
98
+ 'Spanish': {
99
+ 'Alvaro': {'voice_id': 'es-ES-AlvaroNeural', 'styles': ['default']},
100
+ 'Elvira': {'voice_id': 'es-ES-ElviraNeural', 'styles': ['default']},
101
+ 'Ximena': {'voice_id': 'es-ES-XimenaNeural', 'styles': ['default']},
102
+ 'Dalia': {'voice_id': 'es-MX-DaliaNeural', 'styles': ['default']},
103
+ 'Jorge': {'voice_id': 'es-MX-JorgeNeural', 'styles': ['default']},
104
+ 'Alonso': {'voice_id': 'es-US-AlonsoNeural', 'styles': ['default']},
105
+ 'Paloma': {'voice_id': 'es-US-PalomaNeural', 'styles': ['default']}
106
+ }
107
+ }
108
+
109
+ @app.route('/')
110
+ def index():
111
+ return render_template('index.html', voices=voices)
112
+
113
+ @app.route('/get_voice_info', methods=['GET'])
114
+ def get_voice_info():
115
+ voice_id = request.args.get('voice_id')
116
+ language = request.args.get('language')
117
+ if language in voices and voice_id in voices[language]:
118
+ return jsonify(voices[language][voice_id])
119
+ return jsonify({'error': 'Voice not found'})
120
+
121
+ @app.route('/generate_audio', methods=['POST'])
122
+ async def generate_audio():
123
+ text = request.form.get('text')
124
+ language = request.form.get('language')
125
+ voice = request.form.get('voice')
126
+ style = request.form.get('style', 'default')
127
+
128
+ # Format rate properly with % symbol
129
+ rate_value = request.form.get('rate', '0')
130
+ rate = f"{'+' if int(rate_value) >= 0 else ''}{rate_value}%"
131
+
132
+ # Format volume properly with % symbol
133
+ volume_value = request.form.get('volume', '0')
134
+ volume = f"{'+' if int(volume_value) >= 0 else ''}{volume_value}%"
135
+
136
+ # Format pitch properly with Hz
137
+ pitch_value = request.form.get('pitch', '0')
138
+ pitch = f"{'+' if int(pitch_value) >= 0 else ''}{pitch_value}Hz"
139
+
140
+ if not all([text, language, voice]):
141
+ return jsonify({'error': 'Missing required parameters', 'success': False})
142
+
143
+ try:
144
+ voice_info = voices[language][voice]
145
+ voice_id = voice_info['voice_id']
146
+
147
+ if style != 'default':
148
+ voice_id = f"{voice_id}(Style={style})"
149
+
150
+ communicate = edge_tts.Communicate(
151
+ text,
152
+ voice_id,
153
+ rate=rate,
154
+ volume=volume,
155
+ pitch=pitch
156
+ )
157
+
158
+ audio_filename = f"{language}_{voice}_{hash(text)}.mp3"
159
+ audio_filepath = os.path.join(AUDIO_DIR, audio_filename)
160
+
161
+ await communicate.save(audio_filepath)
162
+
163
+ return jsonify({
164
+ 'success': True,
165
+ 'audio_path': f'/generated_audio/{audio_filename}',
166
+ 'filename': audio_filename
167
+ })
168
+ except Exception as e:
169
+ return jsonify({'error': str(e), 'success': False})
170
+
171
+ @app.route('/generated_audio/<filename>')
172
+ def serve_audio(filename):
173
+ return send_from_directory(AUDIO_DIR, filename)
174
+
175
+ @app.route('/download_audio/<filename>')
176
+ def download_audio(filename):
177
+ return send_from_directory(AUDIO_DIR, filename, as_attachment=True)
178
+
179
+ if __name__ == '__main__':
180
+ app.run(debug=False, host='0.0.0.0')
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ telethon