Nodes/comfyui-darkil-nodes/MiniMax H3 Multi Keyframe [darkilNodes]
ComfyUI Node

MiniMax H3 Multi Keyframe [darkilNodes]

Pin keyframes anywhere on the timeline, not just the first and last frame

By pytraveler·Created 8 months ago·Updated 23 days ago· 9
MiniMax H3 Multi Keyframe [darkilNodes]
  • model
  • clip
  • vae
  • first_frame
  • last_frame
  • middle_frames
  • positive
  • latent
  • model
prompt
width1344
height768
length124
middle_positions
position_unitsratio
middle_fitcover
keyframe_noise_aug0.999

The stock ComfyUI "MiniMax H3 Image to Video" node gives you exactly two anchors: frame 0 and the last frame. MiniMax H3 Multi Keyframe [darkilNodes] is a drop-in replacement that lets you pin extra images anywhere in the clip - think shot-board control, or holding a subject at the one-third mark instead of just the bookends. It returns the same positive conditioning and latent the core node does, plus a model output that carries the layout patch. This is the node you want if you've ever groaned at a generated video where the "middle" should have been an image you fed in.

Context first: MiniMax H3 is the open-source Hailuo 3 video model, released at the end of July 2026 with day-0 ComfyUI support. It's brand new territory, and so is this patch.

How it works

This is the rare node where the mechanism is worth understanding, because it explains both why it works and why it's a bit experimental. The core H3 pipeline is already written to carry a list of keyframes of any length - one condition segment and one condition latent per entry. The only thing refusing anchors in the middle is PackedLayout, which raises ValueError("only first/last keyframe anchors are supported") for anything else.

The trick: the temporal RoPE coordinate of a condition row is linear in the pixel frame index - origin + 5/3 * index, which is the 40 Hz RoPE over 24 fps video. That one formula reproduces both stock anchors exactly, which means frame 17, frame 50, whatever, is just… the same formula. So the node builds the keyframe list with real frame indices and hands back a patched MODEL: an OUTER_SAMPLE wrapper that installs a marker-gated PackedLayout patch for one sampling run and removes it in a finally block. Nothing is patched process-wide, and keyframes from other packs without the marker go through the stock code untouched.

The wiring - read this twice

model, clip, and vae come from the same places as for the core node. But that model output has to reach the sampler (the guider and scheduler). It's what carries the layout patch. If you wire it like the stock node and forget the model connection, the run stops with that exact stock error above instead of quietly stacking every anchor on frame 0. The README is blunt about it, and so am I: this is the one gotcha that will eat you.

Inputs and outputs that matter

  • middle_frames (IMAGE, optional) - a batch of images, one anchor per image.
  • middle_positions (STRING) - one value per image, comma separated ("0.33, 0.66"). Leave it empty to spread the anchors evenly between first and last.
  • position_units - ratio (0.0–1.0 of the clip) or frames (absolute index on the snapped timeline).
  • middle_fit - cover (keep aspect, crop - like the stock last_frame) or stretch.
  • keyframe_noise_aug (FLOAT, default 0.999) - condition strength for every keyframe row. Lower values blend noise into the anchors and let the model deviate from them. This is the first knob to reach for when the model fights a middle anchor.
  • length (INT, default 124 ≈ 5 s) - snapped up to the model's 17k+5 frame grid; the trained range is roughly 124–362 frames.

Plus the usual first_frame, last_frame, prompt, width (1344), height (768). Outputs: positive (CONDITIONING), latent (LATENT), model (MODEL).

Install

Pack install is the usual zero-dependency affair - no Python deps, no model files to download (the H3 checkpoint you already need for core MiniMax H3 is all you use):

  • ComfyUI Manager: search "darkil" / "comfyui-darkil-nodes", or
  • cd ComfyUI/custom_nodes && git clone https://github.com/pytraveler/comfyui-darkil-nodes.git, then restart.

The real requirement is hidden: this node needs a ComfyUI build with MiniMax H3 support (comfy_extras/nodes_minimax_h3.py and comfy/ldm/minimax/model.py). If your ComfyUI is older than the H3 release, update ComfyUI itself first - the node will refuse with a clear "no MiniMax H3 support" error, not a crash.

Caveats worth knowing

H3 was trained with first and last anchors (the fl2va mode). A middle anchor is outside that training distribution. In practice it holds - a marker drawn on the middle image shows up in the middle of the clip with consistent motion around it - but the further past three anchors you go, the less trodden the ground. Each extra anchor also adds one condition segment to the packed sequence, roughly 1000 rows at 1344x768, so don't go overboard. Treat this as an experiment node with a really nice error message - and keep keyframe_noise_aug in your back pocket for when the model disagrees with you.

CategorydarkilNodes/minimax

Inputs (14)

NameTypeDefaultDescription
modelMODELH3 diffusion model. The returned model carries the layout patch and has to reach the sampler
clipCLIP
vaeVAE
promptSTRING
widthINT134432–16384
heightINT76832–16384
lengthINT1245–3600Frame count at 24 fps, snapped up to the model's 17k+5 grid (124 = ~5s, trained range is ~124-362)
middle_positionsSTRINGOne position per image in middle_frames, comma separated. Empty spreads them evenly between the first and the last frame
position_unitsCOMBOratioratio: 0.0-1.0 of the clip. frames: absolute frame index on the snapped timeline
middle_fitCOMBOcoverHow a middle frame is fitted to the canvas. cover keeps the aspect and crops, like the stock last_frame
keyframe_noise_augFLOAT0.9990–1Condition strength for every keyframe row. 0.999 is the stock value, lower values blend noise into the anchors and let the model deviate from them
first_frameoptIMAGE
last_frameoptIMAGE
middle_framesoptIMAGEBatch of images anchored between the first and the last frame, one anchor per image

Outputs (3)

NameTypeDescription
positiveCONDITIONING
latentLATENT
modelMODEL