Nodes/comfyui-imgmake/VideoKeyFramesExtractor
ComfyUI Node

VideoKeyFramesExtractor

The node that decides where you get to paint

By dafeng012·Created 2 years ago·Updated 2 years ago· 17
VideoKeyFramesExtractor
    • output_dir
    • INT
    png_dir
    output_dir
    min_gap10
    max_gap300
    key_th0.1
    key_add_last_frametrue
    is_invert_maskfalse

    VideoKeyFramesExtractor picks which frames become your keyframes - the ones you're going to img2img, inpaint, or otherwise restyle by hand before EBSynth propagates the style across the rest of the clip. If that sounds like the most important decision in the whole workflow, it is. EBSynth is only as good as the frames you feed it as reference, and this node automates the "which frames?" question so you don't have to eyeball hundreds of frames.

    It's a direct port of the keyframe-selection logic from the ebsynth_utility extension this pack is based on, which itself borrows the scene-change math from PySceneDetect.

    How it works

    The node compares frames to the last accepted keyframe and watches how much the edges change. Specifically: it converts each frame to HSV, detects edges with Canny, and measures the mean pixel difference between the current frame's edge map and the stored keyframe's edge map. When the difference crosses the threshold, the current frame becomes a new key. It's scene-change detection in disguise - a shot cut or a big movement produces a big edge delta, and that's exactly the moment you want a new reference frame.

    Two knobs shape the whole thing:

    • min_gap / max_gap - keyframes can't be closer than min_gap frames apart, and can't be farther than max_gap. max_gap is the insurance policy: even if nothing changes, EBSynth gets a fresh reference every max_gap frames so drift can't accumulate.
    • key_th - the sensitivity. Crucially, the effective threshold scales down as the gap grows: the closer you get to max_gap, the easier it is to accept a new key. So a busy scene gets lots of keys, a static one gets few, and you never starve.

    key_add_last_frame (default on) appends the final frame as a key so the clip ends cleanly. is_invert_mask flips mask interpretation for background-focused workflows.

    The paths (read this before it bites you)

    Like image2mask, this node appends subfolders to your inputs. It reads from <png_dir>/video_frame/ and writes to <output_dir>/img2img_key/. So pass it your project directory for both fields - not the frames folder directly - or it finds nothing. The selected frames are copied (not moved) into img2img_key/, which is where ebsynth_process later expects your painted keyframes to be.

    Inputs and outputs

    • png_dir - project dir (frames are expected in png_dir/video_frame).
    • output_dir - project dir (keys go to output_dir/img2img_key).
    • min_gap (default 10), max_gap (default 300), key_th (default 0.1), key_add_last_frame, is_invert_mask.

    It returns the output_dir STRING and an INT with the number of keyframes selected - handy for a quick "how many do I need to paint?" sanity check.

    Installing it

    Part of comfyui-imgmake - Manager (search comfyui-imgmake) or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/dafeng012/comfyui-imgmake
    

    No extra system dependencies for this node specifically (ffmpeg is needed later in the pipeline, so you'll want it on PATH anyway per the README).

    Troubleshooting

    • "No PNG files found" - you passed the frames folder, not the project dir. Remember it's looking for png_dir/video_frame.
    • Too many / too few keys - that's key_th and the gaps. Lower key_th = more keys; raise min_gap to thin them out. There's no universally correct setting, it depends on how much the camera moves.
    • Quirk worth knowing - the node actually runs the analysis twice in its current code (harmless, just wastes a few seconds and both runs agree). If you see the progress double, that's not a crash.

    For your first run, keep the defaults. EBSynth handles a reasonable keyframe count fine, and you can always tighten after you see which frames EBSynth chokes on.

    CategoryIMAGEmake

    Inputs (7)

    NameTypeDefaultDescription
    png_dirSTRING
    output_dirSTRING
    min_gapINT101–300
    max_gapINT30010–300
    key_thFLOAT0.10–1
    key_add_last_frameBOOLEANtrue
    is_invert_maskBOOLEANfalse

    Outputs (2)

    NameTypeDescription
    output_dirSTRING
    INTINT