dream2589632147 commited on
Commit
cecbfad
·
verified ·
1 Parent(s): 8fd1ad8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -79
app.py CHANGED
@@ -6,24 +6,23 @@ from PIL import Image
6
  from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, DDIMScheduler
7
  from controlnet_aux import CannyDetector
8
  from diffusers.utils import load_image
9
- from moviepy.editor import VideoFileClip
10
  import os
11
  import shutil
12
  import tempfile
13
  import datetime
 
14
 
15
  # 1. تهيئة النموذج
16
- # تحديد جهاز التشغيل (GPU إذا كان متاحًا)
17
  device = "cuda" if torch.cuda.is_available() else "cpu"
18
  torch_dtype = torch.float16 if device == "cuda" else torch.float32
19
 
20
  try:
21
  print(f"Loading models on: {device}...")
22
- # تحميل ControlNet (نموذج Canny)
23
  controlnet_model = ControlNetModel.from_pretrained(
24
  "lllyasviel/sd-controlnet-canny", torch_dtype=torch_dtype
25
  )
26
- # تحميل الـ Pipeline الرئيسية
27
  model_id = "runwayml/stable-diffusion-v1-5"
28
  pipe = StableDiffusionControlNetPipeline.from_pretrained(
29
  model_id, controlnet=controlnet_model, torch_dtype=torch_dtype
@@ -33,100 +32,106 @@ try:
33
  print("Models loaded successfully.")
34
  except Exception as e:
35
  print(f"Error loading models on CUDA: {e}. Switching to CPU.")
36
- # محاولة التحميل على CPU إذا فشل CUDA
37
  controlnet_model = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-canny")
38
  pipe = StableDiffusionControlNetPipeline.from_pretrained(model_id, controlnet=controlnet_model)
39
  pipe.to("cpu")
40
 
41
- # تهيئة مُعالِج Canny
42
  canny_processor = CannyDetector()
43
 
44
-
45
  # 2. دالة معالجة الفيديو والنموذج
46
  def colorize_video_multistyle(video_file, reference_image_path, prompt, style_choice, steps=25):
47
 
48
- # 0. إنشاء اسم ملف فريد للناتج
49
  timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
 
50
  final_output_name = f"colored_output_{timestamp}.mp4"
51
 
52
- # استخدام مجلد مؤقت لضمان التنظيف
53
- with tempfile.TemporaryDirectory() as temp_dir:
54
-
55
- # 1. استخراج الإطارات والصوت
56
- clip = VideoFileClip(video_file)
57
- audio_file = None
58
- if clip.audio:
59
- audio_file = os.path.join(temp_dir, "temp_audio.mp3")
60
- clip.audio.write_audiofile(audio_file, verbose=False, logger=None)
 
 
 
 
 
 
 
61
 
62
- fps = clip.fps
63
-
64
- # 2. تجهيز المدخلات للنموذج
65
- style_prompts = {
66
- "Auto Color": "photorealistic color photo, cinematic, detailed, masterpiece",
67
- "Vivid": "highly saturated, vibrant color photo, pop art colors",
68
- "Vintage": "sepia tone, old film grain, 1940s vintage look",
69
- }
70
- final_prompt = f"{prompt}, {style_prompts.get(style_choice, '')}"
71
- negative_prompt = "lowres, bad anatomy, bad hands, blurry, distorted, nsfw, frame, border, changed details, monochrome"
72
-
73
- # تجهيز الصورة المرجعية (إذا تم تحميل IP-Adapter)
74
- # ip_adapter_images = []
75
- # if reference_image_path:
76
- # ref_image = load_image(reference_image_path).convert("RGB")
77
- # ip_adapter_images.append(ref_image)
78
- # pipe.set_ip_adapter_images(ip_adapter_images)
79
-
80
- colored_frames = []
81
-
82
- # 3. معالجة الإطارات (التلوين باستخدام ControlNet)
83
- for i, frame in enumerate(clip.iter_frames(fps=fps, dtype='uint8')):
84
-
85
- pil_image = Image.fromarray(frame).convert("RGB")
86
-
87
- # استخراج خريطة Canny للحفاظ على الهيكل
88
- canny_image = canny_processor(pil_image)
89
-
90
- # تمرير خريطة Canny للنموذج
91
- image_out = pipe(
92
- prompt=final_prompt,
93
- negative_prompt=negative_prompt,
94
- image=canny_image, # ControlNet Canny Input
95
- num_inference_steps=steps,
96
- guidance_scale=7.5
97
- ).images[0]
98
 
99
- colored_frames.append(np.array(image_out))
100
-
101
- # 4. تجميع الإطارات في فيديو مؤقت (AVI)
102
- # نستخدم ترميز MJPG و AVI كملف مؤقت لموثوقية OpenCV
103
- output_video_path = os.path.join(temp_dir, "colored_temp_video.avi")
104
- height, width, layers = colored_frames[0].shape
105
 
106
- # MJPG هو ترميز موثوق به في بيئات Linux/Docker مع OpenCV
107
- fourcc = cv2.VideoWriter_fourcc(*'MJPG')
108
- out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))
 
 
 
 
109
 
110
- for frame in colored_frames:
111
- out.write(cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
112
-
113
- out.release()
 
 
 
 
 
 
 
114
 
115
- # 5. إضافة الصوت الأصلي وإعادة الترميز لـ MP4 باستخدام MoviePy
116
- if audio_file and os.path.exists(audio_file):
117
- video_clip = VideoFileClip(output_video_path)
118
- final_clip = video_clip.set_audio(clip.audio)
119
- # MoviePy تتولى إنشاء MP4 النهائي بترميمز libx264 الموثوق
120
- final_clip.write_videofile(final_output_name, codec='libx264', audio_codec='aac', verbose=False, logger=None)
121
- else:
122
- shutil.copy(output_video_path, final_output_name)
123
-
124
- clip.close()
 
 
 
 
 
 
125
 
126
- return final_output_name
127
-
 
 
 
128
 
129
- # 3. واجهة Gradio النهائية
130
  iface = gr.Interface(
131
  fn=colorize_video_multistyle,
132
  inputs=[
 
6
  from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, DDIMScheduler
7
  from controlnet_aux import CannyDetector
8
  from diffusers.utils import load_image
9
+ # تم إزالة: from moviepy.editor import VideoFileClip
10
  import os
11
  import shutil
12
  import tempfile
13
  import datetime
14
+ import ffmpeg # المكتبة الجديدة
15
 
16
  # 1. تهيئة النموذج
17
+ # ... (كود التهيئة يبقى كما هو)
18
  device = "cuda" if torch.cuda.is_available() else "cpu"
19
  torch_dtype = torch.float16 if device == "cuda" else torch.float32
20
 
21
  try:
22
  print(f"Loading models on: {device}...")
 
23
  controlnet_model = ControlNetModel.from_pretrained(
24
  "lllyasviel/sd-controlnet-canny", torch_dtype=torch_dtype
25
  )
 
26
  model_id = "runwayml/stable-diffusion-v1-5"
27
  pipe = StableDiffusionControlNetPipeline.from_pretrained(
28
  model_id, controlnet=controlnet_model, torch_dtype=torch_dtype
 
32
  print("Models loaded successfully.")
33
  except Exception as e:
34
  print(f"Error loading models on CUDA: {e}. Switching to CPU.")
 
35
  controlnet_model = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-canny")
36
  pipe = StableDiffusionControlNetPipeline.from_pretrained(model_id, controlnet=controlnet_model)
37
  pipe.to("cpu")
38
 
 
39
  canny_processor = CannyDetector()
40
 
 
41
  # 2. دالة معالجة الفيديو والنموذج
42
  def colorize_video_multistyle(video_file, reference_image_path, prompt, style_choice, steps=25):
43
 
 
44
  timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
45
+ output_temp_video_no_audio = os.path.join(tempfile.gettempdir(), f"temp_colored_{timestamp}_no_audio.mp4")
46
  final_output_name = f"colored_output_{timestamp}.mp4"
47
 
48
+ # === 1. استخراج الإطارات و الصوت (باستخدام FFMPEG مباشرةً عبر OpenCV) ===
49
+ # نستخدم FFMPEG-Python لاستخراج مسار ملف الصوت المؤقت
50
+
51
+ # 1.1 استخراج الصوت
52
+ audio_path = os.path.join(tempfile.gettempdir(), f"temp_audio_{timestamp}.aac")
53
+ try:
54
+ (
55
+ ffmpeg
56
+ .input(video_file)
57
+ .output(audio_path, acodec='copy')
58
+ .run(overwrite_output=True, quiet=True)
59
+ )
60
+ audio_exists = True
61
+ except ffmpeg.Error:
62
+ audio_exists = False
63
+ print("No audio found or extraction failed. Proceeding without audio.")
64
 
65
+ # 1.2 قراءة الفيديو للإطارات
66
+ cap = cv2.VideoCapture(video_file)
67
+ fps = cap.get(cv2.CAP_PROP_FPS)
68
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
69
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
70
+
71
+ # 2. تجهيز المدخلات للنموذج (كود الأنماط يبقى كما هو)
72
+ style_prompts = {
73
+ "Auto Color": "photorealistic color photo, cinematic, detailed, masterpiece",
74
+ "Vivid": "highly saturated, vibrant color photo, pop art colors",
75
+ "Vintage": "sepia tone, old film grain, 1940s vintage look",
76
+ }
77
+ final_prompt = f"{prompt}, {style_prompts.get(style_choice, '')}"
78
+ negative_prompt = "lowres, bad anatomy, bad hands, blurry, distorted, nsfw, frame, border, changed details, monochrome"
79
+
80
+ colored_frames = []
81
+
82
+ # 3. معالجة الإطارات (التلوين)
83
+ while cap.isOpened():
84
+ ret, frame = cap.read()
85
+ if not ret:
86
+ break
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
+ pil_image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
89
+ canny_image = canny_processor(pil_image)
 
 
 
 
90
 
91
+ image_out = pipe(
92
+ prompt=final_prompt,
93
+ negative_prompt=negative_prompt,
94
+ image=canny_image,
95
+ num_inference_steps=steps,
96
+ guidance_scale=7.5
97
+ ).images[0]
98
 
99
+ colored_frames.append(np.array(image_out))
100
+
101
+ cap.release()
102
+
103
+ # 4. تجميع الإطارات في فيديو مؤقت (MP4) باستخدام OpenCV
104
+ # نستخدم MP4V-2 لتجنب الاعتماد على الترميز الخارجي
105
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
106
+ out = cv2.VideoWriter(output_temp_video_no_audio, fourcc, fps, (width, height))
107
+
108
+ for frame in colored_frames:
109
+ out.write(cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
110
 
111
+ out.release()
112
+
113
+ # 5. دمج الفيديو الملون مع الصوت الأصلي باستخدام FFMPEG-Python
114
+ if audio_exists:
115
+ try:
116
+ (
117
+ ffmpeg
118
+ .input(output_temp_video_no_audio)
119
+ .output(ffmpeg.input(audio_path).audio, final_output_name, vcodec='copy', acodec='copy')
120
+ .run(overwrite_output=True, quiet=True)
121
+ )
122
+ except ffmpeg.Error as e:
123
+ print(f"FFMPEG merge failed: {e.stderr.decode('utf8')}")
124
+ shutil.copy(output_temp_video_no_audio, final_output_name) # العودة إلى الفيديو بدون صوت
125
+ else:
126
+ shutil.copy(output_temp_video_no_audio, final_output_name)
127
 
128
+ # 6. تنظيف الملفات المؤقتة
129
+ if os.path.exists(audio_path):
130
+ os.remove(audio_path)
131
+
132
+ return final_output_name
133
 
134
+ # 3. واجهة Gradio النهائية (بدون تغيير)
135
  iface = gr.Interface(
136
  fn=colorize_video_multistyle,
137
  inputs=[