Zura · Load Wan Motion in Sections
Reading a 30-second shot 81 frames at a time
- footage
- character_view
- width
- height
Same job as the plain preparation loader - hand the sampler its ZURA_FOOTAGE payload from a cache - but this one reads the prepared shot window by window instead of all at once. It's the loader for the pack's long-clip path, where "the clip" might be 720 frames and loading it whole would swallow every byte of RAM you have.
The class docstring calls it what it is: "Thin data adapter for visible native Wan sampling nodes." It reads, it slices, it hands over. No inference, no model loading.
Inputs and outputs
cache_key- string, default empty, 64-hex. Points atComfyUI/output/genj/wan_conditioning/<key>.pt.max_window_frames(optional, default 81, min 5, max 409) - how many frames a single read returns. 81 is Wan's native context and the pack's Studio default; the standalone example workflow uses 41. Lower is more memory-friendly and more sections to stitch.
Outputs are the familiar four: footage, character_view, width, height.
Under the hood it opens a window reader over the preparation archive with the file's expected SHA-256 pinned, so a cache that's been modified since it was written fails loudly rather than streaming garbage into a render.
The cache key is a 64-hex identity, not a label
This is the thing that bites people coming from other node packs. A preparation cache key isn't a filename you choose - it's a digest over the shot's identity: source interval, review hashes, character reference hash, the preparation recipe, the scope, and the speech guide if there is one. The guard node that sits next to this one in an exported graph will refuse to queue if the key doesn't match its recorded provenance.
Which is good news in practice: you can't accidentally sample a shot prepared from a different reference image and only notice in the output. It's also why "use a new cache key" is the correct response to most preparation errors - a fresh key means a fresh identity, and the old files stay around as evidence of what you did before.
Caching behaviour
This node declares itself always-changed, so it re-reads on every queue instead of being cached. For a loader whose validity depends on a file on disk, that's the honest choice - see the pack's guard nodes, which make the same call for the same reason. It does mean an idle re-queue isn't free: on a long shot, the re-run walks the archive again. If you're iterating on sampling settings rather than on preparation, that cost is a fixed tax, not something you can tune away.
Install
Part of the pack:
cd ComfyUI/custom_nodes && git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
pip install -r ComfyUI_zura_nodes/requirements.txt
Manager: search Zura Nodes (publisher ZURAVFX), install, restart. This node needs no extra model weights - but it only reads caches written by the pack's bounded preparation path, which does need the detection stack: ComfyUI-WanAnimatePreprocess plus detection/vitpose-l-wholebody.onnx and detection/yolov10m.onnx.
Common issues
"Wan preparation cache leaves the Comfy output folder" or a plain file-not-found. The key has to resolve to output/genj/wan_conditioning/<key>.pt in this ComfyUI install. Caches don't travel between installs, and they don't survive a wiped output folder.
Key rejected as invalid. It must be 64 lowercase hex characters. A project id or a receipt path pasted in here won't work, and neither will an uppercase hex digest.
Windows read but output looks like it starts mid-shot. Check max_window_frames against how you prepared the shot. The window size here is how the reader slices; if upstream preparation assumed 81-frame partitions, a mismatched read size can hand the sampler a section whose boundaries don't line up with the recorded carry state, and the join will look wrong. Keep 81 unless you have a reason, and change the whole preparation recipe if you do.
Everything got slower after you raised max_window_frames. Expected: fewer, bigger sections means more peak memory and less overlap between preparation and sampling. Drop it to 41 and see whether the joins survive - that's what the standalone example uses, and it halves the working set.
Nothing renders. This node outputs a footage payload, not images. If your graph's output node is wired to the loader instead of to the sampler, you'll get a very satisfying no-op.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| cache_key | STRING | — | |
| max_window_framesopt | INT | 815–409 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| footage | ZURA_FOOTAGE | — |
| character_view | IMAGE | — |
| width | INT | — |
| height | INT | — |