dream2589632147's picture
Update app.py
d2d949b verified
import spaces
import gradio as gr
import cv2
import numpy as np
from PIL import Image
import os
import shutil
import tempfile
import datetime
import ffmpeg
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
# استيراد مكتبة السلايدر الجديدة
from gradio_imageslider import ImageSlider
# ==========================================
# 1. إعداد نموذج DDColor
# ==========================================
print("⏳ Loading DDColor Professional Model...")
try:
ddcolor_pipeline = pipeline(
Tasks.image_colorization,
model='damo/cv_ddcolor_image-colorization',
device='gpu'
)
print("✅ DDColor Model loaded successfully.")
except Exception as e:
print(f"❌ Error loading DDColor model: {e}")
ddcolor_pipeline = None
# ==========================================
# 2. دالة المعالجة
# ==========================================
@spaces.GPU(duration=180)
def colorize_video_professional(video_file):
if not video_file:
return None, None
if ddcolor_pipeline is None:
raise gr.Error("فشل تحميل النموذج.")
print("🚀 Starting processing...")
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
temp_frames_dir = os.path.join(tempfile.gettempdir(), f"frames_{timestamp}")
os.makedirs(temp_frames_dir, exist_ok=True)
final_output_name = f"colored_ddcolor_{timestamp}.mp4"
audio_path = os.path.join(tempfile.gettempdir(), f"audio_{timestamp}.aac")
# مسارات صور المقارنة
comp_original_path = os.path.join(tempfile.gettempdir(), f"comp_orig_{timestamp}.png")
comp_colored_path = os.path.join(tempfile.gettempdir(), f"comp_color_{timestamp}.png")
comparison_result = None
# --- استخراج الصوت ---
audio_exists = False
try:
ffmpeg.input(video_file).output(audio_path, acodec='copy').run(overwrite_output=True, quiet=True)
audio_exists = True
except ffmpeg.Error:
pass
# --- المعالجة ---
cap = cv2.VideoCapture(video_file)
fps = cap.get(cv2.CAP_PROP_FPS) or 25
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# نختار إطاراً في المنتصف ليكون صورة المقارنة
comparison_frame_index = max(0, total_frames // 2)
frame_count = 0
while True:
ret, frame = cap.read()
if not ret:
break
# حفظ الإطار الأصلي للمقارنة إذا وصلنا للمنتصف
if frame_count == comparison_frame_index:
cv2.imwrite(comp_original_path, frame)
# التلوين
result = ddcolor_pipeline(frame)
colorized_frame_bgr = result['output_img']
# حفظ الإطار الملون للمقارنة
if frame_count == comparison_frame_index:
cv2.imwrite(comp_colored_path, colorized_frame_bgr)
comparison_result = (comp_original_path, comp_colored_path)
# حفظ الإطار للفيديو
frame_filename = os.path.join(temp_frames_dir, f"frame_{frame_count:05d}.png")
cv2.imwrite(frame_filename, colorized_frame_bgr)
frame_count += 1
cap.release()
# --- تجميع الفيديو ---
input_frames = ffmpeg.input(os.path.join(temp_frames_dir, 'frame_%05d.png'), framerate=fps)
if audio_exists:
stream = ffmpeg.output(input_frames, ffmpeg.input(audio_path), final_output_name, vcodec='libx264', pix_fmt='yuv420p', acodec='aac', shortest=None)
else:
stream = ffmpeg.output(input_frames, final_output_name, vcodec='libx264', pix_fmt='yuv420p')
try:
stream.run(overwrite_output=True, quiet=True)
except ffmpeg.Error:
# محاولة بديلة
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)
shutil.rmtree(temp_frames_dir, ignore_errors=True)
# نرجع الفيديو + صور المقارنة (Tuple)
return final_output_name, comparison_result
# ==========================================
# 3. الواجهة الجديدة
# ==========================================
custom_css = """
#col-container {max-width: 800px; margin-left: auto; margin-right: auto;}
"""
with gr.Blocks(css=custom_css, title="Pro Video Colorizer") as demo:
with gr.Column(elem_id="col-container"):
gr.Markdown("# 🎞️ Professional Video Colorizer (DDColor)")
gr.Markdown("قم برفع فيديو أبيض وأسود وسيقوم الذكاء الاصطناعي بتلوينه.")
with gr.Row():
video_input = gr.Video(label="فيديو أبيض وأسود (Input)")
submit_btn = gr.Button("✨ تلوين ومعاينة (Colorize)", variant="primary", size="lg")
# عنصر المقارنة الجديد
gr.Markdown("### 🔍 معاينة قبل وبعد (Before / After)")
slider_output = ImageSlider(label="مقارنة النتيجة", type="filepath", position=0.5)
gr.Markdown("### 🎥 الفيديو النهائي الملون")
video_output = gr.Video(label="النتيجة النهائية")
submit_btn.click(
fn=colorize_video_professional,
inputs=[video_input],
outputs=[video_output, slider_output]
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)