Nodes/ComfyUI LC Vision Nodes/LC Vision Shot List πŸ“‹
ComfyUI Node

LC Vision Shot List πŸ“‹

Fill in a form, get the story the Director actually wants

By lonecatone23Β·Created 29 days agoΒ·Updated about 7 hours agoΒ· 10
LC Vision Shot List πŸ“‹
    • story
    • segments
    • warnings
    β—„shot_list{"place": "Evening in a warm, modern city apartment: a small dining table by a large window with the city lights outside, two candles, two plates of pasta and two glasses of red wine.", "setup": "sit across from each other", "cast": [{"name": "Daniel", "who": "man", "look": "in his early forties with short dark hair, light stubble and a navy crew-neck sweater"}, {"name": "Claire", "who": "woman", "look": "in her late thirties with shoulder-length auburn hair and a cream silk blouse"}], "shots": [{"framing": "side view", "subject": "everyone", "move": "still", "action": "They eat quietly, and he pushes his food around his plate without eating.", "speaker": "", "line": "", "after": ""}, {"framing": "close-up", "subject": "Daniel", "move": "still", "action": "He sets his fork down and looks up at her.", "speaker": "Daniel", "line": "They let me go today. Twelve years, and they walked me out with a box.", "after": ""}, {"framing": "close-up", "subject": "Claire", "move": "still", "action": "Her face falls and her eyes fill with tears.", "speaker": "Claire", "line": "Why didn't you call me? I would have come to get you.", "after": ""}, {"framing": "close-up", "subject": "Daniel", "move": "still", "action": "He looks down at the table, his voice breaking.", "speaker": "Daniel", "line": "I didn't know how to tell you. I'm sorry.", "after": ""}, {"framing": "wide shot", "subject": "everyone", "move": "slow push-in", "action": "Claire reaches across the table and takes his hand.", "speaker": "Claire", "line": "Hey. Look at me. We'll get through this together.", "after": "He squeezes her hand and nods, holding back tears."}]}β–Ί

    Nobody tells you that LLM-driven video planning is mostly an input-shape problem. LC Vision Director reads a story best in a very particular form - cast by name, "Cut to ..." for each new shot, the framing, at most one short quoted line per shot. You can write that by hand. Most people won't, and the plans come out mushier because of it.

    LC Vision Shot List πŸ“‹ is the form. Fill in place, cast and one row per shot; out comes the story in exactly that layout. No model, no VRAM, no AI - it's a pure formatter, which makes it the one node in the pack that can't hallucinate at you.

    What it actually does

    There's a hidden JSON string widget on the node and a JavaScript form drawn over it: one card per shot with framing (wide shot, side view, two-shot, medium, close-up, extreme close-up, over the shoulder, from behind, custom), who it's on, camera move (still, slow push-in, pull back, pan, tracking, orbit, handheld), the action, who speaks and the line, plus an "after" box for the end of the shot. The rows are real HTML in a single DOM widget, so it works on the classic canvas and in Nodes 2.0.

    Python then assembles the story: your place line tidied into a sentence; the cast by name with their look in one sentence; then a block per shot - Cut to a close-up of Daniel, framed from the chest up. (the framing gets its subject filled in from your row), a camera-move sentence if you picked one, the action, Daniel says "...", the after-beat. Revisit a shot you already used and it writes "Cut back to". The default node ships filled in with a five-shot dinner scene, a usable template to type over.

    The outputs are the point

    story wires straight into the Director's story input. segments wires into the Director's segments - a suggestion computed with the Director's own timing rules: one per shot, plus one for each ~3.5 seconds of overflow past a 5-second segment, dialogue counted at 2.5 words per second. If you're the type to guess "eh, six segments" and then spend a Sunday re-rendering, take the number.

    warnings is the honest third output, also shown on the node as βœ“ Ready for the Director. when empty. It catches what actually costs you a render:

    • no place line, or no cast
    • a name not starting with a capital letter (the Director finds people by name, so casing matters)
    • a line over 13 words - about ten fits one 5-second segment
    • a speaker who isn't in the cast, or nobody picked to say a line
    • a close-up or medium shot where you never picked who it's on

    Fixing those before you queue fifteen segments beats any prompt trick in this pack.

    Install

    Same pack as the rest of it, and this node is the least demanding piece:

    cd ComfyUI/custom_nodes
    git clone https://github.com/lonecatone23/ComfyUI_LC_Vision_nodes.git
    

    Or Manager β†’ search LC Vision. The pack's install.py exists to get a vision-capable llama-cpp-python in place (the Qwen3VLChatHandler variant lives only in the JamePeng fork and never went to PyPI), but the Shot List imports nothing past the standard library - and the pack loads its modules one at a time, skipping any that fail with a log line. So it comes up regardless of whether the model side works.

    Then restart ComfyUI and hard-refresh your browser. That's from the README's own quick tips and it's the first thing that bites people: the form is JavaScript, and a hard refresh is the only way to pick up changes to the pack's web/ folder. Skip it and you're staring at a raw JSON box wondering where the cards went.

    What goes wrong

    You see JSON, not the form. Stale cached JS. Ctrl/Cmd+Shift+R.

    the shot list is not valid. Undo the last change, or delete the node and add a new one. Something broke the underlying JSON - usually hand-editing the hidden widget or a workflow saved mid-edit. Treat the JSON as an implementation detail, and if the node is wedged, delete it and add a fresh one.

    The story reads like a robot wrote it. By design - it's a formatter. The payoff is that this flat, consistent structure is exactly what the Director's instructions reward: one place, cast by name, a cut per shot, one line per shot. Fix the planning by hand, not the prose.

    The shot count looks high. Check your after boxes: the estimate counts those words too, so a long beat plus a long line can genuinely want three segments. The estimate being right, not wrong.

    It isn't a Director replacement. This writes the story; the Director turns it into CUT/CONTINUE segments with a shared style block and a saved plan. You still need it, and the LC Vision Loader model behind it, downstream.

    CategoryLC Vision

    Inputs (1)

    NameTypeDefaultDescription
    shot_listSTRING{"place": "Evening in a warm, modern city apartment: a small dining table by a large window with the city lights outside, two candles, two plates of pasta and two glasses of red wine.", "setup": "sit across from each other", "cast": [{"name": "Daniel", "who": "man", "look": "in his early forties with short dark hair, light stubble and a navy crew-neck sweater"}, {"name": "Claire", "who": "woman", "look": "in her late thirties with shoulder-length auburn hair and a cream silk blouse"}], "shots": [{"framing": "side view", "subject": "everyone", "move": "still", "action": "They eat quietly, and he pushes his food around his plate without eating.", "speaker": "", "line": "", "after": ""}, {"framing": "close-up", "subject": "Daniel", "move": "still", "action": "He sets his fork down and looks up at her.", "speaker": "Daniel", "line": "They let me go today. Twelve years, and they walked me out with a box.", "after": ""}, {"framing": "close-up", "subject": "Claire", "move": "still", "action": "Her face falls and her eyes fill with tears.", "speaker": "Claire", "line": "Why didn't you call me? I would have come to get you.", "after": ""}, {"framing": "close-up", "subject": "Daniel", "move": "still", "action": "He looks down at the table, his voice breaking.", "speaker": "Daniel", "line": "I didn't know how to tell you. I'm sorry.", "after": ""}, {"framing": "wide shot", "subject": "everyone", "move": "slow push-in", "action": "Claire reaches across the table and takes his hand.", "speaker": "Claire", "line": "Hey. Look at me. We'll get through this together.", "after": "He squeezes her hand and nods, holding back tears."}]}The form's rows as JSON. Fill it in on the node.

    Outputs (3)

    NameTypeDescription
    storySTRINGThe story for LC Vision Director's story input.
    segmentsINTA suggested segment count: one per shot, more where a line or the action needs the time. Plug it into the Director's segments.
    warningsSTRINGWhat to fix in the shot list. Empty when it all looks good.