MiniMax H3 • LongMedia Director
Stop hand-chaining 5-second H3 clips
- director
- report
MiniMax H3 gives you 4–15 seconds with native audio. The moment you want a minute of something, you're in chaining territory - which in most video models means hand-chaining segment nodes and living with drift at every seam. The LongMedia Director is this pack's answer: one node where you author a shot list, a camera track and an audio policy on an actual timeline, and it compiles all of that into one payload the sampler side executes as a continuous multi-clip run.
If you've used LTX Director, you know the genre.
What it is, and what it isn't
Director generates nothing. is_output_node is false; the run function is a compiler. Your authored document plus the Director-managed media become clip, camera and director plans, packed into one H3_LONGMEDIA_DIRECTOR value - the thing that goes into the director socket of MiniMax H3 • Long Media Setup, where you set control_mode = director.
The point: the timeline document - not a pile of widgets - owns shot timing, prompts, reference roles (REF / FIRST / LAST), camera moves, resolution and TAKE history. Setup keeps memory, sampler mode and decode. Under control_mode = director Director's resolution is authoritative and Setup's width/height are legacy furniture, though explicit Setup media sockets still override Director slots - Setup.image_1 replaces <Picture 1> without touching the rest of your document.
How the mechanism works
The frontend is doing half the job. web/longmedia_director.js replaces the raw director_json widget with an editor: MAIN shots, CAMERA / AUDIO / EMBEDDING tracks, a Program Monitor for reviewing rendered takes, and a resizable TAKE gallery. The JSON field still holds everything - it's the serialized source of truth, and build() never parses it as anything cleverer than "a document to compile."
Timeline mode matters more than it looks. single is one H3 pass. multiclip turns MAIN boundaries into clip boundaries, with prompt/seed/timing per clip and native continuation context carried across neighbours. segmented splits one continuous scene into fixed-duration internal segments to bound VRAM - it is not a storyboard cut, and shots get worse if you author it like one. On the default setup_timeline_mode = auto, Director picks MultiClip execution itself.
Frame-lattice alignment is deliberately not Director's problem - the report literally says h3_frame_lattice_owned_by: LongMedia execution planner. The editor's version-9 default document ships with three 5-second shots at 24fps, so the first thing you'll do is delete two of them.
The fields that matter, and what to wire where
Two widgets, and really only one that matters.
global_prompt is the persistent world/style/character context shared by every shot - the author's own words. Put "same woman, same diner, 1970s Kodachrome" here instead of repeating it into six shot prompts.
director_json is the internal serialized timeline, which the frontend hides behind the editor. Don't hand-edit it unless you mean it: clip and block IDs are what TAKE lineage and selective regeneration hang off.
Outputs are director and report. Wire director into Setup's director input. report is a JSON string and the best debugging surface in the pack - shot/subject/camera-block counts, requested_seconds, used_reference_tokens, and a warnings array. Set audio_mode = lip_sync without Picture 1 and Audio 1 attached and the warning is right there.
Install
Same pack, same steps as every other LongMedia node:
cd ComfyUI/custom_nodes
git clone https://github.com/vizart-vj/ComfyUI-MiniMax-H3-LongMedia
Or search "MiniMax H3 LongMedia" in ComfyUI Manager, then restart. Registry publisher ID noise, release 0.6.41 - and pyproject.toml declares no Python dependencies, rare for a video pack and the reason it doesn't fight with your existing install. What you do need is H3 itself: weights loaded through ComfyUI's core H3 nodes, fed into Setup's clip / vae / audio_vae inputs. This pack wraps core support rather than replacing it.
Start from workflows/MiniMax-H3-LongMedia-Director-Unified.json in the repo - the maintained Director graph.
Where people get burned
You see raw JSON instead of a timeline. The editor is a web/ JS extension, and frontend churn is the classic way those break - the Nodes 2.0 rewrite has been splitting third-party packs for months. If the node renders as a text wall, update the pack or switch frontend.
Restoring a TAKE empties your timeline. That's correct behaviour: a TAKE is a complete editor-state snapshot, and restoring an empty one returns you to empty. Check whether you grabbed a draft before you panic.
A reference starts behaving like a frame anchor. REF, FIRST and LAST are separate contracts. A picture that keeps snapping to frame one is assigned FIRST.
Camera changes read as cuts. CAMERA blocks are framing and movement only. Put continuity in the MAIN prompt; scene-change language inside a camera block gets rendered as a cut.
Takes live under output/longmedia_director/ - take.json, state/director.json, cached clip latents, preview sprites. That's your edit, not just your render - a careless output cleanup costs you the project. And leave ComfyUI's dynamic VRAM on with sampler_mode = auto: the changelog keeps fixing transient CUDA references not released between queued runs, which you'd notice as "the second render in a row OOMs."
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| global_prompt | STRING | Persistent world/style/character context shared by every Director shot. | |
| director_json | STRING | {"version": 10, "kind": "h3_longmedia_director", "project_id": "project-44d4f30b-c63e-40a6-adff-975e7ecba23e", "fps": 24.0, "audio_mode": "auto", "setup_h3_mode": "auto", "setup_timeline_mode": "auto", "segmented_count": 3, "segmented_duration": 5.0, "resolution_source": "base_layer", "resolution": "1920x1080", "megapixel": 0.8, "render_mode": "final", "regeneration": {"mode": "none", "clip_id": null, "request_id": null}, "subjects": [], "shots": [{"clip_id": "shot-2801200c-9464-4848-ba43-759e110c9503", "name": "Shot 1", "prompt": "", "prompt_guidance_mode": "inherit", "duration": 5.0, "cut_marks": [], "seed": null, "subjects": [], "media_subject_id": null, "cast_subject_id": null, "first_frame_anchor": false, "last_frame_anchor": false, "source_in": 0.0, "video_reference_scale": 1.0, "base_kind": "generated", "audio_continuation": "AUTO"}, {"clip_id": "shot-eaa6e940-8d9a-436d-a7ec-f7858c6e9a26", "name": "Shot 2", "prompt": "", "prompt_guidance_mode": "inherit", "duration": 5.0, "cut_marks": [], "seed": null, "subjects": [], "media_subject_id": null, "cast_subject_id": null, "first_frame_anchor": false, "last_frame_anchor": false, "source_in": 0.0, "video_reference_scale": 1.0, "base_kind": "generated", "audio_continuation": "AUTO"}, {"clip_id": "shot-6fed3658-9589-449e-80ff-f77116d995ad", "name": "Shot 3", "prompt": "", "prompt_guidance_mode": "inherit", "duration": 5.0, "cut_marks": [], "seed": null, "subjects": [], "media_subject_id": null, "cast_subject_id": null, "first_frame_anchor": false, "last_frame_anchor": false, "source_in": 0.0, "video_reference_scale": 1.0, "base_kind": "generated", "audio_continuation": "AUTO"}], "camera_blocks": [{"block_id": "camera-76831af6-9c0e-4149-9fe0-fd8f564ed66c", "start": 0.0, "duration": 5.0, "camera": {"shot_size": "Medium Shot", "rig": "Tripod / Locked Head", "camera_body": "Cinematic Neutral", "lens": "Auto / Native Lens", "stabilization": "Rig Native", "movement": "Locked-Off / Static", "speed": "Static", "transition_type": "Continuous / Same Shot", "space_relation": "Same Space", "entity_continuity": "Lock Population / Layout", "transition_to_next": false}, "camera_preset_id": null, "note": ""}, {"block_id": "camera-c78394a6-fbb5-419b-b286-61c30a9ee1dc", "start": 5.0, "duration": 5.0, "camera": {"shot_size": "Medium Shot", "rig": "Tripod / Locked Head", "camera_body": "Cinematic Neutral", "lens": "Auto / Native Lens", "stabilization": "Rig Native", "movement": "Locked-Off / Static", "speed": "Static", "transition_type": "Continuous / Same Shot", "space_relation": "Same Space", "entity_continuity": "Lock Population / Layout", "transition_to_next": false}, "camera_preset_id": null, "note": ""}, {"block_id": "camera-2eb2c70b-19f2-47e7-aee7-b6f34bd500b6", "start": 10.0, "duration": 5.0, "camera": {"shot_size": "Medium Shot", "rig": "Tripod / Locked Head", "camera_body": "Cinematic Neutral", "lens": "Auto / Native Lens", "stabilization": "Rig Native", "movement": "Locked-Off / Static", "speed": "Static", "transition_type": "Continuous / Same Shot", "space_relation": "Same Space", "entity_continuity": "Lock Population / Layout", "transition_to_next": false}, "camera_preset_id": null, "note": ""}], "camera_preset_library": [], "audio_blocks": [], "refmods": [], "extra_tracks": []} | Internal serialized Director timeline. The frontend replaces this raw JSON field with the timeline editor. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| director | H3_LONGMEDIA_DIRECTOR | — |
| report | STRING | — |