Spaces:
Running
on
Zero
Running
on
Zero
#testing webm hello hello | |
#okay why is webm taking that much bruh | |
#can someone actually help me please, i dont know whats wrong with the code but it just is so slow when using remover.process(img, type='rgba') | |
#but type=color is still fast (used by mp4) | |
import spaces | |
import gradio as gr | |
import cv2 | |
import numpy as np | |
import time | |
import random | |
from PIL import Image | |
import torch | |
import re | |
import os | |
import shutil | |
import subprocess | |
import tempfile | |
torch.jit.script = lambda f: f | |
from transparent_background import Remover | |
def doo(video, color, mode, out_format, progress=gr.Progress()): | |
print(str(color)) | |
if str(color).startswith('#'): | |
color = color.lstrip('#') | |
rgb = tuple(int(color[i:i+2], 16) for i in (0, 2, 4)) | |
color = str(list(rgb)) | |
elif str(color).startswith('rgba'): | |
rgba_match = re.match(r'rgba\(([\d.]+), ([\d.]+), ([\d.]+), [\d.]+\)', color) | |
if rgba_match: | |
r, g, b = rgba_match.groups() | |
color = str([int(float(r)), int(float(g)), int(float(b))]) | |
print("Parsed color:", color) | |
if mode == 'Fast': | |
remover = Remover(mode='fast') | |
else: | |
remover = Remover() | |
cap = cv2.VideoCapture(video) | |
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) | |
fps = cap.get(cv2.CAP_PROP_FPS) or 25.0 | |
writer = None | |
tmpname = random.randint(111111111, 999999999) | |
processed_frames = 0 | |
start_time = time.time() | |
mp4_path = str(tmpname) + '.mp4' | |
webm_path = str(tmpname) + '.webm' | |
if out_format == 'mp4': | |
while cap.isOpened(): | |
ret, frame = cap.read() | |
if ret is False: | |
break | |
if time.time() - start_time >= 20 * 60 - 5: | |
print("GPU Timeout is coming") | |
cap.release() | |
if writer is not None: | |
writer.release() | |
return mp4_path | |
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) | |
img = Image.fromarray(frame).convert('RGB') | |
if writer is None: | |
writer = cv2.VideoWriter(mp4_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, img.size) | |
processed_frames += 1 | |
print(f"Processing frame {processed_frames}") | |
progress(processed_frames / total_frames, desc=f"Processing frame {processed_frames}/{total_frames}") | |
out = remover.process(img, type=color) | |
frame_bgr = cv2.cvtColor(np.array(out), cv2.COLOR_RGB2BGR) | |
writer.write(frame_bgr) | |
cap.release() | |
if writer is not None: | |
writer.release() | |
return mp4_path | |
else: | |
temp_dir = tempfile.mkdtemp(prefix=f"tb_{tmpname}_") | |
try: | |
frame_idx = 0 | |
while cap.isOpened(): | |
ret, frame = cap.read() | |
if ret is False: | |
break | |
if time.time() - start_time >= 20 * 60 - 5: | |
print("GPU Timeout is coming") | |
cap.release() | |
# cleanup | |
shutil.rmtree(temp_dir, ignore_errors=True) | |
return webm_path | |
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) | |
img = Image.fromarray(frame).convert('RGB') | |
processed_frames += 1 | |
frame_idx += 1 | |
print(f"Processing frame {processed_frames}") | |
progress(processed_frames / total_frames, desc=f"Processing frame {processed_frames}/{total_frames}") | |
out = remover.process(img, type='rgba') #thing that makes the process go slow | |
out = out.convert('RGBA') | |
frame_name = os.path.join(temp_dir, f"frame_{frame_idx:06d}.png") | |
out.save(frame_name, 'PNG') | |
cap.release() | |
fr_str = str(int(round(fps))) if fps > 0 else "25" | |
pattern = os.path.join(temp_dir, "frame_%06d.png") | |
ffmpeg_cmd = [ | |
"ffmpeg", "-y", | |
"-framerate", fr_str, | |
"-i", pattern, | |
"-i", str(video), | |
"-map", "0:v", | |
"-map", "1:a?", | |
"-c:v", "libvpx-vp9", | |
"-pix_fmt", "yuva420p", | |
"-auto-alt-ref", "0", | |
"-metadata:s:v:0", "alpha_mode=1", | |
"-c:a", "libopus", | |
"-shortest", | |
webm_path | |
] | |
print("Running ffmpeg:", " ".join(ffmpeg_cmd)) | |
subprocess.run(ffmpeg_cmd, check=True) | |
shutil.rmtree(temp_dir, ignore_errors=True) | |
return webm_path | |
except subprocess.CalledProcessError as e: | |
print("ffmpeg failed:", e) | |
shutil.rmtree(temp_dir, ignore_errors=True) | |
return webm_path | |
except Exception as e: | |
print("Error during processing:", e) | |
shutil.rmtree(temp_dir, ignore_errors=True) | |
raise | |
title = "ποΈ Video Background Removal Tool π₯" | |
description = """*Please note that if your video file is long (has a high number of frames), there is a chance that processing break due to GPU timeout. In this case, consider trying Fast mode.*""" | |
examples = [ | |
['./input.mp4', '#00FF00', 'Normal', 'mp4'], | |
] | |
iface = gr.Interface( | |
fn=doo, | |
inputs=[ | |
"video", | |
gr.ColorPicker(label="Background color", value="#00FF00"), | |
gr.components.Radio(['Normal', 'Fast'], label='Select mode', value='Normal', info='Normal is more accurate, but takes longer. | Fast has lower accuracy so the process will be faster.'), | |
gr.components.Radio(['mp4', 'webm'], label='Output format', value='mp4') | |
], | |
outputs="video", | |
examples=examples, | |
title=title, | |
description=description | |
) | |
iface.launch() | |