Muse Director V10
One node to direct a whole LTX 2.3 video with a timeline
- model
- clip
- audio_vae
- vae
- spatial_upscaler
- bg_audio
- base_model
- optional_latent
- ref_images
- last_chunk_frames
- audio
- stage1_frames
- seed_hunt_preview_1
- seed_hunt_preview_2
- seed_hunt_preview_3
- seed_hunt_preview_4
- seed_hunt_audio_1
- seed_hunt_audio_2
- seed_hunt_audio_3
- seed_hunt_audio_4
- reference_image
The name tells you what it is: this is the node that directs. Muse Director V10 is a single custom node that takes LTX 2.3 AV (the 22B video+audio model from Lightricks) and turns a drag-and-drop timeline into a finished, long-form video clip - per-segment prompts, speech, ambient audio, lipsync, and a character that stays the same person from the first frame to the last. If you've ever stitched five LTX generations together in ComfyUI and watched the face drift or the scene cut hard at every seam, this is aimed at you.
It's not a beginner's first node - it expects a real VRAM budget and a model you've already got running. But if your goal is "90 seconds of coherent talking-head video with matching audio, without hand-wiring a hundred nodes," nothing else in the open-source stack does it in one graph.
How it works
LTX 2.3 can't natively render minutes of video, so Director does what every long-form workflow does: it splits the timeline into overlapping chunks, samples each one, and locks the tail of the previous chunk into the start of the next via carry frames (carry_frames, default 73 ≈ 3s at 24fps) so the seam disappears. Chunks can align to your timeline segments (auto_chunk_by_segment) so a "cut" lands where you put it instead of straddling a boundary.
Under the hood it runs a two-stage pipeline: a cheap low-res Stage 1 draft (8 steps, euler), then a Stage 2 pass that upscales and refines it (stage2_denoise 0.42). The distilled model runs at CFG 1.0, which silently kills the classic negative-prompt branch - so the node routes negative prompts through NAG (Normalized Attention Guidance) via KJNodes' LTX2_NAG instead. That's why negative_prompt and nag_scale exist.
The identity piece is the clever part. Drop up to three character images into the timeline's character-card panel and pick a reference_mode. Ghost Mask (End) appends the photos as hidden guide frames past the end of each chunk, then crops them off before decode - the model sees real reference photos as identity anchors without them ever appearing in your output. Licon MSR (Prefix) is the newer IC-LoRA identity guide (via ComfyUI-LTXVideo), injected at the front; it needs vae connected. Either way, tag a slot in a prompt with @ref1/@ref2/@ref3 to say which character appears in that segment.
The inputs and outputs that matter
The required inputs are the full LTX stack: model (with LoRAs applied), clip, audio_vae, vae, and spatial_upscaler. Most people wire loaders → this node → video combine and never touch the rest. Optional ref_images adds non-character reference material (an object, a set), and bg_audio mixes ambience under everything at bg_volume.
Outputs: last_chunk_frames (your finished clip - wire it into a VHS Video Combine), audio (the mixed track), stage1_frames (a debug view of the draft pass), four seed_hunt_preview_N/seed_hunt_audio_N pairs, and reference_image (handy for color-matching the result to the source photo).
The most useful feature for LTX specifically is Seed Hunt - LTX 2.3 is far more sensitive to seed than to prompt wording, so flip seed_hunt on, watch four cheap Stage 1 candidates, then flip the matching use_seed_hunt_N on. The node carries that candidate's actual cached latent into Stage 2, so what you previewed is what you get. The cache lives in memory - restart the server and it falls back to re-rolling with the widget's seed.
Installing it
ComfyUI Manager (search "Muse Director V10"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/muse-collective-26/muse-director-v10-final
pip install av torchaudio soundfile
Then restart. You'll also need three companion packs - VideoHelperSuite (saving/preview), ComfyUI-LTXVideo (Licon MSR mode), and KJNodes (NAG) - plus the model files: the LTX 2.3 distilled transformer (diffusion_models/), video and audio VAEs (vae/), the Gemma 3 text encoder (text_encoders/), the spatial upscaler (latent_upscale_models/), and the talking-head LoRA for lipsync. Download links are in the README; budget several GB before anything runs.
Gotchas
- Licon MSR crops with the stock
LTXVCropGuides, notMuseCropGuides- the node warns about this, and it's a real trap: MSR's guides sit at the front, Ghost Mask's at the back, so the crop needs to know which end. - Ghost Mask artifacts near the chunk tail. If you see faint hallucinated junk in the last few visible frames, raise
ghost_anchor_buffer(default 2) - the developer hit exactly this while debugging. - Echoed voice in generated-audio mode.
enable_ambient_passruns a second audio pass that watches the video for context; it can duplicate speech faintly. Flip it off to test. [SPEECH]and[SOUNDS]tags must be uppercase - lowercase is silently ignored.single_stage_modeis experimental - it skips Stage 2 and samples once at full res, and the author hasn't A/B'd it. Keep the default unless you know why you're switching.- Use individual angle shots per character slot, not one composite reference sheet - a multi-panel sheet gets resized as one image and hurts identity fidelity.
Inputs (92)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| clip | CLIP | — | |
| audio_vae | VAE | — | |
| vae | VAE | — | |
| spatial_upscaler | LATENT_UPSCALE_MODEL | — | |
| start_second | FLOAT | 0.000–3600 | — |
| end_second | FLOAT | 10.000–3600 | — |
| duration_seconds | FLOAT | 10.000–3600 | — |
| start_frame | INT | 00–86400 | — |
| end_frame | INT | 2400–86400 | — |
| duration_frames | INT | 2401–86400 | — |
| timeline_data | STRING | {} | — |
| local_prompts | STRING | — | |
| segment_lengths | STRING | — | |
| global_prompt | STRING | — | |
| guide_strength | STRING | — | |
| epsilon | FLOAT | 0.00100–1 | — |
| frame_rate | FLOAT | 24.001–120 | — |
| display_mode | COMBO | seconds | 2 options: seconds, frames |
| custom_width | INT | 96064–4096 | — |
| custom_height | INT | 54464–4096 | — |
| resize_method | COMBO | maintain aspect ratio | 5 options: maintain aspect ratio, stretch to fit, crop, pad, pad green |
| divisible_by | INT | 321–256 | — |
| img_compression | INT | 180–51 | — |
| generate_audio | BOOLEAN | true | LTX generates ambient/sfx audio from [SOUNDS] prompts. |
| custom_audio_on | BOOLEAN | false | Use audio file(s) from the AUDIO timeline track. |
| lipsync | BOOLEAN | true | Sync mouth movements to custom audio. Requires Custom Audio ON and talking head LoRA. |
| motion_guide_on | BOOLEAN | true | Use motion guide segments from the timeline. |
| chunk_duration_seconds | FLOAT | 10.02–120 | — |
| auto_chunk_threshold | FLOAT | 10.00–3600 | — |
| auto_chunk_by_segment | BOOLEAN | false | When ON, chunk boundaries automatically match your timeline segment boundaries exactly — one chunk per segment, never straddling a segment. chunk_duration_seconds and auto_chunk_threshold are ignored while this is on. When OFF (default), chunking works as before (fixed chunk_duration_seconds, segments may straddle a chunk boundary). |
| carry_frames | INT | 731–240 | Reference frames from previous chunk locked at chunk start. 73 ≈ 3s at 24fps. |
| carry_strength | FLOAT | 1.000–1 | — |
| crossfade_frames | INT | 00–120 | — |
| ic_lora_name | COMBO | None | 1 options: None |
| ic_lora_strength | FLOAT | 1.00-10–10 | — |
| stage1_steps | INT | 81–50 | — |
| stage2_steps | INT | 41–50 | — |
| stage2_denoise | FLOAT | 0.420–1 | — |
| cfg | FLOAT | 1.00–20 | — |
| single_stage_mode | BOOLEAN | false | ON: skip Stage 2 (upscale + refine) entirely and sample once, directly, at full target resolution — stage1_steps becomes the single pass's full step count (raise it accordingly; 8 is a draft-only value meant for the two-stage flow). Seed Hunt is ignored while this is on, since there's no Stage 2 for a scouted candidate to be refined into. |
| seed | INT | 420–18446744073709550000 | — |
| filename_prefix | STRING | muse | — |
| bg_volume | FLOAT | 1.000–2 | — |
| stage1_sampler | COMBO | euler | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| guide_scale_by | FLOAT | 0.500.01–8 | — |
| stage2_sampler | COMBO | euler | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| guide_scale_by_s2 | FLOAT | 1.000.01–8 | — |
| guide_upscale_method | COMBO | bicubic | 5 options: bicubic, bilinear, nearest-exact, area, bislerp |
| guide_image_attn_strength | FLOAT | 1.000–1 | — |
| guide_crop | COMBO | center | 2 options: center, disabled |
| guide_auto_snap_ic_grid | BOOLEAN | true | — |
| guide_use_tiled_encode | BOOLEAN | false | — |
| guide_tile_size | INT | 25664–512 | — |
| guide_tile_overlap | INT | 6416–256 | — |
| timeline_ui | STRING | — | |
| seed_hunt | BOOLEAN | false | ON + no candidate chosen: run a 4-seed Stage-1-resolution preview instead of the full pipeline. ON + one use_seed_hunt_N chosen: commit to that candidate — Stage 2 refines its actual cached latent instead of regenerating Stage 1 from scratch. |
| seed_hunt_steps | INT | 61–50 | — |
| seed_hunt_scale | FLOAT | 0.250.05–1 | Unused as of 1.0.4 — Seed Hunt now scouts at Stage 1's real resolution automatically (so the picked candidate's actual latent can carry forward into Stage 2). Kept as a widget only so older saved workflows still load correctly. |
| seed_hunt_1 | INT | 10–18446744073709550000 | Unused as of 1.0.4 — scouting now draws a fresh random seed for each candidate every run instead of reusing these fixed values (the actual latent carries forward on commit, so the seed number no longer needs to be fixed or reproducible). |
| seed_hunt_2 | INT | 20–18446744073709550000 | — |
| seed_hunt_3 | INT | 30–18446744073709550000 | — |
| seed_hunt_4 | INT | 40–18446744073709550000 | — |
| use_seed_hunt_1 | BOOLEAN | false | — |
| use_seed_hunt_2 | BOOLEAN | false | — |
| use_seed_hunt_3 | BOOLEAN | false | — |
| use_seed_hunt_4 | BOOLEAN | false | — |
| ghost_anchor_buffer | INT | 20–20 | Ghost Mask (End) only. Extra empty latent frames inserted between the real visible content and the hidden reference tail, pushing the anchor further from the last visible frames. 2026-07-29/30 debugging found quality degradation (hallucinated overlay content) building up in the final ~6-12 visible frames right before the anchor, on a clip with 0 buffer. Still padding/crop only — never decoded, so raising this costs a little extra compute per chunk but no visible content. |
| enable_ambient_pass | BOOLEAN | true | ON (default): run the second, LoRA-free ambient/SFX audio pass and layer it under the main speech, in both generated-audio and custom-audio modes — needed because the talking-head LoRA suppresses ambient sound in the main pass regardless of audio mode. OFF: skip it entirely (faster; main pass audio only, no separate ambient layer) — useful for testing whether this pass is the source of duplicated/echoed speech in the background, since it does watch the actual talking video as visual context. |
| bg_audioopt | AUDIO | — | |
| base_modelopt | MODEL | Base model without talking-head LoRA. Connect the UNETLoader output directly here so the ambient audio pass generates sounds without speech. | |
| optional_latentopt | LATENT | Connect a latent to override the auto-generated empty one for chunk 1 only. Ignored if its shape doesn't match the expected chunk-1 shape, or on chunk 2+. | |
| automation_startopt | FLOAT | Automation (connection-only). Start time in SECONDS. Overrides the panel start when connected. | |
| automation_endopt | FLOAT | Automation (connection-only). End time in SECONDS. When connected (and duration is not), the render length is derived from start..end. | |
| automation_durationopt | FLOAT | Automation (connection-only). Duration in SECONDS. Overrides the panel duration and sets the render length when connected. | |
| segment_override_1opt | STRING | Overrides segment 0's prompt text if connected and non-empty. | |
| segment_override_2opt | STRING | Overrides segment 1's prompt text if connected and non-empty. | |
| segment_override_3opt | STRING | Overrides segment 2's prompt text if connected and non-empty. | |
| segment_override_4opt | STRING | Overrides segment 3's prompt text if connected and non-empty. | |
| segment_override_5opt | STRING | Overrides segment 4's prompt text if connected and non-empty. | |
| segment_override_6opt | STRING | Overrides segment 5's prompt text if connected and non-empty. | |
| segment_override_7opt | STRING | Overrides segment 6's prompt text if connected and non-empty. | |
| segment_override_8opt | STRING | Overrides segment 7's prompt text if connected and non-empty. | |
| reference_modeopt | COMBO | OFF | OFF: no character-reference guide. Ghost Mask (End): appends the timeline's character-card images + ref_images as hidden guide frames past the end of the clip, then crops them off. Licon MSR (Prefix): real IC-LoRA identity guide injected as a prefix — requires vae connected and ComfyUI-LTXVideo installed; crop downstream with the stock LTXVCropGuides node, not MuseCropGuides. |
| ref_imagesopt | IMAGE | Extra reference image(s) (e.g. an object, not a character) — a single image or a batch. Appended after the timeline's character-card images. | |
| reference_strengthopt | FLOAT | 1.000–5 | Guide strength applied to the character/ref reference images. |
| msr_prefix_framesopt | INT | 659–200 | Licon MSR (Prefix) only. Pixel-frame budget for the reference slideshow, shared across however many identity images + background are provided — more images means less budget per image unless you raise this. Should be 1 + a multiple of 8 (LTX's VAE frame rule); other values get floored to the nearest valid count automatically. |
| negative_promptopt | STRING | Text to steer generation away from (e.g. 'moles, blemishes, skin spots'). Requires comfyui-kjnodes' LTX2_NAG node. Empty = no effect. | |
| nag_scaleopt | FLOAT | 11.00–100 | Strength of the negative-guidance effect. 0 disables NAG entirely. |
| nag_alphaopt | FLOAT | 0.250–1 | — |
| nag_tauopt | FLOAT | 2.50–10 | — |
| nag_bypassopt | BOOLEAN | false | Hard kill-switch — when ON, NAG is never touched at all, regardless of nag_scale or negative_prompt. Checked first, before anything else. |
Outputs (12)
| Name | Type | Description |
|---|---|---|
| last_chunk_frames | IMAGE | — |
| audio | AUDIO | — |
| stage1_frames | IMAGE | — |
| seed_hunt_preview_1 | IMAGE | — |
| seed_hunt_preview_2 | IMAGE | — |
| seed_hunt_preview_3 | IMAGE | — |
| seed_hunt_preview_4 | IMAGE | — |
| seed_hunt_audio_1 | AUDIO | — |
| seed_hunt_audio_2 | AUDIO | — |
| seed_hunt_audio_3 | AUDIO | — |
| seed_hunt_audio_4 | AUDIO | — |
| reference_image | IMAGE | — |