Nodes/ComfyUI Smart Shot Loop · 智能分镜循环/分镜循环 · 一键生成与视频画廊
ComfyUI Node

分镜循环 · 一键生成与视频画廊

The button, the queue-watcher, and the wall of finished videos

By playboy-dongan·Created 23 days ago·Updated 23 days ago· 1
分镜循环 · 一键生成与视频画廊
      ◄prompt_node_id►
      ◄video_output_node_id►
      ◄timeout_minutes120►

      It generates nothing. It drives everything.

      Here's the bit that confuses people on first contact: ShotLoopGallery has three string/int inputs and no outputs at all. It's an OUTPUT_NODE, so ComfyUI treats it as the end of the graph - but it doesn't save, preview or produce a video itself. It's the driver.

      You drop it near the end of your workflow, tell it which node holds your shot list and which node saves the video, then press the button. It re-submits your graph once per shot, watches the queue, and paints each finished clip into a grid inside the node. Delete the gallery from a running batch and the remaining submissions stop - that's the intent, not an oversight.

      If you're starting fresh, note that this is the 0.1 pair's driver and the pack now ships SmartShotLoop, a single node that folds the prompt source, the controls and the gallery together. The gallery node is still what the retained 分镜循环组件.json sample uses, and it's still handy when you want prompt-source and driver separated. The mechanism is the same code path underneath.

      What the three fields do

      prompt_node_id is the ID of the ShotLoopPrompts node that holds your shots_json. It's a string field, but you don't have to go hunting for the number: clicking it opens a dropdown listing the ShotLoopPrompts nodes in the graph (12: 分镜循环 · 成对提示词), and picking one writes the ID in for you.

      video_output_node_id is the save node whose execution history the gallery reads. Its dropdown lists every node in the graph, so you do have to know which one you want - the usual answer is your SaveVideo, SaveWEBM, or VHS VideoCombine. There's one convenience: if the graph contains exactly one of those three classes, it's selected automatically.

      timeout_minutes (default 120, range 1–1440) is per shot - how long the gallery will wait for one submission to appear in history before giving up and stopping the rest of the batch. A 120-minute default is generous on purpose for slow 1080p video models; tighten it if you're on something fast and want a stuck run to fail early rather than squat.

      Running the node the normal way (ComfyUI's Queue) does nothing interesting - the Python execute() just returns a UI string telling you to press the node's button. That's the author being honest about where the logic lives.

      What happens when you press the button

      The gallery's frontend code snapshots the graph, checks that prompt_node_id really points at a prompt node and that both image_prompt and video_prompt reach the chosen save node's upstream, then refuses to start if ComfyUI's queue isn't empty. From there it submits one shot at a time, each time with a fresh shot_index and a random run_token, and polls /history/<prompt_id> until the run completes. Only then does it pull the video file descriptor out of the save node's outputs (videos, gifs, images descriptors are all accepted, with an mp4/webm/mov/m4v/ogv filename) and render it with a <video> tag pointing at ComfyUI's own /view endpoint.

      Every submission goes through ComfyUI's normal authenticated submit path, temporarily proxied - no API key, no separate client. When the batch ends, the proxies are put back, so other extensions that wrap the same functions keep working.

      Save the workflow afterwards and the gallery comes back on reload: the node stores the per-shot result descriptors (including your title labels) in its properties and re-renders them on load. It stores descriptors, not video - if the files are gone from the server, or you moved the workflow to another machine, you get labels with dead players. And it deliberately doesn't resume generation.

      Install

      One install for the whole pack. ComfyUI-Manager → search comfyui-smart-shot-loop, publisher playboy-dongan, display name ComfyUI Smart Shot Loop · 智能分镜循环. Or:

      cd ComfyUI/custom_nodes
      git clone https://github.com/playboy-dongan/ComfyUI-Smart-Shot-Loop.git
      

      No pip dependencies, no model files. Restart ComfyUI and refresh the browser tab - the buttons, dropdowns and gallery are injected frontend code, so a restart on its own leaves you with three lonely widgets and no gallery. The node menu name is Chinese (分镜循环 · 一键生成与视频画廊); search ShotLoopGallery.

      Where it goes wrong

      "prompt_node_id 应填写分镜提示词节点的 ID" - you pointed it at something that isn't a ShotLoopPrompts node. Use the dropdown.

      "both prompt outputs must be connected upstream" - wire image_prompt and video_prompt into the chain that feeds the save node. A half-connected pair is the most common start-up failure, and the check exists so you don't pay for five copies of the same clip.

      "exactly one video expected, found N" - the save node must emit a single video descriptor. For VHS VideoCombine that means save-output enabled, and for a cloud API video node that returns a URL you'll need the matching download/local-save node in between. VHS temp-directory files also get cleaned up by ComfyUI, which is what makes an old restored gallery go blank.

      Duplicate output paths - the runner aborts when two shots resolve to the same file key, because that means silent overwriting. Wire filename_prefix from the prompt node into the save node and let it do its job.

      Keep the browser tab open and the machine awake for the duration; the cross-tab duplicate lock requires HTTPS or localhost. Nested-subgraph node IDs aren't supported. And with the pack this new - 0.2.0, early October 2026, no community reports yet, tests run against a mocked Comfy API - the third-party save nodes are the part to verify on your own machine before building a big batch on it.

      CategoryShot Loop / 分镜循环

      Inputs (3)

      NameTypeDefaultDescription
      prompt_node_idSTRING—
      video_output_node_idSTRING—
      timeout_minutesINT1201–1440—

      Outputs (0)

      No outputs