ComfyUI Node

SequentialImageLoader

The frame-folder loader with a mask editor that AnimateDiff v2v was built on

By bruefire·Created 3 years ago·Updated about a year ago· 48
SequentialImageLoader
    • images
    • mask_images
    • image_count
    sequence_id
    start_index0
    end_index0

    This is the original node in bruefire's ComfyUI-SeqImageLoader pack, and honestly the more controllable one. "VFrame Loader With Mask Editor" (displayed as SequentialImageLoader) does the same job as the pack's video variant - load a whole frame sequence as a batch, then paint masks and sketches on every frame through a GUI - except you hand it a folder of frames instead of an MP4. That means you decide how the frames got there, and that's a feature.

    The pack launched around this node in December 2023, announced on r/comfyui as "a custom node for inpainting a video with a UI," demoed with AnimateDiff. The mask editor was the whole point: before this, per-frame masking for video meant exporting frames, opening them one by one in an image editor, painting masks, and re-importing. This node collapsed that into a right-click.

    Why the folder, not the video

    When you feed this node a directory you control the extraction: choose your own fps, resolution and file format, and reuse the same frame folder across runs without re-decoding. You're also not leaning on a browser-side decoder - frames already on disk can't fail to decode. The pack's headline demo, cat2dog_with_animatediff.json, shows the classic use: mask the cat, then run AnimateDiff over the sequence with SetLatentNoiseMask fed from your masks, so only the masked region re-diffuses and everything else stays put. AnimateDiff is superseded for new work these days, but if you're animating an SD1.5 checkpoint this is still the cleanest input stage around.

    How it works

    sequence_id is the internal path blob that encodes the frame directory plus the mask/sketch subfolders the editor creates - the upload button fills it in, you never type it. After loading, right-click the node → Open In MaskEditor. The editor is built on ComfyUI's standard one: magic-wand auto-masking plus a manual brush, right-click to mask, left-click to unmask, a sketch layer that gets composited straight into the image output, a "paste previous frame's mask" button for the lazy-but-correct approach, and brush thickness control. Undo/redo is Alt+Z / Shift+Alt+Z - not Ctrl+Z, which trips ComfyUI's own undo instead.

    Inputs and outputs that matter

    • sequence_id - internal; ignore it.
    • start_index / end_index - both default to 0, meaning "everything." Set them for a 1-based slice into the sorted frame list when you only want part of the sequence.

    Outputs:

    • images - the frame batch as one IMAGE tensor (sketches composited in).
    • mask_images - white-on-black per-frame masks as IMAGE; run them through an ImageToMask node to feed MASK inputs like SetLatentNoiseMask.
    • image_count - an INT with the frame count.

    Install

    ComfyUI Manager → search "SeqImageLoader", or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/bruefire/ComfyUI-SeqImageLoader
    

    Restart ComfyUI. No requirements.txt, no model downloads - just the torch/PIL/numpy ComfyUI already has.

    Gotchas

    • Zero-pad your frame filenames. The node sorts names lexically, so frame_10 sorts before frame_2 and your start/end slicing will look cursed. Name them frame_0001.png on up. Extract with:
      ffmpeg -i video.mp4 -q:v 2 frame_%04d.png
    • The frame directory must exist and have files, or you'll get a "Directory cannot be found" error from the loader.
    • Mask/sketch data accumulates in input/extVideoFrame*/ - clean it up periodically; the README says so itself.
    • Don't rename or delete those directories while a workflow still references the sequence_id; the node rebuilds paths from that blob.
    Categoryimage

    Inputs (3)

    NameTypeDefaultDescription
    sequence_idSTRING
    start_indexINT0
    end_indexINT0

    Outputs (3)

    NameTypeDescription
    imagesIMAGE
    mask_imagesIMAGE
    image_countINT