MiniMax Director
Direct on a timeline
- clip
- vae
- audio_vae
- positive
- latent
- prompt
- report
If you've actually rendered with MiniMax H3 - the 33B omni-modal video model that makes picture and stereo audio in one pass - you know the pain: everything has to fit into one structured prompt, the shot list, camera moves, who speaks, what they say, every reference. One misplaced token and you're burning another long render on a shot you already knew was wrong. MiniMax Director is the fix: lay out shots, camera moves and audio cues as blocks on a timeline, and the node compiles the whole piece into the exact prompt H3 reads, then hands the sampler its conditioning and a clip length it will accept.
The idea isn't new - LTXDirector got there first, and this README credits WhatDreamsCost outright. But this isn't a port, and the README is careful to say so: LTX has no notion of a shot list, so Director has to inject keyframes into latent space. H3's text encoder is a 32B vision-language model that parses a timeline in plain text - "Timeline: [0s-1s] wide shot, dolly slowly in" - so the interesting work is producing that text correctly rather than injecting guides. The core is pure Python with no tensors, and compiles in a fifth of a second on a laptop.
How it works
The director doesn't reimplement H3 - it resolves ComfyUI's built-in MiniMaxH3ImageToVideo / MiniMaxH3ReferenceToVideo nodes by introspection, so an upstream signature change surfaces as a clear message instead of a stack trace. The path is picked automatically: no files means text-to-video, a block used as first frame/last frame means image-to-video, anything else means reference-to-video. There are no reference or keyframe sockets - every file comes off the timeline.
The WHO & WHAT tab (the cast input) is where H3's picture-plus-voice nature shows: one card per thing the prompt names - person, costume, prop, place - holding its face, its voice, and how much survives from a reference. A face swap folds a card into its target instead of adding a second person.
Everything lands on H3's frame lattice: clip lengths must satisfy length % 17 == 5 at 24fps - 5, 22, 39, 56, 73, 90, 107, 124 frames. The editor snaps durations up while you build, so the timeline you arrange is the clip that renders.
The inputs and outputs that matter
You barely touch these - the timeline editor and cast tab hold your real work. The three you'll set:
- timeline - the whole film as JSON, edited in the node's web UI. Shots, camera moves, audio cues, references.
- cast - the WHO & WHAT document; one card per named thing, and the only place a file is described.
- ref_image_size -
match(default) ormax. Per the tooltip: "How reference images are sized; 'max' is slower but keeps identity." Fiddle with it when a reference face comes back generic.
width/height default to 1344×768; clip, vae and audio_vae come from your loaders. Two VAEs is not a mistake - H3's audio decodes separately.
Four outputs, each wiring somewhere obvious: positive (CONDITIONING) and latent (LATENT) into the sampler - the latent carries the lattice-snapped frame count, which is why there's no length socket - then prompt into MiniMaxDirectorPrompt and report into MiniMaxDirectorReport. The shipped workflow wires all four for you.
Installing it
The pack has no Python dependencies beyond ComfyUI itself, and it ships as a complete workflow - the graph around the nodes is the product.
cd ComfyUI/custom_nodes
git clone https://github.com/imbutus/ComfyUI-MiniMaxDirector.git
Restart, then it's ComfyUI Manager's "ComfyUI-MiniMaxDirector" if you prefer. It needs ComfyUI 0.31.0+ (the Turbo switch uses ModelSamplingAV). Then four weights from Comfy-Org/MiniMax-H3, named exactly as the workflow asks or your loaders show empty dropdowns: the int8 pruned diffusion model into models/diffusion_models/, the qwen3vl-32B text encoder into models/text_encoders/, and two VAEs into models/vae/. Finally drag examples/minimax-director.json onto the canvas.
Gotchas that'll bite
- Filenames matter. ComfyUI matches loaders to files by name; a renamed copy shows as an empty dropdown, not an error.
- The lattice. Off-lattice durations snap up, so a block may render a touch long - read the report panel before queueing.
- Keyframes and references are mutually exclusive per MiniMax's own docs; the linter flags a timeline holding both.
- The H3 weights themselves sit under MiniMax's community licence, which excludes the US, EU, UK and Korea - worth a glance before you commit.
- The workflow's Upscale switch needs a separate pack; with it missing you get a Missing Node Types dialog - expected, harmless while the switch is off.
The one genuine takeaway: this pack is young and its Turbo 4-step path is a v0.1 preview (weak audio, weak fast motion - turn it off for finals). But as a way to actually direct H3 instead of praying at a prompt box, nothing else on the shelf does this yet.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | — | |
| vae | VAE | — | |
| timeline | STRING | { "version": 1, "fps": 24, "duration": 124, "global_prompt": "", "shots": [], "moves": [], "cues": [], "references": [] } | — |
| width | INT | 134432–16384 | — |
| height | INT | 76832–16384 | — |
| ref_image_size | COMBO | match | How reference images are sized; 'max' is slower but keeps identity. |
| castopt | STRING | { "version": 1, "speech": true, "cards": [] } | Everything the prompt names -- people, props, costumes, places -- and the one place a file is described. Edited in the director's WHO & WHAT tab. |
| audio_vaeopt | VAE | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| positive | CONDITIONING | — |
| latent | LATENT | — |
| prompt | STRING | — |
| report | STRING | — |