DAELAB - 剧本分镜导入
The small node that turns editor state into a JSON contract
- storyboard_json
Some nodes exist to be the boundary between a UI and the API. This is one of them, and it's worth a couple of minutes of your life because it explains why half the storyboard machinery in this pack is shaped the way it is.
DAELAB - 剧本分镜导入 has one input (storyboard_data, the hidden JSON state of the storyboard editor panel) and one output (storyboard_json). It validates the editor's state and normalises it into a contract that downstream nodes can trust. No model, no API, no network, no cost.
The validation is the value
Read what it refuses to pass through. It parses the JSON, and if the payload contains a table key it converts that table into the storyboard form instead - so the node accepts both the modern table state and the older shot-list shape. Then, for a shot list, it demands a shots array: a dict without one throws "分镜数据必须包含 shots 列表". Each entry has to be a dict or it throws "分镜行格式错误".
And then the detail that tells you this was written by someone who has debugged real workflows: any shot missing an id, or reusing an existing one, gets a fresh UUID assigned. Not an error - a repair. Duplicate IDs in a shot list are the kind of thing that breaks caching, lookups and per-row results in ways that take an afternoon to find, so silently minting new ones is exactly right.
The output is stamped with schema_version: 3. That's the contract. A consumer can check the version and know what it's dealing with, and the parser in this same pack emits version 4 tables for its own output - so if you're wiring old and new nodes together, you're explicitly translating between two schemas, and this node is a translator.
Why it's an output node
The node is marked is_output_node=True. In ComfyUI terms that means it counts as a terminal: queuing a workflow containing it will execute it even if nothing downstream consumes it, and the result sits in the node's own output.
That's useful in a very specific way. It makes this node a save point: queue the graph with it present and you've serialised your current storyboard state through the validation path, in the API prompt's own JSON, in a form you can inspect. If you're building a workflow that hands work between machines or people, that's a cleaner handoff than "trust the widget value".
Where it fits
Two roles in practice.
Feeding legacy consumers. The pack's older storyboard/video nodes speak the shot-list protocol. This node is the adapter between the modern table editor and that protocol, and it deliberately does not claim the old "final prompt reviewed" state - that honesty means a downstream node won't skip a prompt-review step it thinks already happened.
As a debugging checkpoint. When generated rows show up in the wrong place, or results don't line up with rows, dropping this node in and looking at storyboard_json tells you whether the problem is upstream (editor state) or downstream (result mapping) within about a minute. Cheaper than reading the front-end code.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/TeutonicMepheles/ComfyUI-DAELab-Custom-Nodes-Library.git
Restart ComfyUI and refresh the browser tab. The node is V3 (comfy_api.latest), so a ComfyUI core that predates the V3 node API will fail to import the whole pack with No module named 'comfy_api' - the fix is updating ComfyUI, not installing a package with that name. ComfyUI Manager users can search the pack title "ComfyUI-DAELab-Custom-Nodes-Library".
Clone the full repo rather than a single nodes/ subfolder: the root __init__.py does the registration and the web/ directory serves the editor panel that produces storyboard_data in the first place.
Gotchas
storyboard_data is a socketless hidden widget - you're not meant to type into it. If it's empty, the node happily emits {"shots": []} with the schema version attached, which downstream will treat as "zero shots" rather than an error. That silence is a feature when you're building a graph incrementally and a trap when you queue expecting output.
Don't use this node to try to parse a document. It has no upload, no DOCX handling and no column mapping - that's DAELAB.ScriptParser, which is a much bigger node with a much bigger dependency list. This one is the lightweight normaliser you put between an existing editor state and an existing consumer.
Finally, this node won't trigger generation on its own, and it never has. If your graph produces a table and then nothing happens, look for the generation node: this pack splits "organise the tasks" from "spend credits on the tasks" on purpose, and this node is firmly in the first camp.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| storyboard_data | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| storyboard_json | STRING | — |