parlorsky commited on
Commit
df67f77
·
verified ·
1 Parent(s): 10ef49e

Upload ComfyUI-ShotSplitter/first_frame_reader.py with huggingface_hub

Browse files
ComfyUI-ShotSplitter/first_frame_reader.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Read the first frame of a list of clips into a unified IMAGE batch."""
2
+
3
+ import logging
4
+ from typing import List
5
+
6
+ import numpy as np
7
+ import torch
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def read_first_frames(clip_paths: List[str]) -> torch.Tensor:
13
+ """Return (N, H, W, 3) float32 tensor in 0..1. Uses max-dim resize to first clip's size.
14
+
15
+ On read failure for any clip, substitute a black frame of the reference size.
16
+ """
17
+ import decord
18
+ decord.bridge.set_bridge("native")
19
+
20
+ frames: List[np.ndarray] = []
21
+ ref_h, ref_w = None, None
22
+ for path in clip_paths:
23
+ try:
24
+ vr = decord.VideoReader(path)
25
+ f = vr[0].asnumpy() # HxWx3 uint8 RGB
26
+ if ref_h is None:
27
+ ref_h, ref_w = f.shape[0], f.shape[1]
28
+ if f.shape[0] != ref_h or f.shape[1] != ref_w:
29
+ import cv2
30
+ f = cv2.resize(f, (ref_w, ref_h), interpolation=cv2.INTER_AREA)
31
+ frames.append(f)
32
+ except Exception as e:
33
+ logger.warning("first-frame read failed for %s: %s", path, e)
34
+ if ref_h is None:
35
+ ref_h, ref_w = 64, 64
36
+ frames.append(np.zeros((ref_h, ref_w, 3), dtype=np.uint8))
37
+
38
+ if not frames:
39
+ return torch.zeros((0, 64, 64, 3), dtype=torch.float32)
40
+
41
+ stacked = np.stack(frames, axis=0).astype(np.float32) / 255.0
42
+ return torch.from_numpy(stacked)