Nodes/ComfyUI-CustomNodePacks/AV Handles — Add / Trim
ComfyUI Node

AV Handles — Add / Trim

Give your video model a frame count it actually accepts, then trim it back

By Code2Collapse·Created 8 months ago·Updated about 7 hours ago· 59
AV Handles — Add / Trim
  • images
  • audio
  • handles
  • images
  • audio
  • total_frames
  • handles
  • info
◄modefit►
◄handle_frames8►
◄trim_amountauto►
◄target_frames0►
◄modelMiniMax H3 (17n+5)►
◄custom_step4►
◄custom_plus1►
◄sidehead►
◄padding_modemodel preset►
◄manual_fps0.000►
◄memo_key►

Video models don't take arbitrary frame counts. Wan wants 4n+1, LTX wants 8n+1, MiniMax H3 wants 17n+5. Hand one of them 64 frames and it doesn't throw an error - it reinterprets the clip, and your output comes back at the wrong speed with a frozen or doubled frame somewhere in it. If you've ever generated "5 seconds" and gotten 4.6 seconds of slightly fast motion, this is usually why.

AV Handles does the boring arithmetic around that: pad the clip up to a count the model accepts, then take exactly those extra frames back off afterwards. It also carries the audio along by the same duration, so nothing drifts.

Why it's one node and not two

The upstream ComfyUI-AV-Handles pack ships an Add node and a Trim node, and the Trim has its own handle_frames widget you have to retype to match whatever Add used. Two numbers that must agree, typed in two places, often days apart. They drift, and the symptom is a clip a few frames long or short with nothing telling you why.

This pack ported it into a single node with three modes and a memory. mode = fit is the one you want: you say how many frames you want out, the node works out what the model will accept, pads up to it, and remembers the target. Then mode = trim takes them back off - by target, not by count. That distinction is the whole point: if your sampler returns 123 instead of 124, trimming "remove 4" silently gives you 119, while trimming to 120 gives you 120 from whatever arrives.

mode = add puts a fixed number of frames on and remembers it, for when you're doing the grid maths yourself. mode = trim with trim_amount = auto uses the remembered count, or the one wired into handles. trim_amount = manual uses handle_frames instead, which is only for undoing handles this node didn't add.

The inputs that matter

mode, then target_frames (fit mode - ask for 64 and get 64, whatever the model renders internally; 0 means "use the clip's current length", which pads to the grid and trims straight back). model is the grid selector: none, MiniMax H3, Wan 2.x, LTX/LTX-2, Hunyuan, CogVideoX, Mochi, or custom, which exposes custom_step and custom_plus. There's also a padding_mode widget left over from the older design that rounds the total onto a grid - harmless on old workflows, but on a new one use model and leave it disabled.

side picks head or tail (head, by default, because that's the run a video model uses to settle). manual_fps only matters when there's no audio to measure against - a guessed 30 on 24fps material puts your audio 25% out. memo_key is for the rare case of two independent clips in one graph; give each its own name or their counts overwrite each other. And handles is the honest wire: feed the add node's handles output into the trim node and the count is exact, which is what you need when the two ends live in different workflows and the memory can't reach.

Outputs are images, audio, total_frames, handles, and info. The info string tells you where the trim got its number - worth reading once, because "it trimmed the wrong amount" is otherwise unanswerable.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git

Or search "CustomNodePacks" in ComfyUI Manager. This node is pure PyTorch tensor work - no models, no extra packages. Restart and look for [C2C] CustomNodePacks: 142 nodes loaded (...) in the console.

Where people get burned

Trimming more frames than exist is refused outright rather than returning an empty batch - an empty batch downstream just reads as "no video" and tells you nothing. If your trim says it trimmed 0, you either wired nothing and the memory is empty, or you're in a fresh session where the add ran in a different graph; wire handles and stop guessing.

Both the grid arithmetic and the handle idea are about the same underlying annoyance, which wan-video.md in the KB documents from the other direction: the community default for Wan is 49–81 frames because beyond that it degrades, and every "just give me 5 seconds" node people build is a wrapper around exactly the pad-and-trim this one does honestly.

Category🐺 C2C/🧰 Core/Video

Inputs (14)

NameTypeDefaultDescription
modeCOMBOfitfit — say how many frames you want OUT. The node works out what the model will accept, pads up to it, and remembers the target so the trim lands exactly there. This is the one to use. add — put a specific number of frames on, and remember how many. trim — take them back off, using the remembered target or count.
handle_framesINT80–400ADD: how many frames to put on. With a grid selected, 0 means 'just enough to land on the grid'. TRIM: ignored unless trim_amount is 'manual'.
trim_amountCOMBOautoTRIM mode only. auto — use the count the add side recorded (or the one wired into `handles`). This is the point of the node: the two ends cannot drift apart. manual — use handle_frames instead. Only for undoing handles this node did not add. It is a separate control because 'left at the default' and 'deliberately typed 8' cannot be told apart in one number, and guessing wrong silently trims the wrong amount.
imagesoptIMAGE—
audiooptAUDIO—
target_framesoptINT00–100000FIT mode: how many frames you want OUT. The model's own grid is an implementation detail — ask for 64 and you get 64, whatever the model needs to render to make them. 0 in fit mode means 'use the clip's current length as the target', which pads it to something the model accepts and trims straight back.
modeloptCOMBOMiniMax H3 (17n+5)FIT, and ADD with padding_mode 'model preset': which model's frame grid to land on. Every video model wants step*n + plus frames and they disagree only on the numbers: H3 is 17n+5, Wan is 4n+1, LTX is 8n+1. Hand a model a count it does not accept and it does not complain — it reinterprets the clip, and the result comes out at the wrong speed.
custom_stepoptINT41–1000Only used when model is 'custom'.
custom_plusoptINT10–1000Only used when model is 'custom'.
sideoptCOMBOheadWhich end. Handles go on the head because that is the run a video model uses to settle. both: handle_frames on the head AND the tail (fit splits its padding across the two ends). TRIM takes a wired or remembered count off exactly the ends it went on; this setting only matters for a manual count.
padding_modeoptCOMBOmodel presetADD: round the total onto a model's frame grid. A model that wants 4n+1 and is handed 4n does not complain — it reinterprets the clip, and the result comes out at the wrong speed. model preset: the grid of the `model` dropdown (or the custom step / plus). disabled: exactly handle_frames, no rounding. The fixed WAN / LTX2 / H3 entries are kept for workflows saved with them.
manual_fpsoptFLOAT0.0000–2400 measures it from the clip's own audio. Set it when there is no audio to measure against — a guessed 30 on 24fps material puts the silence 25% out.
handlesoptHANDLESWire the add node's `handles` output here for an exact, explicit count. Takes priority over the remembered one, and works across separate workflows where the memory cannot.
memo_keyoptSTRINGOnly needed when two independent clips are being handled in one workflow — give each its own name so their counts do not overwrite each other. Empty is right for one clip.

Outputs (5)

NameTypeDescription
imagesIMAGEFrames, with handles added or removed.
audioAUDIOAudio moved by the same duration, so it stays in step.
total_framesINTHow many frames came out.
handlesHANDLESThe handle count, to wire into the trim node. Exact, and it does not depend on the memory — use it when the add and the trim are in different workflows.
infoSTRINGWhat happened, including WHERE the trim count came from.