Nodes/ComfyUI-OldTimeRadio/ Shot Lock (video plan authority)
ComfyUI Node

Shot Lock (video plan authority)

The shot list gets frozen before a single frame renders

By jbrick2070·Created 5 months ago·Updated about 16 hours ago· 7
Shot Lock (video plan authority)
    • patched_ledger_json
    • video_revision
    • shot_report
    • done
    • episode_id
    script_json{}
    audio_done
    video_policy_json{}
    gate_in

    On the video side, OTR_CastLock's job is done by OTR_ShotLock: it's the single ledger['video'] authority - the node that stamps the shot plan into the frozen ledger and declares it final. Every beat gets its engine, its prompt, its clip budget, and that plan is what OTRVideoRenderBatch executes. Like its audio cousins, it exists to make the render deterministic: one decision point, locked before the expensive work starts.

    The clever part is what it's locked against. Two of the three required inputs are gates that force the video plan to respect the audio timeline:

    • script_json - the frozen ledger (from OTR_LedgerFreezeCascade's script_json output).
    • audio_done - the gate from OTR_EpisodeAssembler's out3. Wiring it orders ShotLock after audio timing freezes, so the per-beat clip budget is bound against the real timeline, not a guess. This is the "audio is king" discipline made structural: the shot list can't be planned before the episode's actual duration exists.
    • video_policy_json - the per-role engine selection from OTR_VideoDirector.

    There's an image_done input declared to mirror audio_done (the image-before-video contract), but it's non-blocking in v1 - the local image engine runs in-process and nothing emits it yet. So don't sit waiting for it; the image branch's image_done from OTR_ImageGenDispatcher is what you'd wire if you want the ordering, but v1 won't enforce it. consistency_gate_warn_only is a compatibility-only widget - authored non-empty M4 prompts are always preserved, empty replies use the deterministic template.

    Outputs

    patched_ledger_json (ledger with the video section stamped), video_revision (INT - bumps when the shot plan changes), shot_report, done, and - worth knowing - episode_id, which ShotLock holds as the in-graph authority because it owns the audio-overlaid ledger. Everything that needs to write files per-episode (the stills dispatcher, the composite) can key off it.

    Install and gotchas

    Pack-level install (ComfyUI Manager → ComfyUI-OldTimeRadio, restart; v2.0-alpha). No models - plan logic. The gotcha is wiring discipline: leave audio_done unwired and you lose the timeline-bound guarantee, which is how you end up with beats that don't fit their clips. Wire it, and the clip budget is honest. And remember this node only plans - if the rendered clips look wrong, the fix is upstream in the engine selection (VideoDirector) or the prompts, not here; ShotLock is the authority, not the author.

    CategoryOldTimeRadio/v2/video

    Inputs (4)

    NameTypeDefaultDescription
    script_jsonSTRING{}Frozen ledger JSON (OTR_LedgerFreezeCascade out1 script_json). ShotLock stamps a video section into it.
    audio_doneSTRINGAudio-done gate (OTR_EpisodeAssembler out3). Wiring it orders ShotLock AFTER audio timing freezes so the clip budget is bound against the real timeline. Opaque STRING.
    video_policy_jsonSTRING{}Per-role selection policy from OTR_VideoDirector.
    gate_inoptSTRINGOptional ordering signal (opaque STRING).

    Outputs (5)

    NameTypeDescription
    patched_ledger_jsonSTRING
    video_revisionINT
    shot_reportSTRING
    doneSTRING
    episode_idSTRING