import gradio as gr import torch from transformers import pipeline, AutoModelForSeq2SeqLM, AutoTokenizer from moviepy.video.io.VideoFileClip import VideoFileClip import librosa import soundfile as sf import numpy as np import re from gtts import gTTS from langdetect import detect import os # ====================== # 1. الإعدادات الأساسية # ====================== device = "cuda" if torch.cuda.is_available() else "cpu" # ====================== # 2. تحميل النماذج # ====================== pipe = pipeline("automatic-speech-recognition", model="openai/whisper-medium", device=0 if device == "cuda" else -1) bart_model = AutoModelForSeq2SeqLM.from_pretrained("ahmedabdo/arabic-summarizer-bart") bart_tokenizer = AutoTokenizer.from_pretrained("ahmedabdo/arabic-summarizer-bart") # تحميل نموذج الإجابة بالعربية qa_model_name = "ZeyadAhmed/AraElectra-Arabic-SQuADv2-QA" qa_pipeline = pipeline("question-answering", model=qa_model_name, tokenizer=qa_model_name, device=0 if device == "cuda" else -1) # ====================== # 3. التخصيصات # ====================== PRIMARY_COLOR = "#2A4D6E" # اللون الكحلي EXAMPLE_AUDIO_PATH = "_ما_هو_الذكاء_الإصطناعي_؟_فِهموجرافيك_١.m4a" # ====================== # 4. الدوال المساعدة # ====================== def clean_text_advanced(text): """تنظيف النص مع الحفاظ على الهيكل الأساسي""" text = re.sub(r'\b\d+[.)]\s*', '', text) # إزالة الترقيم الرقمي text = re.sub(r'[ـ\-_*#@&]', ' ', text) # إزالة الرموز الخاصة text = re.sub(r'\s+', ' ', text).strip() # تقليل الفراغات return text def prepare_context(text, max_length=1024): """تحضير السياق مع الحفاظ على الجمل الكاملة""" cleaned = clean_text_advanced(text) sentences = [s.strip() for s in cleaned.split('.') if s.strip()] selected = [] total_len = 0 for sentence in reversed(sentences): if total_len + len(sentence.split()) > max_length: break selected.append(sentence) total_len += len(sentence.split()) return '. '.join(reversed(selected)) def convert_audio_to_text(uploaded_file): try: if not uploaded_file: return "⛔ الرجاء رفع ملف أولاً" input_path = uploaded_file if isinstance(uploaded_file, str) else uploaded_file.name output_path = "/tmp/processed.wav" # معالجة ملفات الفيديو if input_path.split('.')[-1].lower() in ['mp4', 'avi', 'mov', 'mkv']: video = VideoFileClip(input_path) if video.audio: video.audio.write_audiofile(output_path, codec='pcm_s16le') else: return "⛔ لا يوجد صوت في الفيديو!" else: output_path = input_path audio, rate = librosa.load(output_path, sr=16000) transcripts = [] # تقسيم الصوت إلى مقاطع للتعامل مع الملفات الكبيرة for start in np.arange(0, len(audio)/rate, 30): end = min(start + 30, len(audio)/rate) segment = audio[int(start*rate):int(end*rate)] sf.write(f"/tmp/segment_{int(start)}.wav", segment, rate) transcripts.append(pipe(f"/tmp/segment_{int(start)}.wav")["text"]) return " ".join(transcripts) except Exception as e: return f"⛔ خطأ: {str(e)}" def process_example_audio(): try: if not os.path.exists(EXAMPLE_AUDIO_PATH): return "⛔ الملف التجريبي غير موجود" return convert_audio_to_text(EXAMPLE_AUDIO_PATH) except Exception as e: return f"⛔ خطأ في معالجة المثال: {str(e)}" def summarize_text(text): cleaned_text = clean_text_advanced(text) inputs = bart_tokenizer(cleaned_text, return_tensors="pt", max_length=1024, truncation=True).to(device) summary_ids = bart_model.generate( inputs.input_ids, max_length=150, num_beams=4, early_stopping=True ) return bart_tokenizer.decode(summary_ids[0], skip_special_tokens=True) def answer_question(text, question): if not question.strip() or not text.strip(): return "⛔️ الرجاء إدخال النص والسؤال بشكل صحيح" # تقسيم النص إلى شرائح صغيرة بحيث لا تزيد كل شريحة عن 256 كلمة words = text.split() chunk_size = 256 segments = [" ".join(words[i:i+chunk_size]) for i in range(0, len(words), chunk_size)] best_answer = None best_score = -1 # تطبيق نموذج الإجابة على كل شريحة واختيار الإجابة ذات أعلى score for seg in segments: result = qa_pipeline({'question': question, 'context': seg}) if result['score'] > best_score: best_score = result['score'] best_answer = result['answer'] return best_answer def text_to_speech(text): if not text.strip(): return None try: tts = gTTS(text=text, lang='ar' if detect(text) == 'ar' else 'en', slow=False) output = "/tmp/tts.wav" tts.save(output) return output except Exception as e: return f"⛔ خطأ في توليد الصوت: {str(e)}" # ====================== # 5. واجهة المستخدم (التصميم المحسّن) # ====================== with gr.Blocks(css=f""" .gradio-container {{ background: #f8f9fa; font-family: 'Noto Sans Arabic', sans-serif; }} .header-section {{ background: {PRIMARY_COLOR}; padding: 2rem; border-radius: 10px; color: white; text-align: center; margin-bottom: 2rem; }} .tab-buttons {{ border-bottom: 3px solid {PRIMARY_COLOR} !important; }} .tab-buttons button {{ color: {PRIMARY_COLOR} !important; background: #f8f9fa !important; transition: all 0.3s !important; }} .tab-buttons button.selected {{ border-top: 3px solid {PRIMARY_COLOR} !important; background: rgba(42, 77, 110, 0.1) !important; }} .custom-button {{ background: {PRIMARY_COLOR} !important; color: white !important; border-radius: 8px; padding: 12px 25px; margin: 5px; }} .custom-button:hover {{ transform: translateY(-2px); box-shadow: 0 5px 15px rgba(42, 77, 110, 0.3); }} audio {{ width: 100%; margin: 1rem 0; }} """) as demo: gr.Markdown("""
منصة الذكاء الاصطناعي المتكاملة لفهم المحتوى المرئي والسمعي