Spaces:
Build error
Build error
| import gradio as gr | |
| import speech_recognition as sr | |
| from pydub import AudioSegment | |
| import numpy as np | |
| import io | |
| import wave | |
| import os | |
| import threading | |
| import queue | |
| from functools import lru_cache | |
| # تنظیمات اولیه | |
| recognizer = sr.Recognizer() | |
| recognizer.energy_threshold = 300 | |
| recognizer.dynamic_energy_threshold = True | |
| # صفهای پردازش real-time | |
| audio_queue = queue.Queue() | |
| transcript_queue = queue.Queue() | |
| # متغیرهای حفظ متن | |
| current_transcript = "" | |
| transcript_lock = threading.Lock() | |
| # تابع تبدیل numpy به فرمت WAV | |
| def numpy_to_wav(audio_data, sample_rate=16000): | |
| """تعداد به فرمت WAV با نرمالسازی""" | |
| buffer = io.BytesIO() | |
| with wave.open(buffer, 'wb') as wav_file: | |
| wav_file.setnchannels(1) | |
| wav_file.setsampwidth(2) | |
| wav_file.setframerate(sample_rate) | |
| wav_file.writeframes(np.int16(audio_data * 32767)) | |
| buffer.seek(0) | |
| return AudioSegment.from_wav(buffer) | |
| # پردازش یک قطعه صوتی | |
| def process_audio_chunk(chunk_data): | |
| """پردازش یک قطعه صوتی با Google Speech Recognition""" | |
| try: | |
| # تبدیل به وفرمت WAV | |
| audio_segment = numpy_to_wav(chunk_data) | |
| with sr.AudioFile(io.BytesIO(audio_segment.raw_data)) as source: | |
| audio = recognizer.record(source) | |
| # تلاش با اولویت فارسی | |
| try: | |
| text = recognizer.recognize_google(audio, language='fa-IR') | |
| except sr.UnknownValueError: | |
| # اگر فارسی معتبر نباشد، با انگلیسی تلاش کنیم | |
| text = recognizer.recognize_google(audio, language='en-US', show_all=False) | |
| except sr.RequestError: | |
| text = "[خطا در اتصال سرویس گوگل]" | |
| except Exception as e: | |
| text = "" | |
| return text.strip() | |
| except Exception as e: | |
| print(f"خطا در پردازش {e}") | |
| return "" | |
| # تابع کمکی به real-time | |
| def update_realtime_transcript(): | |
| """بهروزرسانی متن real-time""" | |
| while True: | |
| if not transcript_queue.empty(): | |
| new_text = transcript_queue.get() | |
| with transcript_lock: | |
| current_transcript += " " + new_text | |
| current_transcript = " ".join(current_transcript.split()) | |
| time.sleep(0.1) | |
| # رابط کاربری با Gradio | |
| with gr.Blocks( | |
| title="گستره گفتار به متن", | |
| theme=gr.themes.Soft(), | |
| css=""" | |
| .gradio-container { font-family: 'Vazir', 'Tahoma', sans-serif !important; } | |
| .rtl { direction: rtl; text-align: right; } | |
| """ | |
| ) as demo: | |
| gr.HTML(""" | |
| <div style="text-align: center; max-width: 800px; margin: 0 auto;"> | |
| <h1 style="font-size: 2.5em; margin-bottom: 0.5em;">🎤 تبدیل گفتار به متن</h1> | |
| <p style="font-size: 1.1em; color: #666; margin-bottom: 2em;">در این ابزار در حال برجستهسازی گفتارها را به فارسی یا انگلیسی تبدیل کنید.</p> | |
| </div> | |
| """) | |
| with gr.Tabs(): | |
| # تب ضبط مستقیم | |
| with gr.TabItem("🎙️ ضبط مستقیم"): | |
| gr.Markdown("### میکروفون خود را فعال کرده و شروع به صحبت کنید") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| audio_input = gr.Audio( | |
| sources=["microphone"], | |
| type="numpy", | |
| streaming=True, | |
| label="میکروفون", | |
| show_label=True, | |
| elem_classes="rtl" | |
| ) | |
| with gr.Column(scale=1): | |
| clear_btn = gr.Button("🗑️ پاک کردن متن", variant="secondary", size="sm") | |
| realtime_output = gr.Textbox( | |
| label="متن تشخیص داده شده", | |
| placeholder="شروع به صحبت کنید و متن اینجا ظاهر میشود...", | |
| lines=12, | |
| elem_classes="rtl", | |
| rtl=True, | |
| show_copy_button=True | |
| ) | |
| # sentaitها | |
| audio_input.stream( | |
| lambda x: process_audio_chunk(x), | |
| inputs=[audio_input], | |
| outputs=[] | |
| ) | |
| audio_input.stream( | |
| lambda: update_realtime_transcript(), | |
| inputs=[], | |
| outputs=[realtime_output], | |
| every=0.5 | |
| ) | |
| clear_btn.click( | |
| lambda: "", | |
| outputs=[realtime_output] | |
| ) | |
| # تب فایل صوتی | |
| with gr.TabItem("📁 فایل صوتی"): | |
| gr.Markdown("### فایل صوتی خود را انتخاب کنید") | |
| with gr.Row(): | |
| with gr.Column(scale=3): | |
| file_input = gr.Audio( | |
| sources=["upload"], | |
| type="filepath", | |
| label="انتخاب فایل صوتی", | |
| elem_classes="rtl" | |
| ) | |
| with gr.Column(scale=1): | |
| chunk_duration = gr.Slider( | |
| minimum=10, | |
| maximum=60, | |
| value=30, | |
| step=5, | |
| label="مدت هر بخش (ثانیه)", | |
| elem_classes="rtl" | |
| ) | |
| with gr.Row(): | |
| process_btn = gr.Button("🚀 شروع تبدیل", variant="primary", size="lg") | |
| progress_label = gr.Textbox( | |
| label="وضعیت پردازش", | |
| interactive=False, | |
| elem_classes="rtl" | |
| ) | |
| file_output = gr.Textbox( | |
| label="متن تشخیص داده شده", | |
| placeholder="متن پس از پردازش اینجا نمایش داده میشود...", | |
| lines=12, | |
| elem_classes="rtl", | |
| rtl=True, | |
| show_copy_button=True | |
| ) | |
| def safe_transcribe_file(file, duration): | |
| """پردازش فایل صوتی با مدیریت خطا""" | |
| if file is None: | |
| return "لطفاً یک فایل صوتی آپلود کنید", "شروع پردازش" | |
| try: | |
| audio = AudioSegment.from_file(file) | |
| results = [] | |
| total_chunks = len(audio) // (duration * 1000) | |
| for i in range(0, len(audio), duration*1000): | |
| chunk = audio[i:i+duration*1000] | |
| text = process_audio_chunk(np.array(chunk.get_array_of_samples())) | |
| if text: | |
| results.append(text) | |
| progress = min(((i + duration*1000) / len(audio)) * 100, 100) | |
| yield " ".join(results), f"پیشرفت: {progress:.1f}%" | |
| return " ".join(results), "تکمیل پردازش ✅" | |
| except Exception as e: | |
| return f"خطا: {str(e)}", "خطا در پردازش ❌" | |
| process_btn.click( | |
| safe_transcribe_file, | |
| inputs=[file_input, chunk_duration], | |
| outputs=[file_output, progress_label] | |
| ) | |
| # بخش راهنما | |
| with gr.Accordion("📖 راهنمای استفاده", open=False, elem_classes="rtl"): | |
| gr.Markdown(""" | |
| ### نحوه استفاده: | |
| **برای ضبط مستقیم:** | |
| 1. به تب "ضبط مستقیم" بروید | |
| 2. اجازه دسترسی به میکروفون را بدهید | |
| 3. شروع به صحبت کنید | |
| 4. متن به صورت خودکار نمایش داده میشود | |
| **برای فایل صوتی:** | |
| 1. به تب "فایل صوتی" بروید | |
| 2. فایل مورد نظر را انتخاب کنید | |
| 3. مدت زمان تقسیمبندی را تنظیم کنید (پیشفرض: ۳۰ ثانیه) | |
| 4. روی "شروع تبدیل" کلیک کنید | |
| 5. منتظر بمانید تا پردازش کامل شود | |
| ### فرمتهای پشتیبانی شده: | |
| - MP3, WAV, M4A, FLAC, OGG, MP4, AVI, MOV | |
| ### نکات مهم: | |
| - 🎯 برای دقت بیشتر، از فایلهای با کیفیت بالا استفاده کنید | |
| - 🔇 نویز پسزمینه را به حداقل برسانید | |
| - 🗣️ واضح و شمرده صحبت کنید | |
| - 🌐 اتصال اینترنت پایدار داشته باشید | |
| """, elem_classes="rtl") | |
| # ساخت و اجرای برنامه | |
| if __name__ == "__main__": | |
| demo.queue().launch( | |
| share=True, | |
| show_error=True | |
| ) |