Latent Keyframe Group ππ π π
Batch ControlNet strengths in one node
- prev_latent_kf
- latent_optional
- LATENT_KF
This is the sane way to set per-frame ControlNet strengths when you have more than a couple of frames. Instead of chaining a dozen single Latent Keyframe nodes, you type one string - 0=0.9, 4:12=0.5, -1=0.2 - and get the whole schedule out of a single node. If you've ever wired five keyframe nodes in a row and lost the thread, this is the fix.
The concept is the same as a single Latent Keyframe: each entry says "the latent at this batch index gets the ControlNet at this strength." A Latent Keyframe Group just lets you declare a bunch of them at once, including ranges. It's the node you actually want in AnimateDiff and batch-video graphs where you're scheduling control across dozens of frames.
How the string works
Everything happens in index_strengths, a multiline text field. The grammar is small and worth memorizing:
- Single frame:
batch_index=strength, e.g.0=0.9- frame 0 gets strength 0.9. - Range:
start:end=strength, python-style (start inclusive, end exclusive), e.g.0:8=0.5- frames 0 through 7 get 0.5. - Separate entries with commas:
0=1.0, 8:16=0.4.
Negative indices - -1 for the last frame, -4=0.25 - work only if you connect the optional latent_optional input, because the node needs to know the real batch size to resolve them. Skip that connection and negatives will error or misbehave, so hook up the latents you're actually sampling if you want to count from the end.
The other optionals: prev_latent_kf chains this group onto an existing latent keyframe schedule (entries carried in from prev take priority on any shared index), and print_keyframes dumps the generated keyframes to your console - genuinely useful when a schedule isn't behaving and you want to see exactly what got parsed.
The single output is LATENT_KF, same type as every other latent-keyframe node. It plugs into a Timestep Keyframe's latent_keyframe input, or straight into latent_kf_override on Apply Advanced ControlNet if strength-per-frame is the only scheduling you need.
Installing the pack
ComfyUI Manager: Install Custom Nodes, search "ComfyUI-Advanced-ControlNet," restart. Or cd ComfyUI/custom_nodes && git clone https://github.com/Kosinkadink/ComfyUI-Advanced-ControlNet and restart. It's a pure-ComfyUI pack - no dependency hell. Note it ships neither preprocessors (those are in comfyui_controlnet_aux) nor ControlNet models (drop those in ComfyUI/models/controlnet yourself). It's from Kosinkadink, the AnimateDiff-Evolved dev, so it's maintained and it's meant to be used alongside sliding-context video sampling.
Common gotchas
The range syntax is the number-one stumbling block: 0:8 is frames 0β7, not 0β8. It's python slicing, exclusive on the right. Off-by-one here is why "my last frame isn't getting controlled."
Second, negative indices silently need latent_optional. If -1=0.3 does nothing, that missing connection is almost always why.
Third - the same trap as the single node - any index you name that isn't actually in the batch is just ignored. And whatever strengths you set here multiply with the strength on the Apply node downstream, so keep that in mind before you wonder why 1.0 doesn't look like full control. When in doubt, flip on print_keyframes and read what the node actually built.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| index_strengths | STRING | β | |
| prev_latent_kfopt | LATENT_KEYFRAME | β | |
| latent_optionalopt | LATENT | β | |
| print_keyframesopt | BOOLEAN | false | β |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT_KF | LATENT_KEYFRAME | β |