VideoFrameExtractor
One MP4 in, every frame plus per-frame masks out
- images
- mask_images
- image_count
Video-to-video editing in ComfyUI has a boring prerequisite nobody warns you about: you need every frame on disk as a separate image, and for most edits you also need a mask on at least some of them. VideoFrameExtractor (registered in the node menu as "Video Loader With Mask Editor") is exactly that prep step, with a paint-on-canvas GUI bolted on. Point it at an MP4, it extracts all the frames, and hands you a batch of images plus a per-frame mask editor without you ever touching ffmpeg or writing a shell loop.
It comes from bruefire's tiny pack, ComfyUI-SeqImageLoader - released back in December 2023 for the AnimateDiff crowd and still the low-friction input stage for Wan-based editing. The repo even ships a wan_video_wrapper.json that routes these frames and masks straight into WanVideoEncode for masked video editing: swap a logo, re-dress a subject, keep the camera motion. Masks are exactly the thing the masked-inpainting crowd still insists on over whole-frame edit models, because unmasked pixels come back bit-identical.
How it works
The interesting bit: frame extraction happens in your browser tab, not in Python. The node reuses getVideoFrames.js to decode the MP4 client-side, so there's no ffmpeg binary and no PyAV in your Python environment - which is why installing this pack is genuinely painless. Decoded frames get written to ComfyUI/input/extVideoFrame<id>/, and the sequence_id widget is just the internal path blob the upload button fills in. You never type it.
Once frames are loaded, right-click the node and pick Open In MaskEditor. The editor is built on ComfyUI's standard Mask Editor: a magic-wand auto-select for the "I want the subject" case, a manual brush, and a sketch layer that gets composited into the image output. Right-click paints the mask, left-click erases it. Two genuinely useful extras: a "paste mask from previous frame" button (huge for video, where masks barely change between frames) and an adjustable brush thickness.
Inputs and outputs that matter
Only three inputs, and only two you ever touch:
- sequence_id - ignore it. The upload button fills it for you.
- start_index / end_index - both default to 0, meaning "no limit, load everything." If you set them, they act as a 1-based slice into the sorted frame list, so "frames 10–60" becomes a two-integer filter. Nice when you only want to edit a section.
Outputs:
- images - the frame batch as one IMAGE tensor, sketches composited in.
- mask_images - white-on-black per-frame masks, as IMAGE. Wire them through an
ImageToMasknode to feed MASK inputs likeSetLatentNoiseMaskorWanVideoEncode. - image_count - just an INT with the frame count.
Install
ComfyUI Manager → search "SeqImageLoader", or the manual way:
cd ComfyUI/custom_nodes
git clone https://github.com/bruefire/ComfyUI-SeqImageLoader
Restart ComfyUI. There's no requirements.txt and no model download - it only needs the torch/PIL/numpy ComfyUI already ships.
Gotchas
- MP4 only. WebM, MKV, MOV will not work. Transcode first:
ffmpeg -i input.mov -c:v libx264 -pix_fmt yuv420p input.mp4. - Frames pile up in
input/extVideoFrame*/and never get cleaned automatically. Delete the ones you've finished with. - Undo/redo in the editor is Alt+Z / Shift+Alt+Z, not Ctrl+Z - Ctrl+Z fires ComfyUI's own undo and will do something you didn't ask for.
- You get frames, not audio. Reassemble sound with
VHS_VideoCombineor your editor. - Long videos mean one huge IMAGE batch, so your sampler's VRAM - not this node - sets the ceiling. Clip first.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| sequence_id | STRING | — | |
| start_index | INT | 0 | — |
| end_index | INT | 0 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| mask_images | IMAGE | — |
| image_count | INT | — |