Nodes/Zura Nodes/Zura V3 · Assemble shots
ComfyUI Node

Zura V3 · Assemble shots

The Node That Stitches Your Multicam Shots Back Together

By ZURAVFX·Created 22 days ago·Updated about 16 hours ago· 1
Zura V3 · Assemble shots
  • source_frames
  • angle_1
  • angle_2
  • angle_3
  • angle_4
  • angle_5
  • angle_6
  • angle_7
  • angle_8
  • angle_9
  • shot_1
  • shot_2
  • shot_3
  • shot_4
  • shot_5
  • shot_6
  • shot_7
  • shot_8
  • shot_9
  • shot_10
  • shot_11
  • shot_12
  • shot_13
  • shot_14
  • shot_15
  • shot_16
  • shot_17
  • shot_18
  • shot_19
  • shot_20
  • shot_21
  • shot_22
  • shot_23
  • shot_24
  • shot_25
  • shot_26
  • shot_27
  • shot_28
  • shot_29
  • shot_30
  • shot_31
  • shot_32
  • shot_33
  • shot_34
  • shot_35
  • shot_36
  • shot_37
  • shot_38
  • shot_39
  • shot_40
  • shot_41
  • shot_42
  • shot_43
  • shot_44
  • shot_45
  • shot_46
  • shot_47
  • shot_48
  • shot_49
  • shot_50
  • shot_51
  • shot_52
  • shot_53
  • shot_54
  • shot_55
  • shot_56
  • shot_57
  • shot_58
  • shot_59
  • shot_60
  • scene_frames
  • IMAGE
◄plan_json—►

Zura V3 · Assemble shots is the least glamorous node in the pack and the one you'll probably never wire by hand - which is exactly why it's worth understanding. When a multicam render comes out with shots in the wrong order, or one shot flashing to the source camera for twelve frames, this is the node that did it.

Its job: take the shot plan, take a pile of rendered takes, and return one frame sequence of exactly the source length.

Inputs

Two are required. source_frames is the decoded 24 fps source clip. plan_json is the plan string the angle gallery produced - it carries frame_count and frames_per_shot, which are the ruler this node measures everything on.

Then it accepts angle_1…angle_9 and shot_1…shot_60 as optional images, plus scene_frames. The distinction matters: an angle_N input is a full-clip take that gets sliced, while a shot_N input is already trimmed to that shot and is used whole. That's how the pack avoids re-generating an angle that appears in four separate shots - the H3 node renders it once and lets this node cut it up.

scene_frames gives the assembler a new-scene guide to align to; if it's present it's also the base frame sequence that original-camera shots are cut from, instead of the source.

The single output is IMAGE. Wire it to your video save node.

How it works

For each shot in the plan it picks its source: an explicit shot_N take if you connected one, else the source (or scene guide) for angle 0, else the matching angle_N take. It then concatenates and asserts the result is exactly frame_count frames long.

The bit that surprises people is the resolution handling. Before assembly it looks at one example frame - scene_frames if present, otherwise the first connected angle or shot - and if the base sequence is a different shape it centre-crops the base to match that aspect ratio, then bilinear-resizes. This isn't the node making aesthetic decisions; it's matching the generated canvas so the concat doesn't blow up. Final output size is still your business downstream in a plain ImageScale.

Angle takes also have to be long enough. If you connected an angle_N take shorter than the source, you get Angle N did not render enough frames for shot N (start:stop) - which in practice means the render failed partway, not that you mis-wired something.

Do you need to install it separately?

No. It ships in the same pack:

cd ComfyUI/custom_nodes
git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes

Restart, done. Optional extras live in requirements.txt (requests, yt-dlp, ultralytics, face-alignment) and only matter for the parts of the pack that detect or download things.

When you'd actually reach for it

Zura V3 · H3 multicam render builds this node internally as part of its expanded graph, so in the normal flow you never touch it. You'd wire it yourself in two situations: you're hand-rolling the render branch and want the same assembly logic, or you're debugging. If you are debugging, feed it the source and the plan and exactly the takes you expect, and check that original-camera shots reproduce the source frames bit-for-bit. They should - the tests in the repo do precisely that assertion, checking that a source frame inside a 0 shot survives assembly unchanged.

One trap: assembly is strict on length but not on content, so a take rendered from the wrong angle will assemble cleanly and just look wrong. It will not save you from a bad plan.

CategoryZura/video/advanced

Inputs (72)

NameTypeDefaultDescription
source_framesIMAGE—
plan_jsonSTRING—
angle_1optIMAGE—
angle_2optIMAGE—
angle_3optIMAGE—
angle_4optIMAGE—
angle_5optIMAGE—
angle_6optIMAGE—
angle_7optIMAGE—
angle_8optIMAGE—
angle_9optIMAGE—
shot_1optIMAGE—
shot_2optIMAGE—
shot_3optIMAGE—
shot_4optIMAGE—
shot_5optIMAGE—
shot_6optIMAGE—
shot_7optIMAGE—
shot_8optIMAGE—
shot_9optIMAGE—
shot_10optIMAGE—
shot_11optIMAGE—
shot_12optIMAGE—
shot_13optIMAGE—
shot_14optIMAGE—
shot_15optIMAGE—
shot_16optIMAGE—
shot_17optIMAGE—
shot_18optIMAGE—
shot_19optIMAGE—
shot_20optIMAGE—
shot_21optIMAGE—
shot_22optIMAGE—
shot_23optIMAGE—
shot_24optIMAGE—
shot_25optIMAGE—
shot_26optIMAGE—
shot_27optIMAGE—
shot_28optIMAGE—
shot_29optIMAGE—
shot_30optIMAGE—
shot_31optIMAGE—
shot_32optIMAGE—
shot_33optIMAGE—
shot_34optIMAGE—
shot_35optIMAGE—
shot_36optIMAGE—
shot_37optIMAGE—
shot_38optIMAGE—
shot_39optIMAGE—
shot_40optIMAGE—
shot_41optIMAGE—
shot_42optIMAGE—
shot_43optIMAGE—
shot_44optIMAGE—
shot_45optIMAGE—
shot_46optIMAGE—
shot_47optIMAGE—
shot_48optIMAGE—
shot_49optIMAGE—
shot_50optIMAGE—
shot_51optIMAGE—
shot_52optIMAGE—
shot_53optIMAGE—
shot_54optIMAGE—
shot_55optIMAGE—
shot_56optIMAGE—
shot_57optIMAGE—
shot_58optIMAGE—
shot_59optIMAGE—
shot_60optIMAGE—
scene_framesoptIMAGE—

Outputs (1)

NameTypeDescription
IMAGEIMAGE—