dream2589632147 commited on
Commit
d2d949b
·
verified ·
1 Parent(s): e4bf82a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -56
app.py CHANGED
@@ -1,4 +1,4 @@
1
- import spaces # <--- يجب أن يبقى في السطر الأول
2
  import gradio as gr
3
  import cv2
4
  import numpy as np
@@ -8,17 +8,16 @@ import shutil
8
  import tempfile
9
  import datetime
10
  import ffmpeg
11
- # استيراد مكتبات ModelScope الخاصة بـ DDColor
12
  from modelscope.pipelines import pipeline
13
  from modelscope.utils.constant import Tasks
 
 
14
 
15
  # ==========================================
16
- # 1. إعداد نموذج DDColor الاحترافي
17
  # ==========================================
18
  print("⏳ Loading DDColor Professional Model...")
19
 
20
- # تحميل خط الأنابيب (Pipeline) الخاص بالتلوين
21
- # نحدد device='gpu' ليعمل مع ZeroGPU عند استدعائه
22
  try:
23
  ddcolor_pipeline = pipeline(
24
  Tasks.image_colorization,
@@ -31,118 +30,118 @@ except Exception as e:
31
  ddcolor_pipeline = None
32
 
33
  # ==========================================
34
- # 2. دالة المعالجة (الاحترافية)
35
  # ==========================================
36
 
37
- @spaces.GPU(duration=180) # نمنح وقتاً كافياً للفيديوهات
38
  def colorize_video_professional(video_file):
39
  if not video_file:
40
- return None
41
 
42
  if ddcolor_pipeline is None:
43
- raise gr.Error("فشل تحميل النموذج. يرجى مراجعة السجلات.")
44
-
45
- print("🚀 Starting professional colorization on ZeroGPU...")
46
 
 
47
  timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
48
- temp_frames_dir = os.path.join(tempfile.gettempdir(), f"frames_dd_{timestamp}")
49
  os.makedirs(temp_frames_dir, exist_ok=True)
50
 
51
  final_output_name = f"colored_ddcolor_{timestamp}.mp4"
52
- audio_path = os.path.join(tempfile.gettempdir(), f"audio_dd_{timestamp}.aac")
 
 
 
 
 
53
 
54
- # --- 1. استخراج الصوت (إن وجد) ---
55
  audio_exists = False
56
  try:
57
- (
58
- ffmpeg
59
- .input(video_file)
60
- .output(audio_path, acodec='copy')
61
- .run(overwrite_output=True, quiet=True)
62
- )
63
  audio_exists = True
64
  except ffmpeg.Error:
65
- print("⚠️ Warning: No audio found or extraction failed.")
66
 
67
- # --- 2. قراءة الفيديو ومعالجة الإطارات ---
68
  cap = cv2.VideoCapture(video_file)
69
- fps = cap.get(cv2.CAP_PROP_FPS)
70
- if fps == 0: fps = 25
71
 
72
- frame_count = 0
73
- print("🎬 Processing frames...")
74
 
 
75
  while True:
76
  ret, frame = cap.read()
77
  if not ret:
78
  break
79
 
80
- # DDColor يقبل الصورة بصيغة BGR أو RGB (مصفوفة Numpy)
81
- # نقوم بتمرير الإطار مباشرة للنموذج
 
82
 
83
- # المعالجة باستخدام DDColor
84
- # الناتج يكون قاموساً يحتوي على الصورة الملونة تحت مفتاح 'output_img'
85
  result = ddcolor_pipeline(frame)
86
  colorized_frame_bgr = result['output_img']
87
 
88
- # حفظ الإطار كصورة PNG (لتجنب مشاكل ترميز الفيديو في OpenCV)
 
 
 
 
 
89
  frame_filename = os.path.join(temp_frames_dir, f"frame_{frame_count:05d}.png")
90
  cv2.imwrite(frame_filename, colorized_frame_bgr)
91
-
92
  frame_count += 1
93
- if frame_count % 10 == 0:
94
- print(f"Processed {frame_count} frames...")
95
 
96
  cap.release()
97
- print(f"✅ Finished processing {frame_count} frames. Stitching video...")
98
 
99
- # --- 3. تجميع الفيديو باستخدام FFmpeg ---
100
- # استخدام نمط %05d لقراءة الإطارات بالترتيب الصحيح
101
  input_frames = ffmpeg.input(os.path.join(temp_frames_dir, 'frame_%05d.png'), framerate=fps)
102
-
103
  if audio_exists:
104
- input_audio = ffmpeg.input(audio_path)
105
- # استخدام ترميز x264 لضمان التوافقية
106
- stream = ffmpeg.output(input_frames, input_audio, final_output_name, vcodec='libx264', pix_fmt='yuv420p', acodec='aac', shortest=None)
107
  else:
108
  stream = ffmpeg.output(input_frames, final_output_name, vcodec='libx264', pix_fmt='yuv420p')
109
 
110
  try:
111
  stream.run(overwrite_output=True, quiet=True)
112
- except ffmpeg.Error as e:
113
- print("FFmpeg Error:", e.stderr.decode('utf8'))
114
- # محاولة أخيرة بدون صوت في حال فشل الدمج
115
  ffmpeg.input(os.path.join(temp_frames_dir, 'frame_%05d.png'), framerate=fps).output(final_output_name, vcodec='libx264', pix_fmt='yuv420p').run(overwrite_output=True)
116
 
117
- # تنظيف
118
  shutil.rmtree(temp_frames_dir, ignore_errors=True)
119
- if os.path.exists(audio_path): os.remove(audio_path)
120
 
121
- return final_output_name
 
122
 
123
  # ==========================================
124
- # 3. واجهة التطبيق (بسيطة واحترافية)
125
  # ==========================================
126
  custom_css = """
127
- #col-container {max-width: 700px; margin-left: auto; margin-right: auto;}
128
  """
129
 
130
- with gr.Blocks(css=custom_css, title="Professional Video Colorizer (DDColor)") as demo:
131
  with gr.Column(elem_id="col-container"):
132
- gr.Markdown("# 🎞️ Professional Video Colorizer")
133
- gr.Markdown("تلوين احترافي وواقعي للفيديو باستخدام نموذج DDColor. يحافظ على التفاصيل الأصلية بدون تغيير.")
134
 
135
  with gr.Row():
136
  video_input = gr.Video(label="فيديو أبيض وأسود (Input)")
137
- video_output = gr.Video(label="الفيديو الملون (Output)")
138
 
139
- # لا توجد خيارات إضافية، فقط زر التلوين
140
- submit_btn = gr.Button("✨ بدء التلوين الاحترافي", variant="primary", size="lg")
 
 
 
 
 
 
141
 
142
  submit_btn.click(
143
  fn=colorize_video_professional,
144
  inputs=[video_input],
145
- outputs=video_output
146
  )
147
 
148
  if __name__ == "__main__":
 
1
+ import spaces
2
  import gradio as gr
3
  import cv2
4
  import numpy as np
 
8
  import tempfile
9
  import datetime
10
  import ffmpeg
 
11
  from modelscope.pipelines import pipeline
12
  from modelscope.utils.constant import Tasks
13
+ # استيراد مكتبة السلايدر الجديدة
14
+ from gradio_imageslider import ImageSlider
15
 
16
  # ==========================================
17
+ # 1. إعداد نموذج DDColor
18
  # ==========================================
19
  print("⏳ Loading DDColor Professional Model...")
20
 
 
 
21
  try:
22
  ddcolor_pipeline = pipeline(
23
  Tasks.image_colorization,
 
30
  ddcolor_pipeline = None
31
 
32
  # ==========================================
33
+ # 2. دالة المعالجة
34
  # ==========================================
35
 
36
+ @spaces.GPU(duration=180)
37
  def colorize_video_professional(video_file):
38
  if not video_file:
39
+ return None, None
40
 
41
  if ddcolor_pipeline is None:
42
+ raise gr.Error("فشل تحميل النموذج.")
 
 
43
 
44
+ print("🚀 Starting processing...")
45
  timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
46
+ temp_frames_dir = os.path.join(tempfile.gettempdir(), f"frames_{timestamp}")
47
  os.makedirs(temp_frames_dir, exist_ok=True)
48
 
49
  final_output_name = f"colored_ddcolor_{timestamp}.mp4"
50
+ audio_path = os.path.join(tempfile.gettempdir(), f"audio_{timestamp}.aac")
51
+
52
+ # مسارات صور المقارنة
53
+ comp_original_path = os.path.join(tempfile.gettempdir(), f"comp_orig_{timestamp}.png")
54
+ comp_colored_path = os.path.join(tempfile.gettempdir(), f"comp_color_{timestamp}.png")
55
+ comparison_result = None
56
 
57
+ # --- استخراج الصوت ---
58
  audio_exists = False
59
  try:
60
+ ffmpeg.input(video_file).output(audio_path, acodec='copy').run(overwrite_output=True, quiet=True)
 
 
 
 
 
61
  audio_exists = True
62
  except ffmpeg.Error:
63
+ pass
64
 
65
+ # --- المعالجة ---
66
  cap = cv2.VideoCapture(video_file)
67
+ fps = cap.get(cv2.CAP_PROP_FPS) or 25
68
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
69
 
70
+ # نختار إطاراً في المنتصف ليكون صورة المقارنة
71
+ comparison_frame_index = max(0, total_frames // 2)
72
 
73
+ frame_count = 0
74
  while True:
75
  ret, frame = cap.read()
76
  if not ret:
77
  break
78
 
79
+ # حفظ الإطار الأصلي للمقارنة إذا وصلنا للمنتصف
80
+ if frame_count == comparison_frame_index:
81
+ cv2.imwrite(comp_original_path, frame)
82
 
83
+ # التلوين
 
84
  result = ddcolor_pipeline(frame)
85
  colorized_frame_bgr = result['output_img']
86
 
87
+ # حفظ الإطار الملون للمقارنة
88
+ if frame_count == comparison_frame_index:
89
+ cv2.imwrite(comp_colored_path, colorized_frame_bgr)
90
+ comparison_result = (comp_original_path, comp_colored_path)
91
+
92
+ # حفظ الإطار للفيديو
93
  frame_filename = os.path.join(temp_frames_dir, f"frame_{frame_count:05d}.png")
94
  cv2.imwrite(frame_filename, colorized_frame_bgr)
 
95
  frame_count += 1
 
 
96
 
97
  cap.release()
 
98
 
99
+ # --- تجميع الفيديو ---
 
100
  input_frames = ffmpeg.input(os.path.join(temp_frames_dir, 'frame_%05d.png'), framerate=fps)
 
101
  if audio_exists:
102
+ stream = ffmpeg.output(input_frames, ffmpeg.input(audio_path), final_output_name, vcodec='libx264', pix_fmt='yuv420p', acodec='aac', shortest=None)
 
 
103
  else:
104
  stream = ffmpeg.output(input_frames, final_output_name, vcodec='libx264', pix_fmt='yuv420p')
105
 
106
  try:
107
  stream.run(overwrite_output=True, quiet=True)
108
+ except ffmpeg.Error:
109
+ # محاولة بديلة
 
110
  ffmpeg.input(os.path.join(temp_frames_dir, 'frame_%05d.png'), framerate=fps).output(final_output_name, vcodec='libx264', pix_fmt='yuv420p').run(overwrite_output=True)
111
 
 
112
  shutil.rmtree(temp_frames_dir, ignore_errors=True)
 
113
 
114
+ # نرجع الفيديو + صور المقارنة (Tuple)
115
+ return final_output_name, comparison_result
116
 
117
  # ==========================================
118
+ # 3. الواجهة الجديدة
119
  # ==========================================
120
  custom_css = """
121
+ #col-container {max-width: 800px; margin-left: auto; margin-right: auto;}
122
  """
123
 
124
+ with gr.Blocks(css=custom_css, title="Pro Video Colorizer") as demo:
125
  with gr.Column(elem_id="col-container"):
126
+ gr.Markdown("# 🎞️ Professional Video Colorizer (DDColor)")
127
+ gr.Markdown("قم برفع فيديو أبيض وأسود وسيقوم الذكاء الاصطناعي بتلوينه.")
128
 
129
  with gr.Row():
130
  video_input = gr.Video(label="فيديو أبيض وأسود (Input)")
 
131
 
132
+ submit_btn = gr.Button("✨ تلوين ومعاينة (Colorize)", variant="primary", size="lg")
133
+
134
+ # عنصر المقارنة الجديد
135
+ gr.Markdown("### 🔍 معاينة قبل وبعد (Before / After)")
136
+ slider_output = ImageSlider(label="مقارنة النتيجة", type="filepath", position=0.5)
137
+
138
+ gr.Markdown("### 🎥 الفيديو النهائي الملون")
139
+ video_output = gr.Video(label="النتيجة النهائية")
140
 
141
  submit_btn.click(
142
  fn=colorize_video_professional,
143
  inputs=[video_input],
144
+ outputs=[video_output, slider_output]
145
  )
146
 
147
  if __name__ == "__main__":