Nodes/Zura Nodes/Zura Load Video
ComfyUI Node

Zura Load Video

The 24 fps clock at the front of a Wan 2.2 Animate run

By ZURAVFX·Created a day ago·Updated about 13 hours ago· 0
Zura Load Video
    • video
    • frames
    clip
    video_url
    start_seconds0.0
    duration_seconds10.0
    keep_source_audiotrue
    source_max_side1280

    Every Wan 2.2 Animate workflow starts with the same awkward question: where does the driving clip come from, and how long is it? Zura Load Video answers both in one node. It's the first of four nodes in ComfyUI_zura_nodes, and it's the one you'll touch on every run.

    It looks boring. Two of its widgets quietly decide everything downstream.

    What it actually does

    You feed it a local file, or a URL, or a YouTube result. It decodes a trimmed slice at 24 fps and hands back an ordinary VIDEO wire plus the raw frames as an IMAGE.

    The number that matters is duration_seconds, and the tooltip spells out why: every second is 24 rendered frames. Ten seconds in, 240 frames out. In a stock Wan graph that would be a wall - native context is 81 frames, roughly five seconds, and pushing past it without engineering gives you warps and looping. It's the field's unsolved constraint, not a settings error. Here you can ask for longer, because the chunking happens later in the sampler node. Load Video's only job is to define truth: frames, timing, audio.

    The video output carries the source audio too, which is why the render node can produce a finished clip with the original soundtrack and no separate muxing node.

    The inputs you'll actually set

    • clip - a dropdown of videos in ComfyUI's input folder. There's a Choose local video button that uploads and selects in one move, which is friendlier than the usual drag-and-drop-into-the-input-folder ritual.
    • video_url - optional. A direct MP4 link, or a YouTube URL. Leave it empty and the dropdown wins.
    • start_seconds / duration_seconds - the trim.
    • source_max_side - the decode bound, 1280 by default. Drop it to 720-ish for fast preview passes; the sampler has its own max_side for the render, so this is purely "how much source detail do I want to pay for".
    • keep_source_audio - on by default.

    Outputs: video (a real VIDEO, understood by any ComfyUI video node) and frames (an IMAGE). Wire video into Zura Mask. Wire frames into a preview if you want to check the trim before committing to a 40-minute render.

    How it works under the hood

    ComfyUI core has no videos model category, so the node lists video files in the input directory - where uploads land anyway - plus anything a custom node has registered as a videos folder. Decoding goes through ffmpeg/ffprobe into a tensor, and the output is assembled with ComfyUI's native VideoFromComponents: a standard VIDEO, not some private payload.

    One genuinely good detail: the node's cache key includes the trim, audio flag and max side, not just the file path, so changing start_seconds from 0 to 12 actually re-decodes instead of silently serving the old frames. It also returns a "always dirty" value when you're using a URL, because there's nothing stable to fingerprint. That's the correct call - the always-rerun trick is a footgun when a loader does it carelessly (ComfyUI's cache comparison semantics are genuinely subtle), but a remote URL is by definition not cacheable by path.

    Install

    ComfyUI Manager → search Zura Nodes. Or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
    # then install the extras into the SAME python env ComfyUI runs in
    pip install -r ComfyUI_zura_nodes/requirements.txt
    

    Restart ComfyUI. The requirements are requests, yt-dlp[default] and ultralytics - ultralytics is for the mask node's person detection, not this one, but it ships with the pack. You also need ffmpeg and ffprobe on your system PATH, which is what actually decodes your clip. Nothing else models-wise: this node needs no checkpoints, no ONNX files.

    The YouTube path is the only one that wants Node.js on PATH, because modern yt-dlp uses it as a JS runtime to extract YouTube streams. Local clips don't care.

    Where people get burned

    • ffmpeg not on PATH. The clone succeeds, the pack loads, and the first run dies on decode. Symptom is a decode error mentioning the subprocess, not a Python traceback about a missing module.
    • A file that isn't in the list. Clips have to be in ComfyUI/input/ (use the picker, and this sorts itself out). The node's validator rejects paths it can't find rather than failing halfway through a render.
    • Confusing the two resolutions. source_max_side bounds the drive clip; the sampler's max_side bounds the render. Lowering only the first makes the pose/face conditioning coarse while the output stays expensive.
    • Assuming the pack is popular. It isn't - the wider community barely mentions "Zura", and this is effectively the pre-Zura Trend Studio line under new display names. The class ID is still TrendStudioV2DrivingClip for exactly that reason: graphs saved before the rename keep loading. Judge it on the output, not on the hype, because there is no hype.
    CategoryZura

    Inputs (6)

    NameTypeDefaultDescription
    clipCOMBOUploaded clips (and any videos already in the input folder). Use the Choose local video button below, or pick from this list.
    video_urlSTRINGOptional direct video URL (YouTube, direct MP4...). Leave empty to use the uploaded clip.
    start_secondsFLOAT0.00–86400
    duration_secondsFLOAT10.01–120Length of the driving clip. Every second is 24 rendered frames.
    keep_source_audioBOOLEANtrue
    source_max_sideINT1280256–1920Decode bound for the driving frames. Lower this for fast previews.

    Outputs (2)

    NameTypeDescription
    videoVIDEO
    framesIMAGE