KIMOSSINO commited on
Commit
de3e3a5
·
verified ·
1 Parent(s): 1efaf54

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +244 -0
app.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import whisper
3
+ import os
4
+ import moviepy.editor as mp
5
+ from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqGeneration
6
+ from tqdm import tqdm
7
+
8
+ # تهيئة النماذج
9
+ print("جاري تحميل نموذج Whisper...")
10
+ whisper_model = whisper.load_model("base")
11
+
12
+ # قائمة اللغات المدعومة
13
+ SUPPORTED_LANGUAGES = {
14
+ 'ar': 'العربية',
15
+ 'en': 'English',
16
+ 'fr': 'Français',
17
+ 'es': 'Español',
18
+ 'de': 'Deutsch',
19
+ 'it': 'Italiano',
20
+ 'pt': 'Português',
21
+ 'ru': 'Русский',
22
+ 'zh': '中文',
23
+ 'ja': '日本語'
24
+ }
25
+
26
+ # تهيئة نماذج الترجمة
27
+ translation_models = {}
28
+
29
+ def load_translation_model(source_lang, target_lang):
30
+ """تحميل نموذج الترجمة عند الحاجة"""
31
+ key = f'{source_lang}2{target_lang}'
32
+ if key not in translation_models:
33
+ model_name = f'Helsinki-NLP/opus-mt-{source_lang}-{target_lang}'
34
+ try:
35
+ translation_models[key] = pipeline('translation', model=model_name)
36
+ except:
37
+ # إذا لم يتوفر نموذج مباشر، نستخدم الإنجليزية كلغة وسيطة
38
+ if source_lang != 'en':
39
+ source_to_en = pipeline('translation',
40
+ model=f'Helsinki-NLP/opus-mt-{source_lang}-en')
41
+ translation_models[f'{source_lang}2en'] = source_to_en
42
+ if target_lang != 'en':
43
+ en_to_target = pipeline('translation',
44
+ model=f'Helsinki-NLP/opus-mt-en-{target_lang}')
45
+ translation_models[f'en2{target_lang}'] = en_to_target
46
+
47
+ def translate_text(text, source_lang, target_lang):
48
+ """ترجمة النص مع دعم الترجمة عبر الإنجليزية كلغة وسيطة"""
49
+ if source_lang == target_lang:
50
+ return text
51
+
52
+ try:
53
+ # محاولة الترجمة المباشرة
54
+ key = f'{source_lang}2{target_lang}'
55
+ if key not in translation_models:
56
+ load_translation_model(source_lang, target_lang)
57
+
58
+ if key in translation_models:
59
+ return translation_models[key](text)[0]['translation_text']
60
+
61
+ # الترجمة عبر الإنجليزية كلغة وسيطة
62
+ if source_lang != 'en':
63
+ text = translation_models[f'{source_lang}2en'](text)[0]['translation_text']
64
+ if target_lang != 'en':
65
+ text = translation_models[f'en2{target_lang}'](text)[0]['translation_text']
66
+ return text
67
+ except Exception as e:
68
+ return f"خطأ في الترجمة: {str(e)}"
69
+
70
+ def process_video(video_path, source_lang, target_lang=None):
71
+ """معالجة الفيديو واستخراج النص وترجمته"""
72
+ try:
73
+ # استخراج الصوت
74
+ video = mp.VideoFileClip(video_path)
75
+ audio_path = video_path.rsplit('.', 1)[0] + '.mp3'
76
+ video.audio.write_audiofile(audio_path, verbose=False)
77
+ video.close()
78
+
79
+ # استخراج النص
80
+ print(f"جاري تحويل الصوت إلى نص باللغة {source_lang}...")
81
+ result = whisper_model.transcribe(audio_path, language=source_lang)
82
+
83
+ # تنظيف
84
+ os.remove(audio_path)
85
+
86
+ transcribed_text = result["text"]
87
+ translated_text = None
88
+
89
+ # ترجمة النص
90
+ if target_lang and target_lang != source_lang:
91
+ print(f"جاري الترجمة من {source_lang} إلى {target_lang}...")
92
+ translated_text = translate_text(transcribed_text, source_lang, target_lang)
93
+
94
+ return {
95
+ "original_text": transcribed_text,
96
+ "translated_text": translated_text,
97
+ "segments": result["segments"]
98
+ }
99
+ except Exception as e:
100
+ return {
101
+ "error": str(e),
102
+ "original_text": "",
103
+ "translated_text": "",
104
+ "segments": []
105
+ }
106
+
107
+ def format_time(seconds):
108
+ """تنسيق الوقت بشكل مقروء"""
109
+ hours = int(seconds // 3600)
110
+ minutes = int((seconds % 3600) // 60)
111
+ seconds = seconds % 60
112
+ if hours > 0:
113
+ return f"{hours:02d}:{minutes:02d}:{seconds:05.2f}"
114
+ return f"{minutes:02d}:{seconds:05.2f}"
115
+
116
+ def create_html_output(result, source_lang, target_lang):
117
+ """إنشاء مخرجات HTML منسقة"""
118
+ html = f"""
119
+ <div style='font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto;'>
120
+ <div style='background: #f5f5f5; padding: 20px; border-radius: 8px; margin-bottom: 20px;'>
121
+ <h3 style='color: #2c3e50; margin-top: 0;'>النص الأصلي ({SUPPORTED_LANGUAGES.get(source_lang, source_lang)})</h3>
122
+ <p style='white-space: pre-wrap; color: #34495e;'>{result['original_text']}</p>
123
+ </div>
124
+ """
125
+
126
+ if result.get('translated_text'):
127
+ html += f"""
128
+ <div style='background: #f5f5f5; padding: 20px; border-radius: 8px; margin-bottom: 20px;'>
129
+ <h3 style='color: #2c3e50; margin-top: 0;'>الترجمة ({SUPPORTED_LANGUAGES.get(target_lang, target_lang)})</h3>
130
+ <p style='white-space: pre-wrap; color: #34495e;'>{result['translated_text']}</p>
131
+ </div>
132
+ """
133
+
134
+ html += """
135
+ <div style='background: #f5f5f5; padding: 20px; border-radius: 8px;'>
136
+ <h3 style='color: #2c3e50; margin-top: 0;'>النص مع التوقيت</h3>
137
+ <div style='max-height: 300px; overflow-y: auto;'>
138
+ """
139
+
140
+ for segment in result['segments']:
141
+ start_time = format_time(segment['start'])
142
+ end_time = format_time(segment['end'])
143
+ html += f"""
144
+ <div style='margin-bottom: 10px; padding: 10px; background: white; border-radius: 4px;'>
145
+ <span style='color: #7f8c8d; font-size: 0.9em;'>[{start_time} → {end_time}]</span>
146
+ <p style='margin: 5px 0 0 0; color: #34495e;'>{segment['text']}</p>
147
+ </div>
148
+ """
149
+
150
+ html += """
151
+ </div>
152
+ </div>
153
+ </div>
154
+ """
155
+
156
+ return html
157
+
158
+ def gradio_interface(video, source_lang, target_lang):
159
+ """واجهة المستخدم الرئيسية"""
160
+ if video is None:
161
+ return "الرجاء رفع ملف فيديو"
162
+
163
+ temp_path = "temp_video.mp4"
164
+ try:
165
+ with open(temp_path, "wb") as f:
166
+ f.write(video)
167
+
168
+ result = process_video(temp_path, source_lang, target_lang)
169
+
170
+ if "error" in result:
171
+ return f"حدث خطأ: {result['error']}"
172
+
173
+ return create_html_output(result, source_lang, target_lang)
174
+ except Exception as e:
175
+ return f"حدث خطأ: {str(e)}"
176
+ finally:
177
+ if os.path.exists(temp_path):
178
+ os.remove(temp_path)
179
+
180
+ # تكوين الواجهة
181
+ css = """
182
+ .gradio-container {
183
+ font-family: 'Arial', sans-serif;
184
+ }
185
+ .output-html {
186
+ max-height: 600px;
187
+ overflow-y: auto;
188
+ }
189
+ """
190
+
191
+ # إنشاء واجهة Gradio
192
+ interface = gr.Interface(
193
+ fn=gradio_interface,
194
+ inputs=[
195
+ gr.File(
196
+ label="رفع فيديو",
197
+ file_types=["video"],
198
+ type="binary"
199
+ ),
200
+ gr.Dropdown(
201
+ choices=list(SUPPORTED_LANGUAGES.keys()),
202
+ value="en",
203
+ label="لغة الفيديو الأصلية",
204
+ info="اختر لغة الفيديو الأصلية"
205
+ ),
206
+ gr.Dropdown(
207
+ choices=list(SUPPORTED_LANGUAGES.keys()),
208
+ value="ar",
209
+ label="لغة الترجمة",
210
+ info="اختر اللغة التي تريد الترجمة إليها"
211
+ )
212
+ ],
213
+ outputs=gr.HTML(
214
+ label="النتيجة",
215
+ elem_classes=["output-html"]
216
+ ),
217
+ title="منصة تحويل الفيديو إلى نص مع الترجمة",
218
+ description="""
219
+ منصة متقدمة لتحويل الفيديو إلى نص مع دعم الترجمة بين العديد من اللغات.
220
+
221
+ اللغات المدعومة:
222
+ - العربية (ar)
223
+ - الإنجليزية (en)
224
+ - الفرنسية (fr)
225
+ - الإسبانية (es)
226
+ - الألمانية (de)
227
+ - الإيطالية (it)
228
+ - البرتغالية (pt)
229
+ - الروسية (ru)
230
+ - الصينية (zh)
231
+ - اليابانية (ja)
232
+
233
+ ملاحظات:
234
+ - الحد الأقصى لحجم الفيديو: 100 ميجابايت
235
+ - يمكن أن تستغرق المعالجة بضع دقائق حسب طول الفيديو
236
+ """,
237
+ css=css,
238
+ examples=[],
239
+ cache_examples=False
240
+ )
241
+
242
+ # تشغيل التطبيق
243
+ if __name__ == "__main__":
244
+ interface.launch()