67 lines
2.5 KiB
Python
67 lines
2.5 KiB
Python
"""
|
|
H3 Shot Length (single model-free source for shot length)
|
|
==========================================================
|
|
Holds ONE shot-length value and emits it as both seconds and a grid-aligned
|
|
H3 frame count. Because it never reads the model, it can sit upstream of
|
|
Kijai's Model Preview Override without creating a cycle -- unlike the preview
|
|
node or the sampler, which read the model to compute their frame counts and so
|
|
cannot feed anything that produces the model.
|
|
|
|
Wire:
|
|
H3 Shot Length (seconds) -> H3 Long Videos FL2VA (shot_seconds)
|
|
H3 Shot Length (frames) -> Model Preview Override (preview_frames)
|
|
|
|
One value, entered once here, drives both -- no manual re-entry, no cycle.
|
|
|
|
Note: this is a FIXED shot length you choose. The sampler's *auto* (VRAM-
|
|
picked) length can't be used for preview_frames, because computing it requires
|
|
reading the model, which is the very dependency that creates the loop. Set the
|
|
sampler's shot_seconds from this node's `seconds` output so the two agree.
|
|
"""
|
|
|
|
H3_MAX_FRAMES = 362
|
|
|
|
|
|
def align_up_grid(n):
|
|
n = max(5, int(n))
|
|
while n % 17 != 5:
|
|
n += 1
|
|
return n
|
|
|
|
|
|
class H3ShotLength:
|
|
CATEGORY = "Dumas/MiniMax"
|
|
FUNCTION = "emit"
|
|
RETURN_TYPES = ("FLOAT", "INT", "STRING")
|
|
RETURN_NAMES = ("seconds", "frames", "info")
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"shot_seconds": ("FLOAT", {"default": 5.0, "min": 0.2, "max": 15.1, "step": 0.5,
|
|
"tooltip": "Length of each shot. Feeds the sampler's shot_seconds AND (as frames) "
|
|
"the preview override. Max ~15s (362 frames)."}),
|
|
"fps": ("INT", {"default": 24, "min": 1, "max": 60}),
|
|
},
|
|
"optional": {
|
|
"cap_to_h3_max": ("BOOLEAN", {"default": True,
|
|
"tooltip": "Clamp frames to 362 (~15s), H3's single-clip maximum."}),
|
|
},
|
|
}
|
|
|
|
def emit(self, shot_seconds, fps, cap_to_h3_max=True):
|
|
fps = max(1, int(fps))
|
|
frames = align_up_grid(round(float(shot_seconds) * fps))
|
|
capped = cap_to_h3_max and frames > H3_MAX_FRAMES
|
|
if capped:
|
|
frames = H3_MAX_FRAMES
|
|
info = (f"{shot_seconds:g}s/shot @ {fps}fps -> {frames} frames"
|
|
f"{' (capped 362)' if capped else ''}")
|
|
return (round(float(shot_seconds), 3), frames, info)
|
|
|
|
|
|
NODE_CLASS_MAPPINGS = {"DumasH3ShotLength": H3ShotLength}
|
|
NODE_DISPLAY_NAME_MAPPINGS = {"DumasH3ShotLength": "Dumas H3 Shot Length"}
|
|
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
|