Nodes/ComfyUI-GiftHelperSuite/Gift Auto Shot Split | 自动切镜
ComfyUI Node

Gift Auto Shot Split | 自动切镜

Find the Cuts Before a Memory-Based Matte Has to Guess

By lingziwyh·Created 5 months ago·Updated a day ago· 7
Gift Auto Shot Split | 自动切镜
  • images
  • shots
  • initial_frames
  • shot_report
cut_threshold0.50
min_scene_frames8
auto_downloadtrue

A matting model with temporal memory is a wonderful thing until the picture cuts to another shot, at which point that memory is actively harmful - the tracker carries the previous subject's shape into the new frame and smears it across the first second of the cut. The fix is boring and effective: find the cuts first, then matte each shot on its own. GiftAutoShotSplit does the finding.

Why you'd split at all

Most people meet this node as step one of the pack's matting chain, and that's the right instinct. Segmentation approaches (InSPyReNet, RMBG-2.0) look at each frame cold and don't care about cuts. Memory-propagating matting cares deeply, because it's carrying a mask forward through time. Reset points are what make that propagation trustworthy, and a cut is the most honest reset point there is.

There's a second use: the shot list tells you how many independent things you're about to process - the difference between a one-minute render and a twenty-minute one because there were eleven shots.

How it works

The detector is TransNetV2, whose PyTorch inference code the pack vendors under an MIT licence - no TensorFlow, and no dependency on ComfyUI-Video-Segmentation, which is what older shot-splitting workflows asked you to install.

Inside the node, from the source:

  1. Frames are downscaled to 27x48 and quantised to 8-bit - TransNetV2's expected input, which is why detection is cheap regardless of your source resolution.
  2. The sequence is padded with 25 repeated frames at the head and 75 at the tail, then run through the network in overlapping windows to produce a per-frame cut probability.
  3. Frames clearing cut_threshold form runs of candidates, and each run contributes its peak frame.
  4. That peak is snapped to the strongest adjacent RGB change within a few frames of it - the local hard-cut alignment. The network knows a cut is near; the delta finds the exact frame.
  5. A candidate is accepted only if it leaves at least min_scene_frames on both sides of the previous cut and the end of the clip. That's the guard against splitting on flashes and camera motion.

Inputs and outputs

images (the whole video's frames), cut_threshold (0.5), min_scene_frames (8) and the optional auto_download toggle.

cut_threshold is the knob you'll actually turn: lower catches subtle transitions and the odd false positive, higher misses soft cuts. min_scene_frames is the secondary one - on a fast-cut montage the 8-frame floor can merge genuinely separate shots, and lowering it is the fix, at the cost of more spurious boundaries.

The outputs are:

  • shots - a list of image batches, one per shot. Feeds GiftMaskCheckFrames for check frames, and GiftAdaptiveMatting as the frames to matte.
  • initial_frames - the first frame of each shot, also as a list. Handy for checking that a shot doesn't open on a fade from black, which would give you a garbage seed mask. The shipped example doesn't use it.
  • shot_report - JSON with the frame count, the shot ranges, the method string and elapsed time, printed to the console too.

Because two of those are list outputs, ComfyUI runs everything downstream once per shot, each with its own result. That's the intent, and it's why the graph looks lighter on wires than it should.

Install

Manager, search ComfyUI-GiftHelperSuite, or:

cd ComfyUI/custom_nodes
git clone https://github.com/lingziwyh/ComfyUI-GiftHelperSuite.git

Restart and refresh. No requirements.txt; TransNetV2's code and weights are the pack's own business. You will want VideoHelperSuite for loading video into an IMAGE batch, since core ComfyUI has no video loader - separate install, same Python.

Weights download the first time you execute the node: ComfyUI/models/GiftHelperSuite/transnetv2-pytorch-weights.pth, from a pinned Hugging Face revision, hash-checked and published atomically. An existing copy at models/VLM/transnetv2-pytorch-weights/ is reused. auto_download=false on the node, or GIFT_HELPER_AUTO_DOWNLOAD=0 before launch, keeps it offline.

Common issues

The node won't run. Probably no frames. Downloads happen at execution, not graph load, so a missing-model error means the toggle is off or the network is unreachable; the message prints the manual URL and path.

A half-finished download gets rejected later. Downloads land in a temp file and are hash-verified before publication, so an HTML error page saved as a .pth can't be silently loaded. And if you swapped in a different build by hand, the check keeps your file rather than overwriting it.

It split one shot into five. Strobe, whip-pans, a music video. Raise min_scene_frames and cut_threshold, then check the report's range count against your own rough guess.

It missed a cut. Lower cut_threshold first. On slow cross-fades there's no sharp RGB delta for the alignment step to find, so the boundary lands approximately - fine for matting, not for anything frame-exact.

And the one everybody hits: change the source video and set Video Combine's frame_rate to match, leaving force_rate=0 on the loader so the source frame rate survives.

CategoryGiftHelperSuite/Video Matting

Inputs (4)

NameTypeDefaultDescription
imagesIMAGE
cut_thresholdFLOAT0.500.01–0.99
min_scene_framesINT81–240
auto_downloadoptBOOLEANtrue

Outputs (3)

NameTypeDescription
shotsIMAGE
initial_framesIMAGE
shot_reportSTRING