ComfyUI Node

H3 Context

The node that makes MiniMax H3 clips continue each other

By Adudeguyman·Created about a month ago·Updated a day ago· 31
H3 Context
  • conditioning
  • latent
  • vae
  • context_frames
  • context_latent
  • audio_vae
  • context_audio
  • conditioning
  • trim_frames
  • latent
context_length22
encode_modevideo
anchor_modehead
cropdisabled
audio_context_length22
audio_modetimeline
video_sourcelatent
seed_headtrue
head_hold1.00
enabled

MiniMax H3 makes gorgeous five-to-fifteen second clips. Stringing them into something longer is where every video model falls apart, and H3 is no exception: the stock trick is last-frame chaining, where the final frame of clip one becomes the first frame of clip two. It works, but it throws away everything except one still. Motion stops and restarts. The soundtrack cuts out and a soundalike picks up. And because every join decodes out of the model's format and re-encodes back in, each handoff quietly costs you quality that the next join builds on.

H3 Context is the node that fixes the join. It's the heart of the H3 Project Suite, and the only node in the pack you actually think about. Set once, wire once, and every clip after the first genuinely continues the one before it - motion carrying its direction and speed through the seam, the same music still playing, the same voice mid-sentence.

How it works

The short version: instead of handing the model a single frozen frame, H3 Context pins a run of consecutive frames from the tail of the previous clip as never-denoised conditioning rows. The model reads real motion - an approaching camera that's still approaching, a character mid-gesture - rather than guessing motion from one still. Roughly a second of what came before is handed over, not one frame.

The pack's default is the clever part. In latent mode (video_source), the pinned video is sliced straight out of the previous clip's latent tail - the same latent you wired into the decoder - so there's no VAE round trip between clips at all. That's the difference between this and the old way of doing it: no decode, no re-encode, no accumulated drift from the plumbing. The frames mode (decoded frames via context_frames, one VAE encode per link) is kept for hand-built graphs and compatibility, but latent is what the example workflows use.

The inputs that matter

There are a lot of widgets, but you set these and ignore the rest:

  • context_length (default 22) - frames of the previous clip to carry over. Only values 1, 5, 22, 39 and 56 exist. Bigger means a smoother join but less new footage: at 56, nearly two and a half seconds of the new clip re-treads the old one. 22 (just under a second) is the default for a reason. A slow push-in benefits from 39 or 56; a fast cut doesn't.
  • video_source (default latent) - leave it on latent unless you know you need frames.
  • seed_head (default on) - normally the carried frames are given to the model as something to agree with. With this on, they're also written directly into the clip's starting latent and held there while it renders (temporal inpainting), so the sampler builds forward from the previous clip's actual content instead of from noise that merely resembles it.
  • head_hold (default 1.0) - how firmly the seeded head is held. 1.0 keeps it exactly; 0.85 lets the model repaint the boundary slightly, which can ease the release.

The rest - encode_mode, anchor_mode, crop, audio_context_length, audio_mode - have sane defaults and the tooltips are honest about when you'd touch them. Audio: if you're not on the latent path, supply context_audio plus audio_vae to carry the tail sound across the join.

The three outputs

  • conditioning → your guider (the conditioned positive input).
  • latent → the sampler's latent_image, instead of the wire from the MiniMax node. This is what makes seed_head work - if the sampler still takes its latent from the MiniMax node, seeding silently does nothing. No harm, just no effect.
  • trim_frames → the H3 Context Trim node, so it knows how many overlap frames to cut.

Install and gotchas

Install the whole suite once (ComfyUI Manager, search "H3 Project Suite", or cd ComfyUI/custom_nodes && git clone https://github.com/Adudeguyman/ComfyUI-H3-Project-Suite, then restart and hard-refresh with Ctrl+Shift+R). No model downloads - it talks to your existing H3 install.

Two gotchas worth knowing. First, if you have the original ComfyUI-H3-Motion-Context pack installed, remove or disable it - this suite detects the conflict and refuses to run rather than produce a bad render. Second, a join that shows a texture or quality change about a second in is the point where the held frames end; that's normal, and head_hold at 0.85 is the knob to try before you start blaming the model. H3 itself is still doing what H3 does - this node just stops the plumbing from making it worse.

Categoryconditioning/minimax

Inputs (17)

NameTypeDefaultDescription
conditioningCONDITIONING
latentLATENT
context_lengthCOMBO22Frames of the previous clip to carry over. Only these land on the VAE grid, so the pinned run always ends exactly at the clip's last frame. Bigger = smoother join, less new content: 56 spends ~2.3s of the new clip re-treading the old one. 1 is effectively last-frame chaining, useful as a baseline.
encode_modeCOMBOvideovideo: one VAE call, motion lives inside the latent, fewer rows. frames: one call per frame, each pinned as a separate still.
anchor_modeCOMBOheadhead: pinned frames occupy the first indices and come back in the output, so trim them. before: negative indices, nothing wasted, but the coordinates overlap the text rows.
cropCOMBOdisabled2 options: disabled, center
audio_context_lengthINT220–240Frames of tail audio to pin, independent of the video window. 0 follows context_length. In timeline mode the window is END-aligned with the pinned video, so 22 with a 22-frame video window overlays it exactly; longer windows extend backwards into vacated coordinate space (untested).
audio_modeCOMBOtimelinetimeline: pinned audio gets coordinates on this clip's own timeline, end-aligned with the pinned video, so the model reads it as this clip's sound so far and continues it. ref: stock placement in a span before the clip, which the model imitates (similar music, not phase-locked) rather than continues.
video_sourceCOMBOlatentframes: pin decoded frames from context_frames (one VAE encode; each link adds a decode/encode round trip, which drifts color slightly down a chain). latent: EXPERIMENTAL - slice the pinned video straight from context_latent's tail, no VAE round trip at all, matching what the audio already does. Needs context_latent wired and the same resolution as the new clip; context_frames and encode_mode are ignored.
seed_headBOOLEANtrueLatent path only. Also writes the pinned steps INTO the clip's starting latent and hold them there while sampling (temporal inpainting), so the sampler's trajectory starts from the previous clip's actual state instead of noise that is merely conditioned toward it. Wire this node's latent OUTPUT into the sampler for this to take effect.
head_holdFLOAT1.000–1How firmly the seeded head is held. 1.0 keeps it exactly; lower values let the model repaint it slightly, which can ease the release at the boundary. On stock ComfyUI this grades the pixels only; with upstream PR #15375 applied it also grades how the held rows are conditioned.
vaeoptVAEVideo VAE, used ONLY to encode context_frames when video_source is 'frames'. The latent path never encodes anything, so leave this unwired there.
enabledoptBOOLEANWire the Project Hub's chain_active here. False makes this node (and, via trim_frames=0, the Trim node) pass everything through untouched, so clip 1 of an empty project renders with no manual bypassing at all.
context_framesoptIMAGEDecoded frames of the previous clip. Required when video_source is 'frames'; ignored on the latent path.
context_latentoptLATENTPrevious clip's SAMPLER OUTPUT latent (the same one you wire into the decode nodes). When supplied, the pinned audio is sliced straight from it, skipping the decode/re-encode round trip that dulls sound a little more at every link of a chain. Takes priority over context_audio; audio_vae is not needed on this path.
audio_vaeoptVAEH3 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_audiooptAUDIOAudio of the previous clip. The tail matching the pinned frames is encoded and pinned alongside them. Ignored when context_latent is wired.

Outputs (3)

NameTypeDescription
conditioningCONDITIONINGconditioning with the pinned context applied
trim_framesINTframes of re-tread for H3 Context Trim
latentLATENTthe clip's latent, passed through - or, with seed_head on, seeded at its head with the pinned steps and carrying a noise mask that holds them during sampling. Wire THIS into the sampler when seeding; otherwise it is identical to the input.