import os import asyncio import tempfile import gradio as gr import whisper import torch import edge_tts from pathlib import Path from moviepy.editor import VideoFileClip from transformers import MarianMTModel, MarianTokenizer # تهيئة النماذج DEVICE = "cuda" if torch.cuda.is_available() else "cpu" whisper_model = whisper.load_model("base") # قاموس للغات المدعومة SUPPORTED_LANGUAGES = { "ar": {"name": "العربية", "code": "ar-SA"}, "en": {"name": "English", "code": "en-US"}, "fr": {"name": "Français", "code": "fr-FR"}, "es": {"name": "Español", "code": "es-ES"} } # قاموس لنماذج الترجمة TRANSLATION_MODELS = { "ar-en": "Helsinki-NLP/opus-mt-ar-en", "en-ar": "Helsinki-NLP/opus-mt-en-ar", "fr-en": "Helsinki-NLP/opus-mt-fr-en", "en-fr": "Helsinki-NLP/opus-mt-en-fr", "es-en": "Helsinki-NLP/opus-mt-es-en", "en-es": "Helsinki-NLP/opus-mt-en-es" } # قاموس لأنواع الأصوات VOICE_TYPES = { "رجل": { "ar": "ar-SA-HamedNeural", "en": "en-US-ChristopherNeural", "fr": "fr-FR-HenriNeural", "es": "es-ES-AlvaroNeural" }, "امرأة": { "ar": "ar-SA-ZariyahNeural", "en": "en-US-JennyNeural", "fr": "fr-FR-DeniseNeural", "es": "es-ES-ElviraNeural" }, "طفل": { "ar": "ar-SA-ZariyahNeural", "en": "en-US-JennyNeural", "fr": "fr-FR-DeniseNeural", "es": "es-ES-ElviraNeural" } } def extract_audio_from_video(video_path): """استخراج الصوت من الفيديو""" try: video = VideoFileClip(video_path) temp_audio_path = tempfile.mktemp(suffix=".mp3") video.audio.write_audiofile(temp_audio_path, codec='mp3') video.close() return temp_audio_path except Exception as e: raise Exception(f"خطأ في استخراج الصوت من الفيديو: {str(e)}") def process_media_file(file_path, source_lang): """معالجة ملف الوسائط (صوت أو فيديو)""" try: if file_path is None: return "الرجاء تحميل ملف صوتي أو فيديو" # التحقق من نوع الملف if file_path.name.lower().endswith(('.mp4', '.avi', '.mov', '.mkv')): # إذا كان فيديو، استخرج الصوت منه audio_path = extract_audio_from_video(file_path.name) elif file_path.name.lower().endswith(('.mp3', '.wav', '.m4a')): # إذا كان ملف صوتي، استخدمه مباشرة audio_path = file_path.name else: return "نوع الملف غير مدعوم. الأنواع المدعومة هي: MP3, WAV, M4A, MP4, AVI, MOV, MKV" # تحويل الصوت إلى نص result = whisper_model.transcribe(audio_path, language=source_lang) # حذف الملف المؤقت إذا كان فيديو if file_path.name.lower().endswith(('.mp4', '.avi', '.mov', '.mkv')): os.remove(audio_path) return result["text"] except Exception as e: return f"خطأ في معالجة الملف: {str(e)}" def translate_text(text, source_lang, target_lang): """ترجمة النص باستخدام MarianMT""" if source_lang == target_lang: return text try: # إذا كانت اللغة المصدر ليست الإنجليزية، نترجم أولاً إلى الإنجليزية if source_lang != "en": model_name = TRANSLATION_MODELS[f"{source_lang}-en"] model = MarianMTModel.from_pretrained(model_name) tokenizer = MarianTokenizer.from_pretrained(model_name) inputs = tokenizer(text, return_tensors="pt", padding=True) translated = model.generate(**inputs) text = tokenizer.decode(translated[0], skip_special_tokens=True) # إذا كانت اللغة الهدف هي الإنجليزية، نتوقف هنا if target_lang == "en": return text # ترجمة من الإنجليزية إلى اللغة الهدف if target_lang != "en": model_name = TRANSLATION_MODELS[f"en-{target_lang}"] model = MarianMTModel.from_pretrained(model_name) tokenizer = MarianTokenizer.from_pretrained(model_name) inputs = tokenizer(text, return_tensors="pt", padding=True) translated = model.generate(**inputs) text = tokenizer.decode(translated[0], skip_special_tokens=True) return text except Exception as e: return f"خطأ في الترجمة: {str(e)}" async def text_to_speech(text, language, voice_type): """تحويل النص إلى صوت باستخدام Edge TTS""" try: # إنشاء مجلد مؤقت للملفات الصوتية temp_dir = Path("temp_audio") temp_dir.mkdir(exist_ok=True) # اختيار الصوت المناسب voice = VOICE_TYPES[voice_type][language] # تعديل السرعة والنبرة حسب نوع الصوت rate = "+0%" if voice_type != "طفل" else "+15%" pitch = "+0Hz" if voice_type == "رجل" else "+10Hz" if voice_type == "امرأة" else "+60Hz" # إنشاء ملف صوتي مؤقت output_file = temp_dir / f"output_{voice_type}_{language}.mp3" # تكوين كائن communicate communicate = edge_tts.Communicate(text, voice, rate=rate, pitch=pitch) # حفظ الملف الصوتي await communicate.save(str(output_file)) return str(output_file) except Exception as e: return f"خطأ في تحويل النص إلى صوت: {str(e)}" def text_to_speech_wrapper(text, language, voice_type): """wrapper function لتشغيل الدالة غير المتزامنة""" return asyncio.run(text_to_speech(text, language, voice_type)) # إنشاء واجهة Gradio with gr.Blocks(title="معالج الصوت والترجمة", theme=gr.themes.Soft()) as demo: gr.Markdown("# معالج الصوت والترجمة متعدد اللغات") with gr.Tab("تحويل الوسائط إلى نص"): gr.Markdown(""" ### الملفات المدعومة: - ملفات الصوت: MP3, WAV, M4A - ملفات الفيديو: MP4, AVI, MOV, MKV """) with gr.Row(): media_input = gr.File( label="ملف صوتي أو فيديو" ) source_lang = gr.Dropdown( choices=list(SUPPORTED_LANGUAGES.keys()), value="ar", label="لغة الملف" ) transcribe_btn = gr.Button("تحويل إلى نص") transcribed_text = gr.Textbox(label="النص المستخرج", lines=5) transcribe_btn.click( fn=process_media_file, inputs=[media_input, source_lang], outputs=transcribed_text ) with gr.Tab("ترجمة النص"): with gr.Row(): input_text = gr.Textbox(label="النص المراد ترجمته", lines=5) translated_text = gr.Textbox(label="النص المترجم", lines=5) with gr.Row(): trans_source_lang = gr.Dropdown( choices=list(SUPPORTED_LANGUAGES.keys()), value="ar", label="اللغة المصدر" ) trans_target_lang = gr.Dropdown( choices=list(SUPPORTED_LANGUAGES.keys()), value="en", label="اللغة الهدف" ) translate_btn = gr.Button("ترجمة") translate_btn.click( fn=translate_text, inputs=[input_text, trans_source_lang, trans_target_lang], outputs=translated_text ) with gr.Tab("تحويل النص إلى صوت"): with gr.Row(): tts_text = gr.Textbox(label="النص المراد تحويله إلى صوت", lines=5) tts_output = gr.Audio(label="الصوت الناتج") with gr.Row(): tts_lang = gr.Dropdown( choices=list(SUPPORTED_LANGUAGES.keys()), value="ar", label="لغة النص" ) voice_type = gr.Radio( choices=list(VOICE_TYPES.keys()), value="رجل", label="نوع الصوت" ) tts_btn = gr.Button("تحويل إلى صوت") tts_btn.click( fn=text_to_speech_wrapper, inputs=[tts_text, tts_lang, voice_type], outputs=tts_output ) # تشغيل التطبيق if __name__ == "__main__": demo.launch()