Mirko Trasciatti commited on
Commit
5a8e5bf
·
1 Parent(s): 996c8dd

Add logging + imageio fallback for API render

Browse files
Files changed (1) hide show
  1. app.py +31 -9
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
- out_path = "/tmp/sam2_playback.mp4"
4773
- # Prefer imageio with PyAV/ffmpeg to respect exact fps
4774
- try:
 
 
 
 
 
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
- return out_path
4781
- except Exception as e:
4782
- print(f"Failed to render video with cv2: {e}")
4783
- raise gr.Error(f"Failed to render video: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
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