qhillerich commited on
Commit
df6230b
·
verified ·
1 Parent(s): 634ed26

Update handler.py

Browse files
Files changed (1) hide show
  1. handler.py +17 -17
handler.py CHANGED
@@ -5,11 +5,11 @@ Outputs: GIF, WebM, ZIP(frames)
5
  This version includes:
6
  - Defensive patches to avoid hosted runtime failing with:
7
  "`ffmpeg` is not a registered plugin name."
8
- - Robust frame extraction for shapes like (T,H,W,C) and (B,T,H,W,C)
9
  - Output encoders:
10
  - GIF: Pillow only (no ffmpeg)
11
  - ZIP: PNG frames zipped (no ffmpeg)
12
- - WebM: imageio + imageio-ffmpeg (absolute ffmpeg path)
13
 
14
  IMPORTANT:
15
  - HF gateway often requires top-level { "inputs": {...} }.
@@ -87,7 +87,7 @@ def _patch_hf_toolkit_ffmpeg_plugin() -> dict:
87
  except Exception as e:
88
  diag["details"].append(f"failed wrapping {fn_name}: {e}")
89
 
90
- # Some runtimes may import a module path for plugins; provide dummy module.
91
  dummy_mod_name = "huggingface_inference_toolkit.plugins.ffmpeg"
92
  if dummy_mod_name not in sys.modules:
93
  dummy = types.ModuleType(dummy_mod_name)
@@ -119,7 +119,7 @@ import imageio
119
  try:
120
  import imageio_ffmpeg # type: ignore
121
  _FFMPEG_EXE = imageio_ffmpeg.get_ffmpeg_exe()
122
- # Force absolute path; some runtimes intercept plain "ffmpeg"
123
  os.environ["IMAGEIO_FFMPEG_EXE"] = _FFMPEG_EXE
124
  except Exception:
125
  _FFMPEG_EXE = ""
@@ -145,7 +145,7 @@ def _clamp_uint8_frame(frame: np.ndarray) -> np.ndarray:
145
  if not isinstance(frame, np.ndarray):
146
  frame = np.array(frame)
147
 
148
- # squeeze batch dim
149
  if frame.ndim == 4 and frame.shape[0] == 1:
150
  frame = frame[0]
151
 
@@ -199,7 +199,11 @@ def _encode_gif(frames: List[np.ndarray], fps: int) -> bytes:
199
 
200
  def _encode_webm(frames: List[np.ndarray], fps: int, quality: str = "good") -> bytes:
201
  """
202
- Encode WebM (VP9) via imageio. Requires ffmpeg through imageio-ffmpeg.
 
 
 
 
203
  """
204
  if not frames:
205
  raise ValueError("No frames to encode WebM.")
@@ -223,7 +227,6 @@ def _encode_webm(frames: List[np.ndarray], fps: int, quality: str = "good") -> b
223
  out_path,
224
  fps=max(1, fps),
225
  format="FFMPEG",
226
- executable=_FFMPEG_EXE if _FFMPEG_EXE else None,
227
  codec="libvpx-vp9",
228
  ffmpeg_params=[
229
  "-pix_fmt", "yuv420p",
@@ -344,7 +347,7 @@ class EndpointHandler:
344
  self.pipe = None
345
  self.init_error: Optional[str] = None
346
 
347
- print("=== CUSTOM handler.py LOADED (updated frames shape handling) ===", flush=True)
348
  print(f"=== HF toolkit patch diag: {HF_TOOLKIT_PATCH_DIAG} ===", flush=True)
349
  print(f"=== imageio-ffmpeg exe: {_FFMPEG_EXE} ===", flush=True)
350
 
@@ -488,24 +491,21 @@ class EndpointHandler:
488
 
489
  frames: List[np.ndarray] = []
490
 
491
- # 1) output.frames — can be list or ndarray/tensor-like
492
  if hasattr(output, "frames") and getattr(output, "frames") is not None:
493
  frames_raw = getattr(output, "frames")
494
  arr = np.array(frames_raw)
495
 
496
- # Common: (T, H, W, C)
497
  if arr.ndim == 4:
498
  frames = [arr[t] for t in range(arr.shape[0])]
499
-
500
- # Sometimes: (B, T, H, W, C)
501
  elif arr.ndim == 5:
502
  arr = arr[0]
503
  frames = [arr[t] for t in range(arr.shape[0])]
504
-
505
- # Rare: list-of-frames already
506
  elif isinstance(frames_raw, list):
507
  frames = [np.array(f) for f in frames_raw]
508
-
509
  else:
510
  raise ValueError(f"Unexpected frames shape: {arr.shape}")
511
 
@@ -522,12 +522,12 @@ class EndpointHandler:
522
  except Exception:
523
  arr = np.array(vids)
524
 
525
- # shapes: (B,T,C,H,W) or (B,T,H,W,C) or (T,C,H,W) or (T,H,W,C)
526
  if arr.ndim == 5:
527
  arr = arr[0]
528
 
 
529
  if arr.ndim == 4 and arr.shape[1] in (1, 3, 4):
530
- # (T,C,H,W) -> (T,H,W,C)
531
  arr = np.transpose(arr, (0, 2, 3, 1))
532
 
533
  if arr.ndim != 4:
 
5
  This version includes:
6
  - Defensive patches to avoid hosted runtime failing with:
7
  "`ffmpeg` is not a registered plugin name."
8
+ - Robust frame extraction for shapes like (T,H,W,C), (B,T,H,W,C), (T,C,H,W), (B,T,C,H,W)
9
  - Output encoders:
10
  - GIF: Pillow only (no ffmpeg)
11
  - ZIP: PNG frames zipped (no ffmpeg)
12
+ - WebM: imageio + imageio-ffmpeg via IMAGEIO_FFMPEG_EXE env var (NO executable= arg)
13
 
14
  IMPORTANT:
15
  - HF gateway often requires top-level { "inputs": {...} }.
 
87
  except Exception as e:
88
  diag["details"].append(f"failed wrapping {fn_name}: {e}")
89
 
90
+ # Dummy module injection (helps if toolkit tries importing a plugin module)
91
  dummy_mod_name = "huggingface_inference_toolkit.plugins.ffmpeg"
92
  if dummy_mod_name not in sys.modules:
93
  dummy = types.ModuleType(dummy_mod_name)
 
119
  try:
120
  import imageio_ffmpeg # type: ignore
121
  _FFMPEG_EXE = imageio_ffmpeg.get_ffmpeg_exe()
122
+ # Force absolute ffmpeg path via env var; do NOT use imageio executable= param (not supported here).
123
  os.environ["IMAGEIO_FFMPEG_EXE"] = _FFMPEG_EXE
124
  except Exception:
125
  _FFMPEG_EXE = ""
 
145
  if not isinstance(frame, np.ndarray):
146
  frame = np.array(frame)
147
 
148
+ # squeeze batch dim (rare)
149
  if frame.ndim == 4 and frame.shape[0] == 1:
150
  frame = frame[0]
151
 
 
199
 
200
  def _encode_webm(frames: List[np.ndarray], fps: int, quality: str = "good") -> bytes:
201
  """
202
+ Encode WebM (VP9) via imageio.
203
+
204
+ IMPORTANT:
205
+ - Do NOT pass executable=...; HF's imageio build can reject that parameter.
206
+ - We rely on IMAGEIO_FFMPEG_EXE env var set at import time.
207
  """
208
  if not frames:
209
  raise ValueError("No frames to encode WebM.")
 
227
  out_path,
228
  fps=max(1, fps),
229
  format="FFMPEG",
 
230
  codec="libvpx-vp9",
231
  ffmpeg_params=[
232
  "-pix_fmt", "yuv420p",
 
347
  self.pipe = None
348
  self.init_error: Optional[str] = None
349
 
350
+ print("=== CUSTOM handler.py LOADED (webm uses IMAGEIO_FFMPEG_EXE only) ===", flush=True)
351
  print(f"=== HF toolkit patch diag: {HF_TOOLKIT_PATCH_DIAG} ===", flush=True)
352
  print(f"=== imageio-ffmpeg exe: {_FFMPEG_EXE} ===", flush=True)
353
 
 
491
 
492
  frames: List[np.ndarray] = []
493
 
494
+ # 1) output.frames — may be list OR ndarray/tensor-like
495
  if hasattr(output, "frames") and getattr(output, "frames") is not None:
496
  frames_raw = getattr(output, "frames")
497
  arr = np.array(frames_raw)
498
 
499
+ # (T,H,W,C)
500
  if arr.ndim == 4:
501
  frames = [arr[t] for t in range(arr.shape[0])]
502
+ # (B,T,H,W,C)
 
503
  elif arr.ndim == 5:
504
  arr = arr[0]
505
  frames = [arr[t] for t in range(arr.shape[0])]
506
+ # list-of-frames
 
507
  elif isinstance(frames_raw, list):
508
  frames = [np.array(f) for f in frames_raw]
 
509
  else:
510
  raise ValueError(f"Unexpected frames shape: {arr.shape}")
511
 
 
522
  except Exception:
523
  arr = np.array(vids)
524
 
525
+ # (B,T,C,H,W) or (B,T,H,W,C) or (T,C,H,W) or (T,H,W,C)
526
  if arr.ndim == 5:
527
  arr = arr[0]
528
 
529
+ # (T,C,H,W) -> (T,H,W,C)
530
  if arr.ndim == 4 and arr.shape[1] in (1, 3, 4):
 
531
  arr = np.transpose(arr, (0, 2, 3, 1))
532
 
533
  if arr.ndim != 4: