Nodes/ComfyUI-LoadGifAsVideo/Load Video (Trim & Loop Assist)
ComfyUI Node

Load Video (Trim & Loop Assist)

Your Clip Doesn't Loop. This Node Finds the Frame Where It Does

By id-fa·Created 3 months ago·Updated about 12 hours ago· 2
Load Video (Trim & Loop Assist)
    • video
    • images
    ◄file►
    ◄start_frame0►
    ◄end_frame0►
    ◄crop_x0►
    ◄crop_y0►
    ◄crop_w0►
    ◄crop_h0►

    You generated a Wan clip and it's good. It doesn't loop, and the seam is right there - a visible jump every few seconds, forever, because you want it as a background or a GIF. The usual fixes live on the generation side: regenerate a bridge with first/last-frame conditioning, or open a VACE joiner with a loop toggle. Slow, and the result is a different clip than the one you liked.

    Load Video (Trim & Loop Assist) takes the other road. When the loop already exists inside footage - a fire, a river, a camera panning back to where it started - the job is spotting the frame that looks like another frame and cutting between them. This node gives you a scrubber, a crop box and a button that finds the matches, then emits exactly the range you picked.

    What it is

    A source node, and deliberately a dumb one: pick a file, pick a frame range, optionally crop, get a VIDEO and an IMAGE batch. No fps, no speed, no length - Loop Video from the same pack owns those.

    Load Video (Trim & Loop Assist) → Loop Video → Save Video   (or Save as GIF)
                         └──────────→ images → any IMAGE input
    

    The video output carries the file's own frame rate plus the audio sliced to the same span, so it drops into Save Video or a Video Combine. The images output is those frames as a batch - no Get Video Components detour needed.

    The inputs that matter

    file is a dropdown of the videos in ComfyUI's input directory. It starts blank, so a fresh node won't silently grab whatever sorts first, and reports "No video file selected" until you pick one.

    start_frame and end_frame are where the loop is made, and end_frame is exclusive: the range is start_frame <= frame < end_frame. That's the trick, not a quirk. If the loop assist says frame 340 looks like frame 100, set start 100 and end 340 and you get 100–339. Jumping from 339 back to 100 is continuous, because 100 is what frame 340 looked like. An inclusive end would show that picture twice at the seam. end_frame = 0 means "to the end of the file."

    Then crop_x / crop_y / crop_w / crop_h, in pixels. A zero width or height runs to the edge, so all zeros is no crop.

    How it works

    Under the panel it's PyAV plus a frame index. The first time a file is opened the server decodes it once, recording every frame's timestamp and a small fingerprint grid; the index is cached in memory (keyed on path, mtime, size, grid, crop), so later searches are instant and the node reuses it when the graph runs. Seeking goes by those timestamps, and the audio is cut with the same span math.

    The panel - playhead, range band, crop overlay, search hits - is a DOM widget talking to HTTP routes on the same server. Nothing is queued, so you can scrub a two-minute file and search it twenty times without pressing Run.

    The loop assist is why you'd install this instead of counting frames by hand. Park the playhead where the loop should start, hit Find similar, and every frame matching at least the similarity threshold is listed with its time and score and given start / end buttons that set the range. Default is 98%, not 100, because lossy encoding keeps repeats from being bit-identical. Raise it when the list is all near-misses, lower it when an obvious repeat is missing. The Start and End thumbnails show the two frames the node will actually cut, cropped the way it will crop them: if they look alike, your loop is clean.

    Installing

    ComfyUI Manager, search the pack title ("Load GIF as Video"), or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/id-fa/ComfyUI-LoadGifAsVideo
    

    Restart. No pip dependencies - the pack's pyproject.toml declares none, and PyAV, Pillow, NumPy and torch ship with ComfyUI. No model downloads, MIT licensed. Your build does need the VIDEO type (comfy_api.input_impl); on older versions the node loads and raises a clear error when run.

    Where people get bitten

    • The dropdown is empty. That list is a read of ComfyUI/input, nothing more. Use the panel's Upload button rather than copying files in another window.
    • First open takes a while. It's a full decode to build the index; a long 4K clip will visibly work. It hasn't hung.
    • Out-of-order or past-the-end ranges raise. start_frame beyond the last frame, or end_frame at or before it, errors and names the real count. Over 10000 frames raises too - the pack's cap.
    • MKV or AVI looks wrong. The preview is your browser's player; when it can't decode the container the panel falls back to server-rendered frames, so stepping and search work but playback doesn't.

    Keep the fingerprint grid at its default: cranking it up on a long file can blow the pack's memory budget, and a 32-pixel grid finds the repeat you're going to eyeball anyway.

    Categoryload-gif-as-video

    Inputs (7)

    NameTypeDefaultDescription
    fileCOMBOVideo file in the ComfyUI input directory. Upload or drop one onto the node.
    start_frameINT00–10000000First frame of the range, counting from 0.
    end_frameINT00–10000000Frame the range stops before (it is not included); 0 means the end of the file. For a seamless loop, set it to the frame that looks like start_frame — the loop then returns to start_frame instead of showing that frame twice.
    crop_xINT00–16384Left edge of the crop box in pixels.
    crop_yINT00–16384Top edge of the crop box in pixels.
    crop_wINT00–16384Width of the crop box in pixels; 0 runs to the right edge.
    crop_hINT00–16384Height of the crop box in pixels; 0 runs to the bottom edge.

    Outputs (2)

    NameTypeDescription
    videoVIDEO—
    imagesIMAGE—