File size: 8,128 Bytes
f79c89e
b0e29e7
36abef4
70d5a19
b0e29e7
d5f394e
 
f79c89e
36abef4
70d5a19
36abef4
d5f394e
f79c89e
 
 
d5f394e
b0e29e7
 
 
 
f79c89e
d5f394e
36abef4
 
 
 
d5f394e
 
70d5a19
 
36abef4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70d5a19
 
36abef4
 
d5f394e
36abef4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f79c89e
d5f394e
36abef4
d5f394e
f79c89e
b0e29e7
d5f394e
 
618c56b
d5f394e
36abef4
b0e29e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d5f394e
 
 
36abef4
 
70d5a19
36abef4
70d5a19
 
 
36abef4
 
 
 
 
 
 
70d5a19
36abef4
70d5a19
36abef4
 
70d5a19
36abef4
 
 
 
70d5a19
 
 
 
36abef4
 
 
 
f79c89e
 
 
 
36abef4
618c56b
36abef4
 
 
 
f4ac0b9
 
 
36abef4
f4ac0b9
f79c89e
 
 
 
 
36abef4
 
f79c89e
 
 
 
618c56b
f79c89e
 
618c56b
 
f4ac0b9
 
 
 
 
 
 
 
 
 
f79c89e
 
 
 
 
 
 
618c56b
70d5a19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36abef4
70d5a19
 
 
d5f394e
f79c89e
70d5a19
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
import os
import json
import asyncio
import tempfile
import requests
import gradio as gr
import whisper
import torch
import edge_tts
from pathlib import Path
from moviepy.editor import VideoFileClip

# تهيئة النماذج
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
whisper_model = whisper.load_model("base")

# مفتاح API لـ Gemini
GEMINI_API_KEY = "AIzaSyDrHCW4FxrDt6amCTQvYPTdh2NE06p9YlQ"
GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent"

# قاموس للغات المدعومة
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"}
}

# قاموس لأنواع الأصوات
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.endswith(('.mp4', '.avi', '.mov', '.mkv')):
            # إذا كان فيديو، استخرج الصوت منه
            audio_path = extract_audio_from_video(file_path)
        else:
            # إذا كان ملف صوتي، استخدمه مباشرة
            audio_path = file_path
        
        # تحويل الصوت إلى نص
        result = whisper_model.transcribe(audio_path, language=source_lang)
        
        # حذف الملف المؤقت إذا كان فيديو
        if file_path.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):
    """ترجمة النص باستخدام Gemini API"""
    if source_lang == target_lang:
        return text
    
    try:
        prompt = f"Translate the following text from {SUPPORTED_LANGUAGES[source_lang]['name']} to {SUPPORTED_LANGUAGES[target_lang]['name']}. Only provide the translation without any additional text or explanation:\n\n{text}"
        
        payload = {
            "contents": [{
                "parts": [{
                    "text": prompt
                }]
            }]
        }
        
        url = f"{GEMINI_API_URL}?key={GEMINI_API_KEY}"
        
        response = requests.post(
            url,
            headers={"Content-Type": "application/json"},
            json=payload
        )
        
        if response.status_code == 200:
            result = response.json()
            translated_text = result['candidates'][0]['content']['parts'][0]['text']
            return translated_text
        else:
            return f"خطأ في الترجمة: {response.status_code} - {response.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 "+50Hz" if voice_type == "امرأة" else "+100Hz"
        
        # إنشاء ملف صوتي مؤقت
        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("تحويل الوسائط إلى نص"):
        with gr.Row():
            media_input = gr.File(
                label="ملف صوتي أو فيديو",
                file_types=["audio/*", "video/*"]
            )
            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()