Nodes/ComfyUI-Easy-Media/H3 Project Static Prepare
ComfyUI Node

H3 Project Static Prepare

Everything in your H3 project the seed can't change

By yolain·Created 5 months ago·Updated 5 days ago· 224
H3 Project Static Prepare
  • model_loader
  • model_loader_2nd
  • tracks_info
  • project_static
  • previous
  • sampler
  • sigmas
  • sampler_2nd
  • sigmas_2nd
  • PROJECT_STATIC
  • TASK_TRACKS_INFO
  • MODEL
  • MODEL_2ND
  • CLIP
  • VAE
  • AUDIO_VAE
  • PREVIEW_VAE
  • LOCKED_AUDIO
  • SAMPLER
  • SIGMAS
  • SAMPLER_2ND
  • SIGMAS_2ND
  • CONTEXT_SIGMAS_2ND
◄task_start_frame0►
◄task_index0►
◄task_duration_frames1►
◄fps24.00►
◄generation_modemulti_frames►
◄sampling_planlight►
◄sampling_modesingle►
◄run_second_passfalse►
◄has_context_second_passfalse►
◄turbo_hintfalse►

H3 Project Static Prepare has the least glamorous name in the pack and one of the more interesting jobs: it's where a MiniMax H3 MultiTrack project parks everything a seed change shouldn't touch. The class docstring says it in one line - "Resolve seed-independent model, media, and sampling resources."

Why the pack bothers splitting this out

ComfyUI's execution cache asks one question: did my inputs change? Anything downstream of a change re-runs; everything else is skipped. In a segment loop that gets expensive, because the two halves of the chain behave nothing alike. A new seed should re-run sampling; it should not reload the H3 model, re-unpack the CLIP and the two VAEs, re-decode 40 seconds of timeline media, or re-resolve which sampler and sigma schedule your sampling_plan name maps to. Bundle all of that into one node per segment and every seed tweak pays for it six times over.

So easy multitrackProject doesn't execute as one node at all. It builds the whole segment loop as a graph at run time and hands it back to ComfyUI to expand - that's the EasyUse/H3/dev neighborhood appearing in your canvas. This node shows up there in three roles:

  • project_media_prepare - gets tracks_info, loads the shared timeline's images, audio, video and locked audio once, and emits the PROJECT_STATIC bundle.
  • project_model_prepare - gets the model_loader plus the sampling config, and emits MODEL, CLIP, the VAEs and the resolved sampler/sigmas.
  • segment_static_prepare_<i> - one per segment: takes the bundle plus that segment's task_start_frame, task_duration_frames, fps and generation_mode, crops that slice of media, and outputs the TASK_TRACKS_INFO the task-output node reads.

Each pass tags the runtime cache with a status you can read in the log - 首次加载 on a first load, 命中恢复缓存 on a restored hit - and caches per-segment media so stepping through segments doesn't redo the same crop.

The PROJECT_STATIC output is the context-bus pattern in miniature: one wire carrying model, media and decision state downstream instead of twenty. Which brings the usual caveat - a bus tells you nothing about which version of a value is inside it, so the cache status tag is your only readout before blaming sampling for a stale-looking segment.

Inputs and outputs worth knowing

Treat these as visible plumbing, not settings. If you want to change any of them, change them on easy multitrackProject and let it regenerate the expansion.

  • model_loader, model_loader_2nd - FAST_MODEL_LOADER links to the pack's loader node (H3 model, CLIP, video VAE, audio VAE, optional second-pass model). The second loader is optional; both VAEs always come from the first.
  • tracks_info and project_static - the entry points above. The per-segment instance takes project_static from the media instance instead of a fresh timeline, and previous (tooltip: "Optional dependency on the previous saved segment") is there purely to sequence segments.
  • task_start_frame, task_duration_frames, fps, generation_mode (reference / multi_frames / last_frame) - which slice of the timeline, at what rate, in what task type.
  • sampling_plan, sampling_mode (single / dual / selflift), run_second_pass, has_context_second_pass, turbo_hint - the preset lookup. light is the shipped default; presets/h3_sample.json maps each name to samplers and sigmas for Turbo and non-Turbo models.
  • sampler, sigmas, sampler_2nd, sigmas_2nd - manual overrides, and they're raw links, so they only take a real SAMPLER/SIGMAS wire, in pairs. Supply one without its partner and the project errors with "Custom H3 first pass sampling requires both sampler and sigmas." Custom second-pass sigmas also suppress the built-in context schedule.

The fourteen outputs are the payoff for the split: PROJECT_STATIC and TASK_TRACKS_INFO, then the resources - MODEL, MODEL_2ND, CLIP, VAE, AUDIO_VAE, PREVIEW_VAE, LOCKED_AUDIO, SAMPLER, SIGMAS, SAMPLER_2ND, SIGMAS_2ND, and CONTEXT_SIGMAS_2ND, the preset's schedule for a second pass inheriting the previous segment's tail (0.50, 0.30, 0.14, 0.06, 0.0 as shipped). On the cached passthrough branch most come back deliberately None - empty sockets here are the design.

Installing it

Everything ships with the pack:

cd ComfyUI/custom_nodes
git clone https://github.com/yolain/ComfyUI-Easy-Media
# restart ComfyUI

ComfyUI Manager works too - search ComfyUI-Easy-Media. Same author as ComfyUI-Easy-Use, but a much younger pack (1.3.x, September 2026; the project pipeline landed in 1.3.0), so expect the internals to move between releases. The pack declares no Python dependencies of its own; what it really wants is FFmpeg on your PATH before you install, since the same pack merges, saves and subtitles video. Context continuity needs ComfyUI 0.34.0+. For the second pass, an H3 latent upscaler weight file goes in ComfyUI/models/latent_upscale_models/, and the fallback path (upscale_model = None, decode → resize → re-encode) needs ComfyUI-KJNodes.

Where people get burned

"Half the outputs are None." Check which instance you're looking at. Only the model-prepare variant holds the loaders; the media and per-segment variants return None for MODEL and CLIP because nothing consumes them there.

The static split only happens when model_loader is a link. The project checks whether it got a link to a loader node or a plain config dict, and only builds these prepare nodes in the link case - otherwise it resolves the model settings inline. If your project doesn't look like the screenshots, that's usually why. With no linked loader, a missing audio_vae is also a hard error, since video projects need it.

Changing anything static invalidates everything downstream. Swap the checkpoint, change sampling_plan, add an upscaler, move a timeline boundary, and ComfyUI correctly decides the cached work is void - every segment re-runs. That's the tradeoff the split buys you, so set the static stuff once and iterate on seeds and prompts instead.

The odd second-pass resolution is not a bug. upscale_by = 1.250 on 1344×768 gives 1664×960, not 1680×960, because the pack aligns with round(dimension * upscale_by / 32) * 32 - rounding isn't always upward.

Don't hand-edit expanded nodes. ComfyUI rebuilds this subgraph from the project node's settings on the next run, so widget values you type onto an expanded prepare node aren't where the configuration lives.

CategoryEasyUse/H3/dev

Inputs (19)

NameTypeDefaultDescription
model_loaderoptFAST_MODEL_LOADER—
model_loader_2ndoptFAST_MODEL_LOADER—
tracks_infooptTRACKS_INFO—
project_staticoptH3_PROJECT_STATIC_DATA—
previousopt*Optional dependency on the previous saved segment.
task_start_frameoptINT0—
task_indexoptINT0—
task_duration_framesoptINT1—
fpsoptFLOAT24.00—
generation_modeoptCOMBOmulti_frames3 options: reference, multi_frames, last_frame
sampling_planoptSTRINGlight—
sampling_modeoptCOMBOsingle4 options: single, dual, selflift, passthrough
sampleroptSAMPLER—
sigmasoptSIGMAS—
sampler_2ndoptSAMPLER—
sigmas_2ndoptSIGMAS—
run_second_passoptBOOLEANfalse—
has_context_second_passoptBOOLEANfalse—
turbo_hintoptBOOLEANfalse—

Outputs (14)

NameTypeDescription
PROJECT_STATICH3_PROJECT_STATIC_DATA—
TASK_TRACKS_INFOTRACKS_INFO—
MODELMODEL—
MODEL_2NDMODEL—
CLIPCLIP—
VAEVAE—
AUDIO_VAEVAE—
PREVIEW_VAEVAE—
LOCKED_AUDIOAUDIO—
SAMPLERSAMPLER—
SIGMASSIGMAS—
SAMPLER_2NDSAMPLER—
SIGMAS_2NDSIGMAS—
CONTEXT_SIGMAS_2NDSIGMAS—