SKEBA H3 Motion Context
Chain MiniMax H3 clips so the motion — and the sound — actually continues
- conditioning
- vae
- latent
- context_frames
- context_latent
- audio_vae
- context_audio
- conditioning
- trim_frames
MiniMax H3 has no built-in clip chaining the way LTX does, so long scenes end as a stack of clips that don't connect - each new take guesses its own motion and audio, and the cut announces itself. SKEBA H3 Motion Context pins the previous clip's last frames (and optionally its tail audio) into the next generation as conditioning rows the model treats as real, already-existing video. Clip B picks up clip A's motion, speed, direction, and sound instead of pretending to be a new scene.
It lives in the ComfyUI-H3-Reference-Library pack (a.k.a. ComfyUI-Minimax-H3-Reference-Library), under Skeba AI Nodes - Motion Context, alongside Trim, the latent Save/Load pair, and Seam Exposure Match. Two things before you build: H3's community license geofences the local weights out of the EU, UK, South Korea, and the US - if you're running it locally you already cleared that bar - and chaining quality does degrade down a long chain, mostly audio.
How it works
H3 can pin a frame at a time coordinate and re-inject it at every sampling step, but stock ComfyUI only accepted the first or last frame. This node's patches lift that restriction so a whole run can anchor the clip - and they install lazily on first run, so installing the pack changes nothing about your other H3 graphs.
The settings that matter:
- context_length - frames of the previous clip's picture to carry over. Only 5, 22, 39, or 56 are offered - those are the lengths that are whole numbers of latent steps. Use 22. It's nearly seamless without wasting much of the render; 56 pins 2.3 seconds of motion you then throw away.
- audio_context_length - frames of tail audio to pin, independent of the picture window. 0 follows
context_length; 22 overlays a 22-frame picture window exactly, and it's the right default.
Wire it like this: the H3 conditioning node (MiniMaxH3ImageToVideo / MiniMaxH3ReferenceToVideo) → Motion Context → guider/sampler. The required conditioning, vae, and latent inputs are the current clip's own - the node reads the clip's length and resolution from its latent.
The previous clip reaches the node one of two ways:
- context_latent (preferred) - the previous clip's sampler output latent, moved across runs via the pack's Save/Load Latent nodes. The pinned frames are sliced straight out of the latent, skipping the decode-to-pixels-and-back VAE round trip that causes visible seams. Resolution must match the new clip - the node refuses rather than silently downshifting.
- context_frames + context_audio + audio_vae - the older decoded path. Works, but each link costs a lossy round trip on both streams, and it's where the visible seams came from. Use the latent.
Outputs are conditioning (feeds the sampler) and trim_frames - how many pinned frames come back at the head of the delivered clip. Wire trim_frames into the Trim node, or those frames stay in your output.
The two-pass setup
Clip 1 has no previous clip, so the first pass runs with bypass on (passes conditioning through, outputs 0 trim frames). Save the sampler's latent, then for clip 2 turn bypass off and feed the saved latent in as context_latent. Motion Context, Trim, and Load Latent all expose the same bypass switch - drive them from one boolean for clean automated first-pass/continuation runs.
The honest caveats
- Quality compounds down a chain - mostly audio, which gets duller after several clips. The latent path kills the codec/VAE round-trip loss, but the model's own smoothing remains - listen critically on long chains.
- The model renders contradictions as unions - a clip N+1 prompt describing a different arrangement of people than clip N ended on produces all of them at once. The pinned frames aren't a suggestion.
- Use the "airlock": open clip N+1 holding clip N's exact closing framing for about two seconds before cutting to the new setup. Joins done this way measure tighter than a plain cut.
- Keep step-skipping optimizers off these graphs - turbo LoRAs and Spectrum-style schedulers thicken audio and mispredict the pinned rows. Turn them off before blaming the chaining.
Installing it
ComfyUI Manager - search "Skeba" or "H3-Reference-Library" - or:
cd ComfyUI/custom_nodes
git clone https://github.com/nikaskeba/ComfyUI-H3-Reference-Library
Restart ComfyUI. No extra Python dependencies. The Motion Context code is a vendored fork of NikoDemon80's ComfyUI-H3-Motion-Context under GPLv3.
The setup traps
- You can't wire the sampler straight into
context_latent- ComfyUI is right to call it circular. The latent crosses runs through the Save/Load pair. - Only install one H3 chaining pack - several lift the same first/last-frame restriction, and only one can own that patch. If another got there first, this node refuses to run and says why.
- Update drift is loud, not silent. The patches self-test against ComfyUI's live code at startup; if an update breaks them, the node refuses with the reason logged - a hard stop beats a subtly wrong render.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| conditioning | CONDITIONING | — | |
| vae | VAE | — | |
| latent | LATENT | — | |
| context_length | COMBO | 22 | Frames of the previous clip's picture to carry over. Only these lengths are whole numbers of latent steps, so only these are offered. 5 is just barely fluid, 22 is nearly seamless. Longer windows pin more motion but come off the front of the delivered clip, so 56 spends 2.3 seconds of the render on frames you throw away. |
| audio_context_length | INT | 220–240 | Frames of tail audio to pin, independent of the picture window. 0 follows it. The window is END-aligned with the pinned video, so 22 against a 22-frame picture window overlays it exactly; longer windows reach further back into vacated coordinate space (untested). |
| context_framesopt | IMAGE | Decoded frames of the previous clip. Used when no context_latent is wired. When one is, the picture comes from it instead and this is ignored. | |
| context_latentopt | LATENT | Previous clip's SAMPLER OUTPUT latent (the same one you wire into the decode nodes). Supplies both picture and sound, sliced straight out, skipping the decode and re-encode that cost a little quality at every link of a chain. Must be the same resolution as the clip being generated. | |
| audio_vaeopt | VAE | H3 audio VAE. Supply with context_audio to carry the previous clip's tail sound across the join. Not needed when context_latent is wired. | |
| context_audioopt | AUDIO | Audio of the previous clip. The tail matching the pinned frames is encoded and pinned alongside them. Ignored when context_latent is wired. | |
| bypassopt | BOOLEAN | false | Pass conditioning through unchanged and output 0 trim frames. Turn this on for the first clip, then off to enable motion context on later clips. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| conditioning | CONDITIONING | — |
| trim_frames | INT | — |