naicoi commited on
Commit
daa6da0
·
1 Parent(s): 2d6af56
Files changed (2) hide show
  1. app.py +28 -3
  2. processing.py +41 -31
app.py CHANGED
@@ -97,15 +97,40 @@ with gr.Blocks() as demo:
97
  with gr.Column():
98
  gr.HTML("""
99
  <div>
100
- <span style="font-size: 20px;">🎬 Output Video</span><br>
101
  </div>
102
  """)
103
- video_output = gr.Video(label="Output", height=512)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  lipsync_only_btn.click(
106
  fn=lipsync_with_audio_target,
107
  inputs=[video_input, audio_input, session_state, crop_size_radio],
108
- outputs=[video_output],
 
 
 
 
 
 
109
  )
110
 
111
 
 
97
  with gr.Column():
98
  gr.HTML("""
99
  <div>
100
+ <span style="font-size: 20px;">🎬 Final Output Video</span><br>
101
  </div>
102
  """)
103
+ final_video = gr.Video(label="Final Output", height=512)
104
+
105
+ gr.HTML("<h3>Processing Steps</h3>")
106
+ with gr.Row():
107
+ with gr.Column():
108
+ gr.HTML('<p style="margin: 0; color: #666;">1. Original (Looped)</p>')
109
+ video_looped_output = gr.Video(label="Original Video", height=256)
110
+ with gr.Column():
111
+ gr.HTML('<p style="margin: 0; color: #666;">2. Face Cropped</p>')
112
+ face_cropped_output = gr.Video(label="Face Cropped", height=256)
113
+ with gr.Column():
114
+ gr.HTML('<p style="margin: 0; color: #666;">3. Lipsynced Face</p>')
115
+ lipsynced_face_output = gr.Video(label="Lipsynced Face", height=256)
116
+
117
+ with gr.Row():
118
+ with gr.Column():
119
+ gr.HTML(
120
+ '<p style="margin: 0; color: #666;">4. Lipsynced Full (Blended)</p>'
121
+ )
122
+ lipsynced_full_output = gr.Video(label="Lipsynced Full", height=256)
123
 
124
  lipsync_only_btn.click(
125
  fn=lipsync_with_audio_target,
126
  inputs=[video_input, audio_input, session_state, crop_size_radio],
127
+ outputs=[
128
+ final_video,
129
+ video_looped_output,
130
+ face_cropped_output,
131
+ lipsynced_face_output,
132
+ lipsynced_full_output,
133
+ ],
134
  )
135
 
136
 
processing.py CHANGED
@@ -50,6 +50,39 @@ def get_memory_usage():
50
  return f"RAM: {ram_used_gb:.2f}GB / {ram.total / (1024**3):.2f}GB ({ram_percent:.1f}%){gpu_info}"
51
 
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  @spaces.GPU
54
  def process_lipsync_with_audio_target(
55
  video_file,
@@ -68,33 +101,15 @@ def process_lipsync_with_audio_target(
68
  progress: Progress tracking object
69
 
70
  Returns:
71
- final_video_path
72
  """
73
  try:
74
- if video_file is None:
75
- raise gr.Error("Please upload a video source.")
76
- if audio_file is None:
77
- raise gr.Error("Please upload a target audio.")
78
 
79
  output_dir = setup_output_dir(session_id)
80
 
81
  logger.info(f"Memory at start: {get_memory_usage()}")
82
 
83
- if isinstance(video_file, dict):
84
- video_path = video_file.get("name") or video_file.get("path")
85
- else:
86
- video_path = video_file
87
-
88
- if isinstance(audio_file, dict):
89
- audio_path = audio_file.get("name") or audio_file.get("path")
90
- else:
91
- audio_path = audio_file
92
-
93
- if video_path is None or not os.path.exists(video_path):
94
- raise gr.Error("Could not read uploaded video file.")
95
- if audio_path is None or not os.path.exists(audio_path):
96
- raise gr.Error("Could not read uploaded audio file.")
97
-
98
  audio_duration = get_audio_duration(audio_path)
99
 
100
  progress(0.1, desc="🎬 Đang chuẩn bị video...")
@@ -158,15 +173,6 @@ def process_lipsync_with_audio_target(
158
  gc.collect()
159
  logger.info(f"Memory after lipsync: {get_memory_usage()}")
160
 
161
- progress(0.8, desc="🔀 Đang ghép video...")
162
- with timer("Blending face into original"):
163
- lipsynced_full = blend_face_into_original(
164
- video_looped, lipsynced_face, face_bbox, output_dir
165
- )
166
-
167
- gc.collect()
168
- logger.info(f"Memory after lipsync: {get_memory_usage()}")
169
-
170
  progress(0.8, desc="🔀 Đang ghép video...")
171
  with timer("Blending face into original"):
172
  lipsynced_full = blend_face_into_original(
@@ -182,7 +188,7 @@ def process_lipsync_with_audio_target(
182
  progress(1.0, desc="✅ Hoàn tất!")
183
  logger.info(f"Memory at end: {get_memory_usage()}")
184
 
185
- return final_video
186
 
187
  except Exception as e:
188
  print(f"ERROR in process_lipsync_with_audio_target: {e}")
@@ -197,7 +203,11 @@ def lipsync_with_audio_target(
197
  crop_size=256,
198
  progress=gr.Progress(track_tqdm=True),
199
  ):
200
- """Wrapper for Gradio: Lipsync video source with audio target (English only)"""
 
 
 
 
201
  if video_file is None:
202
  raise gr.Error("Please upload a video source.")
203
  if audio_file is None:
 
50
  return f"RAM: {ram_used_gb:.2f}GB / {ram.total / (1024**3):.2f}GB ({ram_percent:.1f}%){gpu_info}"
51
 
52
 
53
+ def validate_input(video_file, audio_file):
54
+ """Validate input files
55
+
56
+ Args:
57
+ video_file: Video input
58
+ audio_file: Audio input
59
+
60
+ Returns:
61
+ Tuple of (video_path, audio_path)
62
+ """
63
+ if video_file is None:
64
+ raise gr.Error("Please upload a video source.")
65
+ if audio_file is None:
66
+ raise gr.Error("Please upload a target audio.")
67
+
68
+ if isinstance(video_file, dict):
69
+ video_path = video_file.get("name") or video_file.get("path")
70
+ else:
71
+ video_path = video_file
72
+
73
+ if isinstance(audio_file, dict):
74
+ audio_path = audio_file.get("name") or audio_file.get("path")
75
+ else:
76
+ audio_path = audio_file
77
+
78
+ if video_path is None or not os.path.exists(video_path):
79
+ raise gr.Error("Could not read uploaded video file.")
80
+ if audio_path is None or not os.path.exists(audio_path):
81
+ raise gr.Error("Could not read uploaded audio file.")
82
+
83
+ return video_path, audio_path
84
+
85
+
86
  @spaces.GPU
87
  def process_lipsync_with_audio_target(
88
  video_file,
 
101
  progress: Progress tracking object
102
 
103
  Returns:
104
+ Tuple of (final_video, video_looped, face_cropped, lipsynced_face, lipsynced_full)
105
  """
106
  try:
107
+ video_path, audio_path = validate_input(video_file, audio_file)
 
 
 
108
 
109
  output_dir = setup_output_dir(session_id)
110
 
111
  logger.info(f"Memory at start: {get_memory_usage()}")
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  audio_duration = get_audio_duration(audio_path)
114
 
115
  progress(0.1, desc="🎬 Đang chuẩn bị video...")
 
173
  gc.collect()
174
  logger.info(f"Memory after lipsync: {get_memory_usage()}")
175
 
 
 
 
 
 
 
 
 
 
176
  progress(0.8, desc="🔀 Đang ghép video...")
177
  with timer("Blending face into original"):
178
  lipsynced_full = blend_face_into_original(
 
188
  progress(1.0, desc="✅ Hoàn tất!")
189
  logger.info(f"Memory at end: {get_memory_usage()}")
190
 
191
+ return final_video, video_looped, face_cropped, lipsynced_face, lipsynced_full
192
 
193
  except Exception as e:
194
  print(f"ERROR in process_lipsync_with_audio_target: {e}")
 
203
  crop_size=256,
204
  progress=gr.Progress(track_tqdm=True),
205
  ):
206
+ """Wrapper for Gradio: Lipsync video source with audio target (English only)
207
+
208
+ Returns:
209
+ Tuple of (final_video, video_looped, face_cropped, lipsynced_face, lipsynced_full)
210
+ """
211
  if video_file is None:
212
  raise gr.Error("Please upload a video source.")
213
  if audio_file is None: