Nodes/ComfyUI-BFSNodes/BFS H3 Native Shot Loop End / Join
ComfyUI Node

BFS H3 Native Shot Loop End / Join

The node that re-queues your whole graph until the video is done

By alisson-anjos·Created 7 months ago·Updated 2 days ago· 133
BFS H3 Native Shot Loop End / Join
  • images
  • loop_state
  • joined_images
  • fps
  • manifest

What it is

BFS H3 Native Shot Loop End / Join is the closing bracket of the pack's experimental native shot loop. You wire your trimmed, decoded shot frames into it; it stashes them, then quietly re-expands the middle of your graph and runs the whole thing again for the next shot. When the last segment lands, it concatenates everything and hands you a single image batch at 24 fps.

If you've used any of the loop-node genre in ComfyUI - SxCP, context loops, the various "generate 4 clips in one queue" packs - the shape is familiar. What makes this one worth reading the docs for is how much it refuses to do: no crossfade, no overlap, no retiming. Output length equals the length of the clip you loaded, and that's it.

The pack's own docs credit the expansion pattern: it's adapted from Ethanfel's MiniMax H3 Context Loop / SxCP loop nodes, which are GPL-3.0. If you're licensing something downstream, go read the pack's LICENSE rather than assuming.

The mechanism, because this is the part that bites

On each pass the node works out how many frames the current segment should be - from the ranges Loop Start computed - and errors if your decoded frames come up short. Otherwise it slices to exactly that count, saves the tensor to ComfyUI/temp/bfs_h3_native_loop/<session>/00000.pt, and writes a manifest.json. Then it looks at how many segments are left.

If there are more, it uses ComfyUI's dynamic graph execution to clone only the body between Loop Start and Loop End and queues that expanded graph for the next shot. Everything upstream of Start (model load, LoRA, TARA) and everything after End (Create Video, Save Video) stays out of the loop and stays shared. That's the design intent, and it's why the docs say "do not add final Save Video inside the repeated body" - you'd be re-saving a partial file per segment and re-encoding the model each time.

If there are none left, it loads every .pt back, checks they all share the same resolution (All segments must decode at the same resolution otherwise), and torch.cats them.

Inputs and outputs

images - the decoded frames of one shot, after you've trimmed H3's 17n+5 padding. loop_state - the wire coming from Loop Start, unchanged.

joined_images goes into Create Video; fps is a float 24.0, and it exists so you don't hardcode the frame rate wrong; manifest is a string path to that manifest.json, and it's the most useful debugging output in the node. It records segment ranges and where each tensor went. It is not a resume mechanism - if your run dies at segment 4, you start over.

Audio doesn't come through here at all. Connect the original loader's audio directly into Create Video.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/alisson-anjos/ComfyUI-BFSNodes.git
cd ComfyUI-BFSNodes
pip install -r requirements.txt

Restart, refresh the browser tab. The requirements file is thin - torch, numpy, Pillow, safetensors, librosa, opencv-python, scenedetect - while the pack's pyproject.toml also wants transformers>=4.55.0 and scipy. If your ComfyUI env is a normal one you already have both, but a bare container can fail on the loop nodes for want of libraries the README's install line never installs.

Version 1.115.27 is where these nodes landed; the installed pack is 1.115.33 at time of writing. Everything here is marked experimental in the author's own docs, with CPU graph checks rather than a validated GPU render.

Common issues

"Segment N has X decoded frames but needs Y." The classic. Your sampler output got capped or truncated somewhere - a frame-count cap on the loader, a max_frames set to something finite on Prepare Native Video, or the last short segment not being padded. The example workflow sets max_frames=0 and frame_rounding=pad last frame for exactly this reason, and trims the padding before the join. A final segment under five frames gets its last source frame repeated upstream to satisfy H3's minimum; Loop End only keeps the real count.

"Native shot loop requires ComfyUI dynamic graph execution." Your ComfyUI is too old, or something in the graph is breaking the dynamic expansion. Update first.

RAM creeping up over a long loop. Each segment is saved as a float image tensor in temp, and the final concatenation pulls them all into CPU RAM. Twenty shots at 2K is not a small number. There is no streaming join; budget accordingly, and clean out old session folders.

Segments at different resolutions. Usually the reference image sizes differ between shots and something downstream is resizing per-shot instead of per-run. Keep the prepared canvas fixed.

CategoryBFS/MiniMax H3/Native Shot Loop

Inputs (2)

NameTypeDefaultDescription
imagesIMAGE—
loop_stateBFS_H3_NATIVE_LOOP—

Outputs (3)

NameTypeDescription
joined_imagesIMAGE—
fpsFLOAT—
manifestSTRING—