Mirko Trasciatti
commited on
Commit
·
5a8e5bf
1
Parent(s):
996c8dd
Add logging + imageio fallback for API render
Browse files
app.py
CHANGED
|
@@ -3402,7 +3402,7 @@ def process_video_api(
|
|
| 3402 |
|
| 3403 |
# Step 8: Render the final video
|
| 3404 |
log_msg(f"Rendering video (remove_background={remove_background})")
|
| 3405 |
-
result_video_path = _render_video(api_state, remove_background)
|
| 3406 |
|
| 3407 |
log_msg("Processing complete 🎉")
|
| 3408 |
return preview_img, result_video_path, "\n".join(log_entries)
|
|
@@ -4732,7 +4732,7 @@ with gr.Blocks(title="SAM2 Video (Transformers) - Interactive Segmentation", the
|
|
| 4732 |
# Playback via MP4 rendering only
|
| 4733 |
|
| 4734 |
# Render a smooth MP4 using imageio/pyav (fallbacks to imageio v2 / OpenCV)
|
| 4735 |
-
def _render_video(s: AppState, remove_bg: bool = False):
|
| 4736 |
if s is None or s.num_frames == 0:
|
| 4737 |
raise gr.Error("Load a video first.")
|
| 4738 |
fps = s.video_fps if s.video_fps and s.video_fps > 0 else 12
|
|
@@ -4756,6 +4756,7 @@ with gr.Blocks(title="SAM2 Video (Transformers) - Interactive Segmentation", the
|
|
| 4756 |
frames_np = []
|
| 4757 |
first = compose_frame(s, start_idx, remove_bg=remove_bg)
|
| 4758 |
h, w = first.size[1], first.size[0]
|
|
|
|
| 4759 |
for idx in range(start_idx, end_idx):
|
| 4760 |
# Don't use cache when remove_bg changes behavior
|
| 4761 |
if remove_bg:
|
|
@@ -4769,18 +4770,39 @@ with gr.Blocks(title="SAM2 Video (Transformers) - Interactive Segmentation", the
|
|
| 4769 |
# Periodically release CPU mem to reduce pressure
|
| 4770 |
if (idx + 1) % 60 == 0:
|
| 4771 |
gc.collect()
|
| 4772 |
-
|
| 4773 |
-
|
| 4774 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4775 |
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
|
| 4776 |
writer = cv2.VideoWriter(out_path, fourcc, fps, (w, h))
|
|
|
|
|
|
|
|
|
|
| 4777 |
for fr_bgr in frames_np:
|
| 4778 |
writer.write(fr_bgr)
|
| 4779 |
writer.release()
|
| 4780 |
-
|
| 4781 |
-
|
| 4782 |
-
|
| 4783 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4784 |
|
| 4785 |
render_btn.click(_render_video, inputs=[GLOBAL_STATE, remove_bg_checkbox], outputs=[playback_video])
|
| 4786 |
|
|
|
|
| 3402 |
|
| 3403 |
# Step 8: Render the final video
|
| 3404 |
log_msg(f"Rendering video (remove_background={remove_background})")
|
| 3405 |
+
result_video_path = _render_video(api_state, remove_background, log_fn=log_msg)
|
| 3406 |
|
| 3407 |
log_msg("Processing complete 🎉")
|
| 3408 |
return preview_img, result_video_path, "\n".join(log_entries)
|
|
|
|
| 4732 |
# Playback via MP4 rendering only
|
| 4733 |
|
| 4734 |
# Render a smooth MP4 using imageio/pyav (fallbacks to imageio v2 / OpenCV)
|
| 4735 |
+
def _render_video(s: AppState, remove_bg: bool = False, log_fn=None):
|
| 4736 |
if s is None or s.num_frames == 0:
|
| 4737 |
raise gr.Error("Load a video first.")
|
| 4738 |
fps = s.video_fps if s.video_fps and s.video_fps > 0 else 12
|
|
|
|
| 4756 |
frames_np = []
|
| 4757 |
first = compose_frame(s, start_idx, remove_bg=remove_bg)
|
| 4758 |
h, w = first.size[1], first.size[0]
|
| 4759 |
+
total_frames = max(1, end_idx - start_idx)
|
| 4760 |
for idx in range(start_idx, end_idx):
|
| 4761 |
# Don't use cache when remove_bg changes behavior
|
| 4762 |
if remove_bg:
|
|
|
|
| 4770 |
# Periodically release CPU mem to reduce pressure
|
| 4771 |
if (idx + 1) % 60 == 0:
|
| 4772 |
gc.collect()
|
| 4773 |
+
processed = idx - start_idx + 1
|
| 4774 |
+
if log_fn and (processed % 20 == 0 or processed == total_frames):
|
| 4775 |
+
log_fn(f"Rendering frames {processed}/{total_frames}")
|
| 4776 |
+
import tempfile
|
| 4777 |
+
out_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
|
| 4778 |
+
out_path = out_file.name
|
| 4779 |
+
out_file.close()
|
| 4780 |
+
def _write_with_opencv():
|
| 4781 |
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
|
| 4782 |
writer = cv2.VideoWriter(out_path, fourcc, fps, (w, h))
|
| 4783 |
+
if not writer.isOpened():
|
| 4784 |
+
writer.release()
|
| 4785 |
+
raise RuntimeError("OpenCV VideoWriter failed to open (missing codec?).")
|
| 4786 |
for fr_bgr in frames_np:
|
| 4787 |
writer.write(fr_bgr)
|
| 4788 |
writer.release()
|
| 4789 |
+
def _write_with_imageio():
|
| 4790 |
+
import imageio
|
| 4791 |
+
with imageio.get_writer(out_path, fps=fps, codec="libx264", mode="I", quality=8) as writer:
|
| 4792 |
+
for fr_bgr in frames_np:
|
| 4793 |
+
writer.append_data(fr_bgr[:, :, ::-1]) # convert back to RGB
|
| 4794 |
+
try:
|
| 4795 |
+
_write_with_opencv()
|
| 4796 |
+
except Exception as cv_err:
|
| 4797 |
+
print(f"OpenCV writer failed: {cv_err}")
|
| 4798 |
+
try:
|
| 4799 |
+
if log_fn:
|
| 4800 |
+
log_fn("OpenCV writer unavailable, falling back to imageio/pyav.")
|
| 4801 |
+
_write_with_imageio()
|
| 4802 |
+
except Exception as io_err:
|
| 4803 |
+
print(f"Failed to render video: {io_err}")
|
| 4804 |
+
raise gr.Error(f"Failed to render video: {io_err}")
|
| 4805 |
+
return out_path
|
| 4806 |
|
| 4807 |
render_btn.click(_render_video, inputs=[GLOBAL_STATE, remove_bg_checkbox], outputs=[playback_video])
|
| 4808 |
|