Nodes/CoachBate/CoachBate Shot Loader
ComfyUI Node

CoachBate Shot Loader

The node that runs your whole LTX movie while you sleep

By CoachBate·Created 2 months ago·Updated 6 days ago· 0
CoachBate Shot Loader
    • video_prompt
    • duration_seconds
    • shot_id
    • video_filename_prefix
    • start_image
    • end_image
    • start_image_prompt
    • negative_prompt
    • negative_audio_prompt
    • total_shots
    • start_image_strength
    • end_image_strength
    • end_image_timestamp
    • global_prompt
    • local_prompts
    • segment_lengths
    • h3_ref_image_1
    • h3_ref_image_2
    • h3_ref_image_3
    • h3_ref_image_4
    • h3_ref_image_5
    • h3_ref_image_6
    • h3_ref_audio_1
    • h3_ref_audio_2
    • h3_ref_audio_3
    json_path
    shot_number1
    modeincrement
    framerate24

    Ever stared at a 50-shot shot list and thought "I am not clicking Queue 50 times"? That's the exact problem this node exists to delete. CoachBate Shot Loader reads a shotlist.json file, hands your graph one shot per queue run, and auto-advances to the next one. Pair it with Auto Queue and a 40-shot LTX-2.3 sequence processes itself while you go do something else.

    This is the pack's flagship, and the reason the pack exists at all. The author built it for his own shot-by-shot LTX-2.3 video production, so it's tuned for that world: a clip per shot, start/end frame conditioning, audio prompts, filename prefixes that map straight into VHS save nodes. Note it's a data driver, not a generator - no model weights, no VRAM, no extra downloads. It just feeds values in.

    How it works

    The mechanism is simple and robust: the JSON is read fresh from disk on every run, so you can edit the shotlist mid-queue and the next shot picks up your changes. DONE shots are skipped automatically, and a class-level counter (stored_index) advances one step per execution - the same self-advancing pattern ComfyUI's built-in JSON Array Iterator uses.

    Three modes control the counter: increment (forward, the default), decrement (backward), and fixed (always the same shot, handy for debugging one entry). Missing start/end image files don't crash the run - you get an orange toast and that shot is skipped so the pipeline keeps moving. There's also a POST /coachbate/skip HTTP endpoint that advances past the current shot without a full re-run, which production scripts use to bail on a bad take.

    Inputs that matter

    • json_path - absolute path to your shotlist JSON. The file can be a bare array or wrapped in {"shots": [...]}.
    • mode - increment / decrement / fixed. You'll live in increment.
    • shot_number - 1-based starting position. Seeds the counter on first run, then updates itself.
    • framerate - used to convert segment durations to frame counts. Must match your video generation FPS.

    The outputs

    There are a lot of them, but the ones you'll wire up first: video_prompt and negative_prompt into your CLIP text encoders, duration_seconds into your frame-count math (fps × duration), video_filename_prefix into Save Video, and start_image / end_image through a Load Image into LTX start/end-frame conditioning, with start_image_strength / end_image_strength alongside. total_shots tells you how many non-DONE shots remain.

    The extras - global_prompt, local_prompts, segment_lengths - exist for Prompt Relay / LTX Director-style workflows. local_prompts holds pipe-separated sub-prompts with per-segment durations; segment_lengths converts those to comma-separated frame counts, snapped to the 8n+1 pattern video models expect. Ignore them until you need them.

    Shot list format

    Four fields are required per shot: shot_id, video_filename_prefix, duration_seconds, and video_prompt. Everything else (start_image, strengths, negatives, status, even your own production-tracking fields) is optional, and unknown fields are loaded and ignored - so you can stash metadata without breaking anything. Set "status": "DONE" on a shot to skip it permanently.

    Looping every shot automatically

    1. Set mode to increment.
    2. Open the queue drop-down next to the Queue button and pick Auto Queue.
    3. Click Queue once. The node runs shot 0, advances, re-fires, and keeps going until the queue wraps or you stop it.

    The node even paints a status box on its face - 3/12 001-BATE ENTERS GYM / 16s ➡️ 002-BATE TRAINS - so you can see where you are without opening anything.

    Common issues

    • "All shots have status DONE" error - the node refuses to loop forever. Check your status fields.
    • Orange toast "Skipping: start_image not found" - a conditioning image path is wrong; the shot is skipped rather than failed, so the queue keeps running.
    • Wrong clip length - duration_seconds is seconds, not frames. Multiply by your framerate.

    Installation

    Install via ComfyUI Manager (search "CoachBate") or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/CoachBate/ComfyUI-CoachBate.git
    

    Restart ComfyUI; the node appears under CoachBate in Add Node. The pack has no Python dependencies, so there's nothing heavy to install - just the pack and whatever video model you already run. It's alpha-stage personal tooling, so don't be surprised by the occasional rough edge.

    CategoryCoachBate

    Inputs (4)

    NameTypeDefaultDescription
    json_pathSTRINGAbsolute path to the shotlist JSON file
    shot_numberINT11–9999Shot number to start from (1-based). In increment mode: seeds the starting position on first run. Updated automatically after each shot.
    modeCOMBOincrementfixed: always output shot_index. increment/decrement: advance one shot per run using the stored counter.
    framerateINT241–120Frames per second used to convert segment durations in local_prompts to frame counts.

    Outputs (25)

    NameTypeDescription
    video_promptSTRING
    duration_secondsINT
    shot_idSTRING
    video_filename_prefixSTRING
    start_imageSTRING
    end_imageSTRING
    start_image_promptSTRING
    negative_promptSTRING
    negative_audio_promptSTRING
    total_shotsINT
    start_image_strengthFLOAT
    end_image_strengthFLOAT
    end_image_timestampFLOAT
    global_promptSTRING
    local_promptsSTRING
    segment_lengthsSTRING
    h3_ref_image_1STRING
    h3_ref_image_2STRING
    h3_ref_image_3STRING
    h3_ref_image_4STRING
    h3_ref_image_5STRING
    h3_ref_image_6STRING
    h3_ref_audio_1STRING
    h3_ref_audio_2STRING
    h3_ref_audio_3STRING