suprimedev commited on
Commit
b4b418f
·
verified ·
1 Parent(s): 128a17b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +217 -51
app.py CHANGED
@@ -1,74 +1,240 @@
1
- # کد اصلاح شده با توجه به مرحله بیگانگان به‌درستی اسکوپدهایع، бродریạ، و جستجوهایوسرا مدیریت می‌کند:
2
-
3
  import gradio as gr
4
  import speech_recognition as sr
5
  from pydub import AudioSegment
6
  import numpy as np
7
- import tempfile
 
8
  import os
 
 
 
9
 
10
  # تنظیمات اولیه
11
  recognizer = sr.Recognizer()
12
  recognizer.energy_threshold = 300
13
  recognizer.dynamic_energy_threshold = True
14
 
15
- # سرکننده صداهای واقعی
16
- def process_audio_chunk(audio_chunk):
17
- """پردازش یک قطعه صوتی"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  try:
19
- buffer = io.BytesIO()
20
- with wave.open(buffer, 'wb') as wav_file:
21
- wav_file.setnchannels(1)
22
- wav_file.setsampwidth(2)
23
- wav_file.setframerate(16000)
24
- wav_file.writeframes(np.int16(audio_chunk * 32767))
25
- with sr.AudioFile(io.BytesIO(buffer.getvalue())) as source:
26
  audio = recognizer.record(source)
27
- # تلاش با اولویت فارسی
 
28
  try:
29
- return recognizer.recognize_google(audio, language='fa-IR')
30
  except sr.UnknownValueError:
31
- return recognizer.recognize_google(audio, language='en-US', show_all=False)
 
 
 
 
 
 
 
32
  except Exception as e:
33
- return "[خطا در تشخیص]"
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
- # رابط کاربری طراحی شده
36
- with gr.Blocks(title="گستره گفتار به متن", theme=gr.themes.Soft()) as demo:
37
- gr.Markdown("# 🎙️ تبدیل گفتار به متن (پیش‌روز 2025)")
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- # تب ضبط مستقیم
40
- with gr.TabItem("🎙️ ضبط مستقیم"):
41
- audio_input = gr.Audio(type="numpy", label="میکروفون", streaming=True)
42
- clear_btn = gr.Button("پاک کردن")
43
- output = gr.Textbox(label="متن تشخیص داده‌شده", lines=12)
44
 
45
- def update_transcript(audio, transcript):
46
- output = ""
47
- for segment in audio:
48
- transcribed = process_audio_chunk(segment)
49
- if transcribed:
50
- output += transcribed + " "
51
- return output.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
- audio_input.stream(update_transcript, inputs=[audio_input, gr.State("")], outputs=[output])
 
 
 
 
 
54
 
55
- # تب فایل صوتی
56
- with gr.TabItem("📁 فایل صوتی"):
57
- file_input = gr.Audio(type="file", label="انتخاب فایل")
58
- progress = gr.Textbox(label="وضعیت")
59
- file_output = gr.Textbox(label="متن خروجی")
60
- save_btn = gr.Button("ذخیره")
61
 
62
- def process_file(audio_file, chunk_size=30000):
63
- audio = AudioSegment.from_file(audio_file)
64
- chunk_ms = chunk_size * 1000
65
- results = []
66
- for i in range(0, len(audio), chunk_ms):
67
- chunk = audio[i:i+chunk_ms]
68
- chunk_array = np.array(chunk.get_array_of_samples())
69
- chunk_np = chunk_array.astype(np.float32) / 32767.0
70
- recognized = process_audio_chunk(chunk_np)
71
- results.append(recognized)
72
- return " ".join(results)
73
 
74
- demo.queue().launch(share=True)
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import speech_recognition as sr
3
  from pydub import AudioSegment
4
  import numpy as np
5
+ import io
6
+ import wave
7
  import os
8
+ import threading
9
+ import queue
10
+ from functools import lru_cache
11
 
12
  # تنظیمات اولیه
13
  recognizer = sr.Recognizer()
14
  recognizer.energy_threshold = 300
15
  recognizer.dynamic_energy_threshold = True
16
 
17
+ # صف‌های پردازش real-time
18
+ audio_queue = queue.Queue()
19
+ transcript_queue = queue.Queue()
20
+
21
+ # متغیرهای حفظ متن
22
+ current_transcript = ""
23
+ transcript_lock = threading.Lock()
24
+
25
+ # تابع تبدیل numpy به فرمت WAV
26
+ def numpy_to_wav(audio_data, sample_rate=16000):
27
+ """تعداد به فرمت WAV با نرمال‌سازی"""
28
+ buffer = io.BytesIO()
29
+ with wave.open(buffer, 'wb') as wav_file:
30
+ wav_file.setnchannels(1)
31
+ wav_file.setsampwidth(2)
32
+ wav_file.setframerate(sample_rate)
33
+ wav_file.writeframes(np.int16(audio_data * 32767))
34
+ buffer.seek(0)
35
+ return AudioSegment.from_wav(buffer)
36
+
37
+ # پردازش یک قطعه صوتی
38
+ @lru_cache(maxsize=128)
39
+ def process_audio_chunk(chunk_data):
40
+ """پردازش یک قطعه صوتی با Google Speech Recognition"""
41
  try:
42
+ # تبدیل به وفرمت WAV
43
+ audio_segment = numpy_to_wav(chunk_data)
44
+ with sr.AudioFile(io.BytesIO(audio_segment.raw_data)) as source:
 
 
 
 
45
  audio = recognizer.record(source)
46
+
47
+ # تلاش با اولویت فارسی
48
  try:
49
+ text = recognizer.recognize_google(audio, language='fa-IR')
50
  except sr.UnknownValueError:
51
+ # اگر فارسی معتبر نباشد، با انگلیسی تلاش کنیم
52
+ text = recognizer.recognize_google(audio, language='en-US', show_all=False)
53
+ except sr.RequestError:
54
+ text = "[خطا در اتصال سرویس گوگل]"
55
+ except Exception as e:
56
+ text = ""
57
+
58
+ return text.strip()
59
  except Exception as e:
60
+ print(f"خطا در پردازش {e}")
61
+ return ""
62
+
63
+ # تابع کمکی به real-time
64
+ def update_realtime_transcript():
65
+ """به‌روزرسانی متن real-time"""
66
+ while True:
67
+ if not transcript_queue.empty():
68
+ new_text = transcript_queue.get()
69
+ with transcript_lock:
70
+ current_transcript += " " + new_text
71
+ current_transcript = " ".join(current_transcript.split())
72
+ time.sleep(0.1)
73
 
74
+ # رابط کاربری با Gradio
75
+ with gr.Blocks(
76
+ title="گستره گفتار به متن",
77
+ theme=gr.themes.Soft(),
78
+ css="""
79
+ .gradio-container { font-family: 'Vazir', 'Tahoma', sans-serif !important; }
80
+ .rtl { direction: rtl; text-align: right; }
81
+ """
82
+ ) as demo:
83
+
84
+ gr.HTML("""
85
+ <div style="text-align: center; max-width: 800px; margin: 0 auto;">
86
+ <h1 style="font-size: 2.5em; margin-bottom: 0.5em;">🎤 تبدیل گفتار به متن</h1>
87
+ <p style="font-size: 1.1em; color: #666; margin-bottom: 2em;">در این ابزار در حال برجسته‌سازی گفتارها را به فارسی یا انگلیسی تبدیل کنید.</p>
88
+ </div>
89
+ """)
90
 
91
+ with gr.Tabs():
 
 
 
 
92
 
93
+ # تب ضبط مستقیم
94
+ with gr.TabItem("🎙️ ضبط مستق��م"):
95
+ gr.Markdown("### میکروفون خود را فعال کرده و شروع به صحبت کنید")
96
+
97
+ with gr.Row():
98
+ with gr.Column(scale=1):
99
+ audio_input = gr.Audio(
100
+ sources=["microphone"],
101
+ type="numpy",
102
+ streaming=True,
103
+ label="میکروفون",
104
+ show_label=True,
105
+ elem_classes="rtl"
106
+ )
107
+
108
+ with gr.Column(scale=1):
109
+ clear_btn = gr.Button("🗑️ پاک کردن متن", variant="secondary", size="sm")
110
+
111
+ realtime_output = gr.Textbox(
112
+ label="متن تشخیص داده شده",
113
+ placeholder="شروع به صحبت کنید و متن اینجا ظاهر می‌شود...",
114
+ lines=12,
115
+ elem_classes="rtl",
116
+ rtl=True,
117
+ show_copy_button=True
118
+ )
119
+
120
+ # sentait‌ها
121
+ audio_input.stream(
122
+ lambda x: process_audio_chunk(x),
123
+ inputs=[audio_input],
124
+ outputs=[]
125
+ )
126
+
127
+ audio_input.stream(
128
+ lambda: update_realtime_transcript(),
129
+ inputs=[],
130
+ outputs=[realtime_output],
131
+ every=0.5
132
+ )
133
+
134
+ clear_btn.click(
135
+ lambda: "",
136
+ outputs=[realtime_output]
137
+ )
138
+
139
+ # تب فایل صوتی
140
+ with gr.TabItem("📁 فایل صوتی"):
141
+ gr.Markdown("### فایل صوتی خود را انتخاب کنید")
142
+
143
+ with gr.Row():
144
+ with gr.Column(scale=3):
145
+ file_input = gr.Audio(
146
+ sources=["upload"],
147
+ type="filepath",
148
+ label="انتخاب فایل صوتی",
149
+ elem_classes="rtl"
150
+ )
151
+
152
+ with gr.Column(scale=1):
153
+ chunk_duration = gr.Slider(
154
+ minimum=10,
155
+ maximum=60,
156
+ value=30,
157
+ step=5,
158
+ label="مدت هر بخش (ثانیه)",
159
+ elem_classes="rtl"
160
+ )
161
+
162
+ with gr.Row():
163
+ process_btn = gr.Button("🚀 شروع تبدیل", variant="primary", size="lg")
164
+ progress_label = gr.Textbox(
165
+ label="وضعیت پردازش",
166
+ interactive=False,
167
+ elem_classes="rtl"
168
+ )
169
+
170
+ file_output = gr.Textbox(
171
+ label="متن تشخیص داده شده",
172
+ placeholder="متن پس از پردازش اینجا نمایش داده می‌شود...",
173
+ lines=12,
174
+ elem_classes="rtl",
175
+ rtl=True,
176
+ show_copy_button=True
177
+ )
178
+
179
+ def safe_transcribe_file(file, duration):
180
+ """پردازش فایل صوتی با مدیریت خطا"""
181
+ if file is None:
182
+ return "لطفاً یک فایل صوتی آپلود کنید", "شروع پردازش"
183
+
184
+ try:
185
+ audio = AudioSegment.from_file(file)
186
+ results = []
187
+ total_chunks = len(audio) // (duration * 1000)
188
+
189
+ for i in range(0, len(audio), duration*1000):
190
+ chunk = audio[i:i+duration*1000]
191
+ text = process_audio_chunk(np.array(chunk.get_array_of_samples()))
192
+ if text:
193
+ results.append(text)
194
+
195
+ progress = min(((i + duration*1000) / len(audio)) * 100, 100)
196
+ yield " ".join(results), f"پیشرفت: {progress:.1f}%"
197
+
198
+ return " ".join(results), "تکمیل پردازش ✅"
199
+ except Exception as e:
200
+ return f"خطا: {str(e)}", "خطا در پردازش ❌"
201
+
202
+ process_btn.click(
203
+ safe_transcribe_file,
204
+ inputs=[file_input, chunk_duration],
205
+ outputs=[file_output, progress_label]
206
+ )
207
+
208
+ # بخش راهنما
209
+ with gr.Accordion("📖 راهنمای استفاده", open=False, elem_classes="rtl"):
210
+ gr.Markdown("""
211
+ ### نحوه استفاده:
212
+ **برای ضبط مستقیم:**
213
+ 1. به تب "ضبط مستقیم" بروید
214
+ 2. اجازه دسترسی به میکروفون را بدهید
215
+ 3. شروع به صحبت کنید
216
+ 4. متن به صورت خودکار نمایش داده می‌شود
217
 
218
+ **برای فایل صوتی:**
219
+ 1. به تب "فایل صوتی" بروید
220
+ 2. فایل مورد نظر را انتخاب کنید
221
+ 3. مدت زمان تقسیم‌بندی را تنظیم کنید (پیش‌فرض: ۳۰ ثانیه)
222
+ 4. روی "شروع تبدیل" کلیک کنید
223
+ 5. منتظر بمانید تا پردازش کامل شود
224
 
225
+ ### فرمت‌های پشتیبانی شده:
226
+ - MP3, WAV, M4A, FLAC, OGG, MP4, AVI, MOV
 
 
 
 
227
 
228
+ ### نکات مهم:
229
+ - 🎯 برای دقت بیشتر، از فایل‌های با کیفیت بالا استفاده کنید
230
+ - 🔇 نویز پس‌زمینه را به حداقل برسانید
231
+ - 🗣️ واضح و شمرده صحبت کنید
232
+ - 🌐 اتصال اینترنت پایدار داشته باشید
233
+ """, elem_classes="rtl")
 
 
 
 
 
234
 
235
+ # ساخت و اجرای برنامه
236
+ if __name__ == "__main__":
237
+ demo.queue().launch(
238
+ share=True,
239
+ show_error=True
240
+ )