Nodes/ComfyUI_zura_nodes/Zura · Wan Video Render
ComfyUI Node

Zura · Wan Video Render

The same Wan Animate loop, with the frames going straight to disk

By ZURAVFX·Created about a month ago·Updated a day ago· 2
Zura · Wan Video Render
  • model
  • clip
  • vae
  • clip_vision
  • reference_image
  • footage
  • vision_reference
  • video
  • receipt
◄promptPreserve the character appearance and scene.►
◄negative_promptflicker, warped hands, extra limbs, identity drift►
◄steps6►
◄cfg1.0►
◄seed0►
◄chunk_frames41►
◄overlap_frames5►
◄max_side1280►
◄shot_modeDetect cuts►
◄cut_threshold0.20►
◄cut_frames►
◄delivery_key►
◄viewport_renderfalse►
◄join_modeNative continuation►

Same renderer, different exit. This is the streamed twin of Zura Wan 2.2 Looped Chunks Sampler: identical conditioning inputs, identical 4n+1 window loop with native continue_motion continuation, but the decoded frames are written to a file as they're produced and you get a VIDEO back instead of an IMAGE batch.

Two consequences, and both are the reason this node exists. The images never all sit in RAM at once. And there's a delivery_key widget, which is how the delivery file is named and tracked.

What's different from the looped sampler

  • Outputs. video and receipt. No images. If a downstream node wants frames, this is the wrong sampler - that's what the looped one is for.
  • delivery_key - a string, default empty. It's the delivery identity, and the pack is strict about it: it has to be 64 hex characters. It's a separate concept from the preparation cache key, and the render will not proceed without both being valid.
  • join_mode is locked to Native continuation. The soft-blend cross-fade is the looped sampler's option; streaming wants frames it can write, not two renditions of the same frame to average. The widget is still there, with one choice, mostly so you can see that.
  • Audio policy. File-backed delivery refuses to carry a keep_audio payload. The receipt records this as restore_global_soundtrack_once - you put the original soundtrack back with the pack's soundtrack-restore node after delivery, instead of asking the render to carry it.

Everything else is shared: model, clip, vae, clip_vision, reference_image, footage, prompt, negative_prompt, steps, cfg, seed, chunk_frames, overlap_frames, max_side, shot_mode, cut_threshold, cut_frames, viewport_render, vision_reference. The same defaults, the same tooltips, the same 4n+1 rules.

The provenance checks are the interesting part

A streamed render is harder to audit than a batch one, because the output is a file appearing over time. So the node gates hard on the input side. It requires that the connected preparation records file-backed storage (torch_zip_mmap_float32 or torch_zip_readonly_windows_float32), a frame count and 24 fps that match the footage, and 64-hex cache key and SHA-256 values - plus a valid 64-hex delivery_key. Get it wrong and the message tells you what it wanted: "Use verified file-backed Wan preparation for streamed delivery."

If the preparation came through the windowed route, the payload's frames, character_mask, pose_video and face_video all have to be window arrays, not dense tensors, or you get "Connect the bounded Wan preparation arrays to streamed delivery." And the resolved cache file has to live inside ComfyUI's output directory with the expected name. This is a lot of ceremony for a loader/sampler pair, and it's there because a streaming writer that publishes a truncated file with no error is much worse than one that refuses to start.

The delivery itself is written atomically: the writer is finished after the encoded-video readback and immediately before publication, and a cache-verification step runs in between. That ordering is the whole point - the file becomes visible only once it's known good.

Outputs

video - the finished clip. receipt - the JSON record, which here also carries delivery, preparation, streaming: true, audio_policy, plus the per-chunk timings and continuation_delta values you'd use to decide whether the joins held.

Install

cd ComfyUI/custom_nodes && git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
pip install -r ComfyUI_zura_nodes/requirements.txt

Zura Nodes from ComfyUI Manager (publisher ZURAVFX) works too - restart after. You need the full Wan Animate stack plus ComfyUI-WanAnimatePreprocess and the detection weights, and ffmpeg/ffprobe on PATH, because this path muxes and muxes again when you restore the audio.

Common issues

"Use verified file-backed Wan preparation for streamed delivery." You wired the plain preparation loader. Streamed delivery needs file-backed or windowed preparation, and the provenance has to say so - the standard loader's cache won't satisfy this.

"Restore the global soundtrack after streamed Wan delivery." The preparation was flagged keep_audio. Re-prepare without it, or route the audio back in after delivery. The streamed path deliberately does one audio pass at the end rather than per chunk.

"Streamed Wan delivery requires native continuation joins." You changed join_mode. There's only one valid choice here.

Delivery key rejected. It must be 64 lowercase hex. A preparation cache key is a different value and pasting it in is the honest mistake.

A file appeared in the output folder but downstream says it's unreadable. That shouldn't happen - atomic publication is specifically there to prevent it - but if you see it, check that nothing outside the pack is writing into the same delivery path. Two processes pointing at one key is the one way to defeat the ordering.

Runtime is long and RAM is flat, which is the point. This is the node you graduate to when the batch sampler's peak memory is the thing killing your render. It will not make Wan animate faster; it makes a 30-second shot survive.

CategoryZura

Inputs (21)

NameTypeDefaultDescription
modelMODEL—
clipCLIP—
vaeVAE—
clip_visionCLIP_VISION—
reference_imageIMAGE—
footageZURA_FOOTAGEPrepared footage from the Zura Mask node.
promptSTRINGPreserve the character appearance and scene.—
negative_promptSTRINGflicker, warped hands, extra limbs, identity drift—
stepsINT61–200Sampler steps. The Turbo Switch node overrides this when connected.
cfgFLOAT1.00–30Guidance scale. The Turbo Switch node overrides this when connected.
seedINT00–18446744073709550000—
chunk_framesINT415–409Frames rendered per loop, in one pass of the sampler. Must be 4n+1 and at least twice the continuation frames.
overlap_framesINT55–405Continuation frames: the real tail of the previous chunk that the next chunk is told to carry on from, then cross-fades its own take onto. Deeper context holds motion tighter through fast movement (9 helps on quick dance); must be 4n+1.
max_sideINT1280256–1920—
shot_modeCOMBODetect cutsWhere continuation restarts. Detect cuts (auto) and Manual cuts split the clip into shots: a new shot starts unconditioned, so the cut stays hard. Continuous treats the whole clip as a single shot.
cut_thresholdFLOAT0.200.01–1Lower values detect more cuts. Raise this if flashes or fast movements are mistaken for edits.
cut_framesSTRINGManual cuts: comma-separated frame numbers where a new shot begins. At 24 fps, frame 96 is 4 seconds.
delivery_keySTRING—
vision_referenceoptIMAGEOptional separate character view for CLIP Vision; the main reference still guides the scene latent.
viewport_renderoptBOOLEANfalseKeep the full blockout frame as Wan's background guide while regenerating the complete scene.
join_modeoptCOMBONative continuation1 options: Native continuation

Outputs (2)

NameTypeDescription
videoVIDEO—
receiptSTRING—