Spaces:
Sleeping
Sleeping
File size: 7,411 Bytes
db1e44f fa7bb31 3661e51 5e20b77 fa7bb31 3661e51 5e20b77 fa7bb31 57d8c78 625e33f c5c002d 625e33f 0c44bc5 625e33f fa7bb31 0c44bc5 5e20b77 625e33f 3661e51 625e33f 3661e51 625e33f 3661e51 625e33f 0c44bc5 625e33f 0c44bc5 3661e51 625e33f 3661e51 625e33f 3661e51 625e33f 3661e51 625e33f 3661e51 625e33f fa7bb31 594f284 fa7bb31 6e25931 625e33f 6e25931 3661e51 625e33f 6e25931 625e33f 3661e51 594f284 3661e51 625e33f 3661e51 625e33f 6e25931 594f284 6e25931 3661e51 6e25931 5e20b77 594f284 625e33f 594f284 625e33f 594f284 625e33f c5c002d b110f2d c5c002d ad7a29e 625e33f 0c44bc5 625e33f 594f284 625e33f 5e20b77 625e33f c5c002d 625e33f 594f284 |
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 |
import gradio as gr
import whisper
from moviepy.editor import VideoFileClip, AudioFileClip, ImageClip, CompositeVideoClip
import tempfile
import os
from pathlib import Path
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import arabic_reshaper
from bidi.algorithm import get_display
from pydub import AudioSegment
# تحميل نموذج Whisper
model = whisper.load_model("base") # نموذج أفضل للغة العربية
# تحديد الخطوط المتاحة
FONTS = {
"الخط المثنى": "fonts/Al-Mothnna.ttf",
"خط بين": "fonts/bein-normal.ttf"
}
def prepare_arabic_text(text):
"""تحضير النص العربي للعرض بشكل صحيح"""
try:
reshaped_text = arabic_reshaper.reshape(text)
bidi_text = get_display(reshaped_text)
return bidi_text
except Exception as e:
print(f"خطأ في معالجة النص العربي: {str(e)}")
return text
def create_text_image(text, font_name, size=(720, 480), font_size=30):
"""إنشاء صورة تحتوي على نص"""
# إنشاء صورة جديدة مع خلفية سوداء
img = Image.new('RGB', size, 'black')
draw = ImageDraw.Draw(img)
# تحميل الخط المحدد
try:
font_path = FONTS[font_name]
if not os.path.exists(font_path):
raise FileNotFoundError(f"الخط غير موجود: {font_path}")
font = ImageFont.truetype(font_path, font_size)
except Exception as e:
print(f"خطأ في تحميل الخط: {str(e)}")
# استخدام الخط الافتراضي في حالة الفشل
font = ImageFont.load_default()
# تحضير النص العربي
prepared_text = prepare_arabic_text(text)
# حساب موقع النص في وسط الصورة
text_bbox = draw.textbbox((0, 0), prepared_text, font=font)
text_width = text_bbox[2] - text_bbox[0]
text_height = text_bbox[3] - text_bbox[1]
x = (size[0] - text_width) // 2
y = (size[1] - text_height) // 2
# رسم النص
draw.text((x, y), prepared_text, font=font, fill='white')
return np.array(img)
def convert_audio_to_wav(audio_path):
"""تحويل الملف الصوتي إلى صيغة WAV"""
audio_path = Path(audio_path)
if audio_path.suffix.lower() != '.wav':
wav_path = audio_path.with_suffix('.wav')
audio = AudioSegment.from_file(str(audio_path))
audio.export(str(wav_path), format='wav')
return str(wav_path)
return str(audio_path)
def create_video_with_text(audio_path, transcription, font_name, video_size):
"""إنشاء فيديو مع نص متزامن"""
try:
# تحويل الملف الصوتي إلى WAV
wav_path = convert_audio_to_wav(audio_path)
# تحميل الملف الصوتي
audio_clip = AudioFileClip(wav_path)
duration = audio_clip.duration
# تقسيم النص إلى أجزاء
words = transcription.split()
total_frames = int(duration * 24) # 24 FPS
words_per_frame = max(1, len(words) // total_frames)
# إنشاء قائمة المقاطع
clips = []
current_time = 0
frame_duration = duration / (len(words) / words_per_frame)
for i in range(0, len(words), words_per_frame):
# تجميع الكلمات لهذا الإطار
frame_words = ' '.join(words[i:i + words_per_frame])
# إنشاء صورة للنص
text_image = create_text_image(frame_words, font_name, size=video_size)
# تحويل الصورة إلى مقطع
text_clip = ImageClip(text_image).set_duration(frame_duration)
# إضافة المقطع مع توقيته
clips.append(text_clip.set_start(current_time))
current_time += frame_duration
if not clips:
raise ValueError("لم يتم إنشاء أي مقاطع")
# دمج جميع المقاطع
video = CompositeVideoClip(clips, size=video_size)
video = video.set_audio(audio_clip)
# حفظ الفيديو
temp_output = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4')
video_path = temp_output.name
video.write_videofile(
video_path,
fps=24,
codec='libx264',
audio_codec='aac',
verbose=False
)
return video_path
except Exception as e:
print(f"خطأ في create_video_with_text: {str(e)}")
raise
def process_audio(audio_path, selected_font, video_orientation):
"""معالجة الملف الصوتي وإنشاء الفيديو"""
try:
if not isinstance(audio_path, str):
raise ValueError("يجب أن يكون المدخل مسار ملف صوتي")
if not os.path.exists(audio_path):
raise FileNotFoundError("الملف غير موجود")
# تحويل الصوت إلى نص
print("جاري تحويل الصوت إلى نص...")
result = model.transcribe(audio_path, language="ar") # تحديد اللغة العربية
transcription = result["text"]
print("تم استخراج النص بنجاح")
# تحديد حجم الفيديو بناءً على الاختيار
video_size = (1280, 720) if video_orientation == 'أفقي' else (720, 1280)
# إنشاء الفيديو
print("جاري إنشاء الفيديو...")
video_path = create_video_with_text(audio_path, transcription, selected_font, video_size)
print("تم إنشاء الفيديو بنجاح")
return video_path, transcription
except Exception as e:
print(f"خطأ في process_audio: {str(e)}")
return None, f"حدث خطأ أثناء المعالجة: {str(e)}"
# إنشاء واجهة Gradio
iface = gr.Interface(
fn=process_audio,
inputs=[
gr.Audio(type="filepath", label="قم بتحميل ملف صوتي (MP3 أو WAV)"),
gr.Dropdown(
choices=list(FONTS.keys()),
value=list(FONTS.keys())[0],
label="اختر الخط"
),
gr.Dropdown(
choices=["أفقي", "عمودي"],
value="أفقي",
label="اختيار اتجاه الفيديو"
)
],
outputs=[
gr.Video(label="الفيديو المنشأ"),
gr.Textbox(label="النص المستخرج")
],
title="محول الصوت إلى فيديو مع النص",
description="قم بتحميل ملف صوتي لإنشاء فيديو مع نص متزامن باللغة العربية.",
)
if __name__ == "__main__":
# التحقق من وجود مجلد الخطوط
if not os.path.exists("fonts"):
print("تحذير: مجلد الخطوط غير موجود")
os.makedirs("fonts")
# التحقق من وجود الخطوط
for font_name, font_path in FONTS.items():
if not os.path.exists(font_path):
print(f"تحذير: الخط {font_name} غير موجود في {font_path}")
iface.launch()
|