Spaces:
Running
on
T4
Running
on
T4
Update app.py
Browse files
app.py
CHANGED
|
@@ -151,46 +151,6 @@ async def log_faceswap_hit(token: str, status: str = "success"):
|
|
| 151 |
# --------------------- Face Swap Pipeline ---------------------
|
| 152 |
swap_lock = threading.Lock()
|
| 153 |
|
| 154 |
-
def swap_faces_on_video(source_img, video_file):
|
| 155 |
-
"""
|
| 156 |
-
source_img: numpy RGB image
|
| 157 |
-
video_file: path to uploaded video
|
| 158 |
-
Returns path to swapped video
|
| 159 |
-
"""
|
| 160 |
-
temp_dir = tempfile.mkdtemp(prefix="faceswap_video_")
|
| 161 |
-
input_path = video_file.name # Gradio gives a NamedTemporaryFile
|
| 162 |
-
output_path = os.path.join(temp_dir, f"swapped_{uuid.uuid4().hex}.mp4")
|
| 163 |
-
|
| 164 |
-
cap = cv2.VideoCapture(input_path)
|
| 165 |
-
fps = cap.get(cv2.CAP_PROP_FPS)
|
| 166 |
-
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 167 |
-
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 168 |
-
|
| 169 |
-
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
|
| 170 |
-
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
|
| 171 |
-
|
| 172 |
-
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
| 173 |
-
print(f"Processing {frame_count} frames...")
|
| 174 |
-
|
| 175 |
-
while True:
|
| 176 |
-
ret, frame = cap.read()
|
| 177 |
-
if not ret:
|
| 178 |
-
break
|
| 179 |
-
|
| 180 |
-
# Convert frame to RGB
|
| 181 |
-
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
| 182 |
-
|
| 183 |
-
# Apply existing functions
|
| 184 |
-
swapped_rgb = multi_face_swap(source_img, frame_rgb)
|
| 185 |
-
final_rgb = mandatory_enhancement(swapped_rgb)
|
| 186 |
-
|
| 187 |
-
# Convert back to BGR and write frame
|
| 188 |
-
out.write(cv2.cvtColor(final_rgb, cv2.COLOR_RGB2BGR))
|
| 189 |
-
|
| 190 |
-
cap.release()
|
| 191 |
-
out.release()
|
| 192 |
-
return
|
| 193 |
-
|
| 194 |
def enhance_image_with_codeformer(rgb_img, temp_dir=None):
|
| 195 |
if temp_dir is None:
|
| 196 |
temp_dir = os.path.join(tempfile.gettempdir(), f"enhance_{uuid.uuid4().hex[:8]}")
|
|
@@ -410,32 +370,7 @@ def build_multi_faceswap_gradio():
|
|
| 410 |
btn.click(process, [src, tgt], [out, error])
|
| 411 |
|
| 412 |
return demo
|
| 413 |
-
|
| 414 |
-
# ------------------- Gradio Interface -------------------
|
| 415 |
-
def build_video_faceswap_gradio():
|
| 416 |
-
with gr.Blocks() as demo:
|
| 417 |
-
gr.Markdown("## 🎬 Video Face Swap")
|
| 418 |
-
|
| 419 |
-
with gr.Row():
|
| 420 |
-
src = gr.Image(type="numpy", label="Source Face Image")
|
| 421 |
-
vid = gr.File(label="Target Video (.mp4)")
|
| 422 |
-
|
| 423 |
-
out = gr.Video(label="Swapped Video")
|
| 424 |
-
error = gr.Textbox(label="Logs", interactive=False)
|
| 425 |
-
|
| 426 |
-
def process(src_img, video_file):
|
| 427 |
-
try:
|
| 428 |
-
swapped_video = swap_faces_on_video(src_img, video_file)
|
| 429 |
-
return swapped_video, ""
|
| 430 |
-
except Exception as e:
|
| 431 |
-
return None, str(e)
|
| 432 |
-
|
| 433 |
-
btn = gr.Button("Swap Faces in Video")
|
| 434 |
-
btn.click(process, [src, vid], [out, error])
|
| 435 |
-
|
| 436 |
-
return demo
|
| 437 |
-
|
| 438 |
-
|
| 439 |
def mandatory_enhancement(rgb_img):
|
| 440 |
"""
|
| 441 |
Always runs CodeFormer on the final image.
|
|
@@ -910,19 +845,14 @@ async def multi_face_swap_api(
|
|
| 910 |
|
| 911 |
# --------------------- Mount Gradio ---------------------
|
| 912 |
|
| 913 |
-
|
| 914 |
-
# fastapi_app = mount_gradio_app(
|
| 915 |
-
# fastapi_app,
|
| 916 |
-
# multi_faceswap_app,
|
| 917 |
-
# path="/gradio-multi"
|
| 918 |
-
# )
|
| 919 |
-
video_faceswap_app = build_video_faceswap_gradio()
|
| 920 |
fastapi_app = mount_gradio_app(
|
| 921 |
fastapi_app,
|
| 922 |
-
|
| 923 |
-
path="/gradio-
|
| 924 |
)
|
| 925 |
|
| 926 |
|
|
|
|
| 927 |
if __name__ == "__main__":
|
| 928 |
uvicorn.run(fastapi_app, host="0.0.0.0", port=7860)
|
|
|
|
| 151 |
# --------------------- Face Swap Pipeline ---------------------
|
| 152 |
swap_lock = threading.Lock()
|
| 153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
def enhance_image_with_codeformer(rgb_img, temp_dir=None):
|
| 155 |
if temp_dir is None:
|
| 156 |
temp_dir = os.path.join(tempfile.gettempdir(), f"enhance_{uuid.uuid4().hex[:8]}")
|
|
|
|
| 370 |
btn.click(process, [src, tgt], [out, error])
|
| 371 |
|
| 372 |
return demo
|
| 373 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 374 |
def mandatory_enhancement(rgb_img):
|
| 375 |
"""
|
| 376 |
Always runs CodeFormer on the final image.
|
|
|
|
| 845 |
|
| 846 |
# --------------------- Mount Gradio ---------------------
|
| 847 |
|
| 848 |
+
multi_faceswap_app = build_multi_faceswap_gradio()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 849 |
fastapi_app = mount_gradio_app(
|
| 850 |
fastapi_app,
|
| 851 |
+
multi_faceswap_app,
|
| 852 |
+
path="/gradio-couple-faceswap"
|
| 853 |
)
|
| 854 |
|
| 855 |
|
| 856 |
+
|
| 857 |
if __name__ == "__main__":
|
| 858 |
uvicorn.run(fastapi_app, host="0.0.0.0", port=7860)
|