Nodes/ComfyUI-H3-Multishot/H3 Multishot Sampler (one node)
ComfyUI Node

H3 Multishot Sampler (one node)

One node, a whole seamless take instead of a cut sequence

By jlucasmcrell·Created 21 days ago·Updated 2 days ago· 31
H3 Multishot Sampler (one node)
  • model
  • clip
  • video_vae
  • audio_vae
  • start_image
  • reference_images
  • voice_ref
  • upscale_model
  • sigmas
  • master_frames
  • master_audio
  • shots_rendered
  • first_shot_frames
  • first_shot_audio
scriptShot 1 prompt goes here. --- Shot 2 prompt goes here. --- Shot 3 prompt goes here.
shot_count0
width768
height1344
frames_per_shot243
seed0
steps20
seed_per_shottrue
sampler_nameres_multistep
schedulersimple
sampler_override
scheduler_override
self_anchor_voicefalse
output_scale1.00
save_every_shotfalse

The classic one. MiniMax-H3 generates roughly 10-15 second blocks, and if you've ever tried to chain two of them with stock nodes you know what happens: shot 2 re-imagines the scene from text, so the face shifts, the wardrobe drifts, the colour jumps, and what you have is a cut sequence, not a take. H3MultishotSampler is the pack's zero-dependency answer to that - it renders shot after shot and hands each one's last frame to the next as its first frame, using the checkpoint's own trained continuation task (fl2va's image-to-video mechanism), so the join is continuous by construction. Same face, same room, same light - because the next shot starts from an actual rendered picture, not a fresh reading of the prompt.

How the chaining works

Each shot's last frame becomes the next shot's first frame through fl2va's trained I2V path - the conditioning route the model was trained on, not a bolted-on hack. Two cleanups make the join invisible: the duplicated boundary frame is trimmed (one-frame stutter gone), and the seam audio gets a 40ms equal-power weld so the join doesn't dip in loudness. Identity holds through a second mechanism as well: byte-identical text. The prompt writer repeats each character's appearance block verbatim in every shot, so sampling noise around a reworded description can't drift the face. Frame pins the instance; text pins the category.

The inputs that matter

  • script - one prompt per shot, --- on its own line between them (JSON {"prompts": [...]} also accepted). This is where the quality lives. The README's boundary rules are worth reading before you write one: each shot after the first opens holding the previous shot's closing arrangement with ~2 quiet seconds, and a spoken line never straddles two shots.
  • shot_count - 0 = one shot per --- block (leave it). 1-8 forces a total; a short script repeats its last block as a continuation.
  • frames_per_shot - 243 default (~10.1s), 362 is the trained max (~15.1s), on H3's 17k+5 grid.
  • seed_per_shot - leave ON. Measured: per-shot seeds hold the face; one seed for every shot drifted both face and voice.
  • start_image - optional I2V first frame for shot 1 (a real first frame, unlike the memory sampler's same-named input). Later shots keep chaining from previous last frames.
  • reference_images - character refs carried into every shot as <Picture 1>, etc. Bind them in the prompt: "She looks like the woman in <Picture 1>." Verified on ref2va.
  • voice_ref - an audio anchor (<Audio 1>) that pins the voice across the chain. Also ref2va territory.
  • self_anchor_voice - after shot 1 renders, its own audio becomes the reference for later shots. No file needed; write shot 1 so the character speaks a clean solo line.
  • output_scale / upscale_model - post-decode resizing / real upscale. Read the tooltip carefully: with an upscale model wired, 1.0 does not mean off - it means don't correct, so you get the raw 4x. The console prints the projected size when the model loads; at 1344x768 a 4x upscale is 22GB a shot in system RAM.

Outputs: master_frames and master_audio (the joined take, seams trimmed), shots_rendered, and first_shot_frames / first_shot_audio so you can judge shot 1 before the chain commits.

Install and reality check

cd ComfyUI/custom_nodes
git clone https://github.com/jlucasmcrell/ComfyUI-H3-Multishot

or search H3 Multishot in ComfyUI-Manager (Registry: comfyui-h3-multishot). ComfyUI v0.30.0+, no pip dependencies. Models: checkpoint in models/diffusion_models/, encoder + VAEs in text_encoders/ and vae/. GGUF users also install ComfyUI-GGUF.

The pack is young - effectively zero community footprint on Reddit as of writing - and its README is refreshingly honest about limits: audio dulls slightly per hop on long chains (restart chains on scene cuts), and the texture ratchet is ~1.05-1.3x per join depending on settings. For 3-4 shot scenes the joins reviewed as one continuous take. It's a meticulous solo project (jlucasmcrell / joeygambino), free, and the docs are the best part of it - read the prompting rules before you queue, and a word clipped at a join is almost always your script, not the sampler.

Categorysampling/minimax

Inputs (24)

NameTypeDefaultDescription
modelMODEL
clipCLIP
video_vaeVAE
audio_vaeVAE
scriptSTRINGShot 1 prompt goes here. --- Shot 2 prompt goes here. --- Shot 3 prompt goes here.One prompt per shot, separated by --- on its own line. JSON {"prompts": [...]} also accepted.
shot_countINT00–8The TOTAL number of shots - not shots per prompt. Leave it at 0 and the script decides: one shot per --- block, which is what you want for a written scene. 1-8 forces the total instead: extra blocks are dropped, and if the script is short the last block repeats as a continuation. Every shot renders.
widthINT76832–4096
heightINT134432–4096
frames_per_shotINT2435–481Frames at 24fps on H3's 17k+5 grid (243 = ~10.1s; 362 = trained max ~15.1s; beyond is untested).
seedINT00–18446744073709550000
stepsINT201–50
seed_per_shotBOOLEANtrueLeave ON. Measured: varying the seed per shot holds the face across the chain; using one seed for every shot made BOTH the face and the voice drift. Identity lives in the conditioning, not the seed.
start_imageoptIMAGEOptional first frame (I2V). Shot 1 starts from this image; later shots continue chaining from the previous shot's last frame as usual. Leave unconnected for pure text-to-video.
reference_imagesoptIMAGEOptional SUBJECT/CHARACTER reference images (batch = multiple refs, e.g. via Batch Images), carried into EVERY shot as <Picture 1>, <Picture 2>, ... - distinct from start_image (which only seeds the I2V chain frame). Bind them in each shot's prompt: 'She looks like the woman in <Picture 1>.' Verified on the ref2va checkpoint.
voice_refoptAUDIOOptional VOICE ANCHOR carried into EVERY shot as a reference audio (<Audio 1>). Feed a clean solo line of the character - e.g. a slice of stage A's output - and the voice is PINNED across the chain instead of re-performed from text (verified: control drifted, voice-ref held). Bind it in each shot's prompt: 'Her voice is the voice in <Audio 1>.' Works with keyframe chaining via the refs+keyframes merge patch. NOTE: verified on the ref2va checkpoint; fl2va was not trained with reference rows, so wire the ref2va model when using this.
sampler_nameoptCOMBOres_multistepSampling algorithm. res_multistep is the default and what every measurement in the docs used.
scheduleroptCOMBOsimpleSigma schedule. simple is the default and what the docs measured.
sampler_overrideoptSTRINGLink a sampler NAME here (e.g. from H3 Studio Controls) to drive this widget from one master source. Overrides sampler_name when connected.
scheduler_overrideoptSTRINGLink a scheduler NAME here to single-source it. Overrides scheduler when connected.
self_anchor_voiceoptBOOLEANfalseAUTOMATIC voice identity: after shot 1 renders, its own audio becomes the reference (<Audio 1>) for every later shot - the voice the model actually performed is pinned, no file needed. Write shot 1 so the character speaks a clean solo line. An external voice_ref, if connected, takes priority. Use with a ref2va checkpoint.
output_scaleoptFLOAT1.001–4FINAL size multiplier, applied after decode. No upscale model: a lanczos resize, 1.0 is off. WITH a model: the model runs at its OWN fixed factor (usually 4x) and this brings the result to source x this value, so 2.0 on a 4x model gives 2x, not 8x. CAREFUL - 1.0 does NOT mean off once a model is wired; it means do-not-correct, so you get the full 4x. At 1344x768 that is 5376x3072: 94 MB a frame, 22 GB a shot, and every shot stays in system RAM until the master is joined. The console prints the projected size when the model loads - read it. Adds resolution, not detail. Works with every continuity mode; the bank still stores base-resolution clips.
upscale_modeloptUPSCALE_MODELOptional. Wire ComfyUI's Load Upscale Model here (ESRGAN and friends) to synthesise detail instead of merely resizing. Applied per shot after decode, at the model's own factor; if output_scale is also set, the result is resized to land exactly there. Slower than output_scale and it invents texture - on a chain, judge it on the LAST shot, where any texture ratchet is worst.
sigmasoptSIGMASOptional custom sigma schedule, replacing sampler/scheduler + steps entirely. Some turbo LoRAs ship a schedule they need in order to work at all. When this is connected the 'steps' and 'scheduler' widgets are IGNORED - the step count becomes len(sigmas)-1 - and the console says so. The two-pass upscale split is taken as a fraction of the supplied schedule.
save_every_shotoptBOOLEANfalseWrite EVERY shot to output/video/H3_SHOTS/ the moment it decodes, in addition to the master. Insurance for long chains: everything that fails after the last shot - a mux OOM, a full disk, a cancelled tab - otherwise destroys the whole render at once. Shots are written BEFORE the seam trim, so consecutive files overlap by ~1s; the master is still the clean join. Costs one file write per shot.

Outputs (5)

NameTypeDescription
master_framesIMAGE
master_audioAUDIO
shots_renderedINT
first_shot_framesIMAGE
first_shot_audioAUDIO