🎬 Dynamic Scene Director
A JSON scene list that drives the whole loop, one scene per cycle
- flux_prompt
- wan_prompt
- chunk_frames
- image_load_path
- project_json_path
Somewhere between "one long video, chunked" and "a folder of files, batched" there's a third workflow shape: a storyboard - a list of scenes, each with its own prompt, duration, and model-specific text. You want the loop to walk the storyboard one scene per cycle, feeding the right prompt to each model. That's what DynamicSceneDirector is: a state machine that takes a JSON scene plan and turns loop indices into scene directives.
It's the pack's split-workflow orchestrator. You describe the whole video as JSON on cycle 0; it writes that plan to disk; and on every cycle it reads the plan back and hands you the pieces for that scene - prompts, frame count, keyframe path, and the plan's location.
How it works
The agent_json input expects a structure like the default:
{"scenes": [{"scene_id": 1, "duration_seconds": 5.0, "flux_prompt": "A cinematic wide shot...", "wan_prompt": "Camera pans..."}]}
On cycle 0 it parses the JSON, validates it, and saves it as {audio_filename}_plan.json in ComfyUI's output directory. On later cycles it ignores the input entirely and reloads the plan from disk - that's a deliberate design choice so a flaky agent or a changed text field can't corrupt a mid-run storyboard. The scene index is derived directly from the loop index (one scene per cycle), clamped to the scene count, and each cycle returns:
flux_prompt/wan_prompt(STRING) - the per-model texts for this scene.chunk_frames(INT) -ceil(duration_seconds * fps).image_load_path(STRING) - where the keyframe for this scene lives ({audio_filename}_Keyframes/scene_{id}.png).project_json_path(STRING) - the saved plan file, for other nodes to read.
It also updates the pack's step-by-chunk globals so the loop trigger knows when the last scene has rendered.
The inputs that matter
agent_json(STRING, multiline) - the storyboard. The name hints at the intended source: an LLM "agent" that writes the plan. Any JSON-producing node works.audio_filename(STRING, defaultaudio_track) - used to name the plan and keyframe folders, so a batch of audio files gets a matching set of projects.fps(INT, default 12) - converts each scene's seconds into frames.current_loop_index(INT) - the scene selector.
The traps
The JSON is parsed strictly on cycle 0 - a typo raises an error and stops the run, so validate your JSON before you hit queue. And because scene index is loop index, if your scene count and loop count disagree you'll get repeated or clamped scenes rather than an error. Check total_chunks-style feedback in the log on the first run. This node also assumes the Save Scene Keyframe / Load Scene Keyframe pair is doing the actual frame continuity work - the director just points at the paths.
Install
ComfyUI Manager → "comfyui-sequential-batcher", or:
cd ComfyUI/custom_nodes
git clone https://github.com/Meisoftcoltd/comfyui-sequential-batcher
Restart ComfyUI. No model downloads. And the pack-wide rule: run without --highvram.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| agent_json | STRING | {"scenes": [{"scene_id": 1, "duration_seconds": 5.0, "flux_prompt": "A cinematic wide shot...", "wan_prompt": "Camera pans..."}]} | — |
| audio_filename | STRING | audio_track | — |
| current_loop_index | INT | 00–10000 | — |
| fps | INT | 128–60 | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| flux_prompt | STRING | — |
| wan_prompt | STRING | — |
| chunk_frames | INT | — |
| image_load_path | STRING | — |
| project_json_path | STRING | — |