suprimedev commited on
Commit
1c4f949
·
verified ·
1 Parent(s): d4e17af

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +141 -37
app.py CHANGED
@@ -3,6 +3,7 @@ from pydub import AudioSegment
3
  import requests
4
  import os
5
  import uuid # برای تولید نام فایل منحصر به فرد
 
6
 
7
  # مسیر ذخیره فایل‌های موقت
8
  TEMP_DIR = "temp_audio"
@@ -34,7 +35,11 @@ def get_audio_from_input(input_source):
34
 
35
  if input_source.startswith("http://") or input_source.startswith("https://"):
36
  # این یک URL است، دانلودش کن
37
- temp_filepath = unique_filename + "_downloaded" + os.path.splitext(input_source)[1].split("?")[0]
 
 
 
 
38
  if not download_file(input_source, temp_filepath):
39
  return None, f"خطا در دانلود فایل از لینک: {input_source}"
40
  audio_path = temp_filepath
@@ -50,24 +55,26 @@ def get_audio_from_input(input_source):
50
  finally:
51
  # اگر فایل از URL دانلود شده بود، آن را پاک کن
52
  if 'temp_filepath' in locals() and os.path.exists(temp_filepath):
53
- os.remove(temp_filepath)
 
 
 
 
 
 
54
 
55
  def merge_audio_files(input_sources):
56
  """
57
  چندین فایل صوتی را (از لینک یا فایل) ادغام می‌کند و یک فایل MP3 خروجی می‌دهد.
58
- input_sources: یک رشته حاوی لینک‌ها یا مسیرهای فایل‌ها که با خط جدید جدا شده‌اند.
59
  """
60
- if not input_sources.strip():
61
- return None, "لطفاً حداقل یک لینک یا مسیر فایل وارد کنید."
62
-
63
- sources = [s.strip() for s in input_sources.split('\n') if s.strip()]
64
- if not sources:
65
- return None, "خطا: لیست ورودی‌ها خالی است."
66
 
67
  combined_audio = AudioSegment.empty()
68
  errors = []
69
 
70
- for source in sources:
71
  audio_segment, error = get_audio_from_input(source)
72
  if audio_segment:
73
  combined_audio += audio_segment
@@ -85,44 +92,141 @@ def merge_audio_files(input_sources):
85
  except Exception as e:
86
  return None, f"خطا در ذخیره فایل خروجی: {e}"
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  # ایجاد رابط کاربری Gradio
89
  with gr.Blocks() as demo:
90
  gr.Markdown(
91
  """
92
- # ابزار ادغام فایل‌های صوتی (MP3/WAV)
93
- در اینجا می‌توانید لینک چندین فایل صوتی (MP3 یا WAV) را وارد کنید (هر لینک در یک خط جدید).
94
- این ابزار تمام فایل‌ها را دانلود کرده و به یک فایل MP3 واحد ادغام می‌کند.
95
- **نکته:** برای لینک‌های دانلود، مطمئن شوید قابلیت دانلود مستقیم دارند (نه صفحات وب).
 
 
96
  """
97
  )
 
 
 
 
 
 
 
 
 
 
 
98
 
99
- audio_links_input = gr.Textbox(
100
- label="لینک یا مسیر فایل‌های صوتی (هر کدام در یک خط جدید)",
101
- placeholder="مثال:\nhttps://example.com/audio1.mp3\n./local_audio.wav\nhttps://example.com/audio2.wav",
102
- lines=10
103
- )
 
 
 
 
 
 
 
 
 
 
104
 
105
- output_message = gr.Textbox(label="پیام", interactive=False)
106
- output_audio = gr.Audio(label="فایل صوتی ادغام شده", type="filepath")
 
 
 
 
 
 
 
 
107
 
108
- merge_button = gr.Button("ادغام فایل‌ها")
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
- merge_button.click(
111
- fn=merge_audio_files,
112
- inputs=[audio_links_input],
113
- outputs=[output_audio, output_message]
114
- )
115
-
116
- gr.Examples(
117
- examples=[
118
- ["https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3\nhttps://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"],
119
- # اگر فایل‌های واقعی داشته باشید، می‌توانید این خط را فعال کنید:
120
- # ["./path/to/your/local_audio.mp3\n./path/to/another/local_audio.wav"]
121
- ],
122
- inputs=audio_links_input,
123
- label="نمونه‌ها"
124
- )
125
 
126
  if __name__ == "__main__":
127
  demo.launch() # برای اجرا در لوکال
128
  # demo.launch(share=True) # برای اشتراک‌گذاری موقت در یک لینک عمومی (برای هوش مصنوعی)
 
 
3
  import requests
4
  import os
5
  import uuid # برای تولید نام فایل منحصر به فرد
6
+ import re # برای تجزیه متن
7
 
8
  # مسیر ذخیره فایل‌های موقت
9
  TEMP_DIR = "temp_audio"
 
35
 
36
  if input_source.startswith("http://") or input_source.startswith("https://"):
37
  # این یک URL است، دانلودش کن
38
+ # سعی می کنیم پسوند فایل را از URL تشخیص دهیم، در غیر این صورت از .mp3 استفاده می کنیم.
39
+ file_extension = os.path.splitext(input_source.split('?')[0])[1]
40
+ if not file_extension: # اگر پسوندی در URL نباشد (مثلا برای APIها)
41
+ file_extension = ".mp3"
42
+ temp_filepath = unique_filename + "_downloaded" + file_extension
43
  if not download_file(input_source, temp_filepath):
44
  return None, f"خطا در دانلود فایل از لینک: {input_source}"
45
  audio_path = temp_filepath
 
55
  finally:
56
  # اگر فایل از URL دانلود شده بود، آن را پاک کن
57
  if 'temp_filepath' in locals() and os.path.exists(temp_filepath):
58
+ # اگر فایل بعداً توسط pydub پردازش و لود شده باشد، می‌توانیم آن را حذف کنیم.
59
+ # در غیر این صورت، ممکن است در حال استفاده باشد.
60
+ try:
61
+ os.remove(temp_filepath)
62
+ except OSError as e:
63
+ print(f"Error removing temporary file {temp_filepath}: {e}")
64
+
65
 
66
  def merge_audio_files(input_sources):
67
  """
68
  چندین فایل صوتی را (از لینک یا فایل) ادغام می‌کند و یک فایل MP3 خروجی می‌دهد.
69
+ input_sources: یک لیست از URLها یا مسیرهای فایل‌ها.
70
  """
71
+ if not input_sources:
72
+ return None, "لیست ورودی‌های صوتی خالی است."
 
 
 
 
73
 
74
  combined_audio = AudioSegment.empty()
75
  errors = []
76
 
77
+ for source in input_sources:
78
  audio_segment, error = get_audio_from_input(source)
79
  if audio_segment:
80
  combined_audio += audio_segment
 
92
  except Exception as e:
93
  return None, f"خطا در ذخیره فایل خروجی: {e}"
94
 
95
+ def tts_and_merge(text_input):
96
+ """
97
+ متن ورودی را تجزیه می‌کند، با Talkbot API صدا تولید می‌کند و سپس آن‌ها را ادغام می‌کند.
98
+ """
99
+ if not text_input.strip():
100
+ return None, "لطفاً متنی برای پردازش وارد کنید."
101
+
102
+ # الگو برای تشخیص شماره و متن پرانتزی: (شماره)متن
103
+ # این الگو همچنین newline را برای پردازش خط به خط در نظر می‌گیرد.
104
+ lines = text_input.strip().split('\n')
105
+
106
+ audio_urls_to_merge = []
107
+ errors = []
108
+
109
+ for line in lines:
110
+ match = re.match(r'^\s*\((\d+)\)(.*)$', line)
111
+ if match:
112
+ speaker_number = match.group(1)
113
+ text_for_tts = match.group(2).strip()
114
+
115
+ if not text_for_tts:
116
+ errors.append(f"خطا: متن خالی برای گوینده {speaker_number} در خط '{line}'")
117
+ continue
118
+
119
+ # ساخت URL برای Talkbot API
120
+ # متن باید URL-encoded شود، اما requests.get این کار را به طور خودکار برای پارامترها انجام می‌دهد.
121
+ tts_url = f"https://talkbot.ir/api/TTS-S{speaker_number}?text={text_for_tts}"
122
+
123
+ print(f"درخواست TTS برای گوینده {speaker_number}: {tts_url}") # برای debugging
124
+
125
+ try:
126
+ # درخواست به Talkbot API
127
+ response = requests.get(tts_url)
128
+ response.raise_for_status() # برای خطاهای HTTP
129
+
130
+ # فرض بر این است که پاسخ مستقیم لینک MP3 است
131
+ # اگر API لینک را در JSON برمی‌گرداند، باید آن را parse کنید.
132
+ # در مثال شما، فرض می‌شود پاسخ مستقیم لی��ک MP3 است.
133
+ audio_link = response.text.strip()
134
+
135
+ if audio_link.startswith("http"): # مطمئن شوید لینک معتبر است
136
+ audio_urls_to_merge.append(audio_link)
137
+ else:
138
+ errors.append(f"API برای گوینده {speaker_number} لینک معتبری برنگرداند: '{audio_link}'")
139
+
140
+ except requests.exceptions.RequestException as e:
141
+ errors.append(f"خطا در ارتباط با Talkbot API برای گوینده {speaker_number}: {e}")
142
+ except Exception as e:
143
+ errors.append(f"خطای غیرمنتظره در پردازش Talkbot API برای گوینده {speaker_number}: {e}")
144
+ else:
145
+ if line.strip(): # اگر خط خالی نباشد، اما مطابق الگو نباشد
146
+ errors.append(f"فرمت نامعتبر در خط: '{line}'. انتظار می‌رود (شماره)متن.")
147
+
148
+
149
+ if not audio_urls_to_merge:
150
+ return None, "هیچ فایل صوتی برای ادغام تولید نشد." + "\n".join(errors) if errors else ""
151
+
152
+ # حالا لینک‌های تولید شده را به تابع merge_audio_files اصلی می‌فرستیم
153
+ merged_output_path, merge_message = merge_audio_files(audio_urls_to_merge)
154
+
155
+ final_message = merge_message
156
+ if errors:
157
+ final_message += "\n\nخطاهای رخ داده:\n" + "\n".join(errors)
158
+
159
+ return merged_output_path, final_message
160
+
161
+
162
  # ایجاد رابط کاربری Gradio
163
  with gr.Blocks() as demo:
164
  gr.Markdown(
165
  """
166
+ # ابزار ادغام فایل‌های صوتی (MP3/WAV) و تولید صدا از متن
167
+ در اینجا دو بخش اصلی وجود دارد:
168
+ 1. **ادغام فایل‌های صوتی موجود:** می‌توانید لینک‌های فایل‌های صوتی (MP3/WAV) را وارد کنید.
169
+ 2. **تولید صدا از متن با Talkbot API و ادغام:** متنی را با فرمت `(شماره)متن` وارد کنید.
170
+ (مثال: `(1)سلام\n(2)بله`)
171
+ این بخش با استفاده از Talkbot API صدا تولید کرده و آن‌ها را ادغام می‌کند.
172
  """
173
  )
174
+
175
+ with gr.Tab("ادغام فایل‌های صوتی موجود"):
176
+ gr.Markdown("## ادغام فایل‌های صوتی موجود (از لینک یا فایل محلی)")
177
+ audio_links_input = gr.Textbox(
178
+ label="لینک یا مسیر فایل‌های صوتی (هر کدام در یک خط جدید)",
179
+ placeholder="مثال:\nhttps://example.com/audio1.mp3\n./local_audio.wav\nhttps://example.com/audio2.wav",
180
+ lines=10
181
+ )
182
+ audio_merge_output_message = gr.Textbox(label="پیام", interactive=False)
183
+ audio_merge_output_audio = gr.Audio(label="فایل صوتی ادغام شده", type="filepath")
184
+ merge_button = gr.Button("ادغام فایل‌های صوتی")
185
 
186
+ merge_button.click(
187
+ fn=lambda x: merge_audio_files([s.strip() for s in x.split('\n') if s.strip()]), # تبدیل ورودی رشته‌ای به لیست برای تابع
188
+ inputs=[audio_links_input],
189
+ outputs=[audio_merge_output_audio, audio_merge_output_message]
190
+ )
191
+
192
+ gr.Examples(
193
+ examples=[
194
+ ["https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3\nhttps://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"],
195
+ # اگر فایل‌های واقعی داشته باشید، می‌توانید این خط را فعال کنید:
196
+ # ["./path/to/your/local_audio.mp3\n./path/to/another/local_audio.wav"]
197
+ ],
198
+ inputs=audio_links_input,
199
+ label="نمونه‌ها"
200
+ )
201
 
202
+ with gr.Tab("تولید صدا از متن (Talkbot API) و ادغام"):
203
+ gr.Markdown("## تولید صدا با Talkbot API و ادغام فایل‌ها")
204
+ tts_text_input = gr.Textbox(
205
+ label="متن برای تولید صدا (فرمت: (شماره)متن - هر پرسوناژ در یک خط جدید)",
206
+ placeholder="(1)سلام این تست صحبت اولین نفر است.\n(2)سلام، بله این هم یک تست است و من کاراکتر دوم هستم.\n(1)خب از کجا شروع کنیم\n(2)بهتره از اول شروع کنیم",
207
+ lines=10
208
+ )
209
+ tts_output_message = gr.Textbox(label="پیام", interactive=False)
210
+ tts_output_audio = gr.Audio(label="فایل صوتی تولید و ادغام شده", type="filepath")
211
+ tts_merge_button = gr.Button("تولید و ادغام صدا")
212
 
213
+ tts_merge_button.click(
214
+ fn=tts_and_merge,
215
+ inputs=[tts_text_input],
216
+ outputs=[tts_output_audio, tts_output_message]
217
+ )
218
+
219
+ gr.Examples(
220
+ examples=[
221
+ ["(1)سلام این تست صحبت اولین نفر است.\n(2)سلام، بله این هم یک تست است و من کاراکتر دوم هستم."],
222
+ ["(1)امروز هوا چطوره؟\n(2)فکر کنم آفتابیه."]
223
+ ],
224
+ inputs=tts_text_input,
225
+ label="نمونه‌ها"
226
+ )
227
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
 
229
  if __name__ == "__main__":
230
  demo.launch() # برای اجرا در لوکال
231
  # demo.launch(share=True) # برای اشتراک‌گذاری موقت در یک لینک عمومی (برای هوش مصنوعی)
232
+