ComfyUI Node

Frame Extractor

Pull stills out of a video to feed your captioning or reference chain

By sammykumar·Created 12 months ago·Updated 8 months ago· 6
Frame Extractor
    • frame_paths
    • frame_timestamps
    • frame_info
    • frames_directory
    video_path
    num_frames3
    extraction_methodEvenly Spaced
    seed0
    start_time0.0
    end_time0.0
    output_formatpng

    Vision-language models love images and tolerate videos grudgingly. Send a ten-second clip to most of them and you either burn tokens on hundreds of frames or they summarize so aggressively you lose the detail you actually wanted. Frame Extractor sidesteps the whole mess: it pulls a small, deliberate set of stills out of a video - evenly spaced, random, or start/middle/end - so the rest of your chain works on a handful of images instead of a video file.

    The required inputs are video_path (the path from a Media Selection node or anywhere else), num_frames (1–20, default 3), and extraction_method, which gives you the three selection strategies. Evenly Spaced is the sensible default - it samples the clip evenly so the set represents the whole thing. Random picks frames at random, which is the right call when you want to see a representative spread without bias (or when the video is mostly static and even spacing wastes frames on near-identical shots). Start/Middle/End grabs exactly those three, useful for checking continuity across a clip. The optional seed only matters for Random - set it to make the selection reproducible, and change it to force a re-pick.

    Beyond that: start_time and end_time (in seconds) define the window you sample from - both default to 0, which means "start of video" and "end of video", so you can extract only the interesting middle chunk of a long clip. output_format lets you choose png (lossless, default) or jpg (smaller).

    On the way out you get four STRING outputs: frame_paths (the extracted image files), frame_timestamps (where each frame came from in the video), frame_info (a summary blob), and frames_directory - the temp directory holding the images, which is handy if you want to point something else at the whole set at once. Under the hood it's OpenCV (cv2.VideoCapture) doing the reading, which is why opencv-python is a hard dependency of the pack. The frames land in a temp subdirectory the pack manages.

    The natural pairing: Frame Extractor → LLM Studio Picture Describe (or the Gemini path via Media Describe) → Multi-Caption Combiner, turning a video into per-frame captions and then a single coherent description.

    Installing

    Part of Swiss Army Knife:

    • ComfyUI Manager: search "Swiss Army Knife", install, restart.
    • Manual:
    cd ComfyUI/custom_nodes
    git clone https://github.com/sammykumar/ComfyUI-SwissArmyKnife.git
    cd ComfyUI-SwissArmyKnife
    pip install -e .
    

    Gotchas

    • num_frames caps at 20. If you need more, split the clip or accept the cap - that's the intended ceiling.
    • Temp directory output. frames_directory points into temp storage; don't treat it as your archive. If you want the frames permanently, copy them out.
    • Random extraction needs a seed to be reproducible - and changing the seed is also how you get a different random set, a nice trick for generating multiple caption passes.
    • If OpenCV can't open the file (missing codec, corrupt clip), you'll get an error rather than empty output - the error message is usually informative enough to point at the file.

    It's a small utility with one job, but it's the hinge of the pack's whole local-captioning flow. Videos in, sensible stills out, and your VLM does the heavy lifting on images it actually understands.

    CategorySwiss Army Knife 🔪/Utils

    Inputs (7)

    NameTypeDefaultDescription
    video_pathSTRINGPath to video file (from Media Selection node)
    num_framesINT31–20Number of frames to extract
    extraction_methodCOMBOEvenly SpacedMethod for selecting which frames to extract
    seedoptINT00–18446744073709550000Seed for random extraction (used when extraction_method is 'Random')
    start_timeoptFLOAT0.00–1000Start time in seconds for frame extraction window (0 = start of video)
    end_timeoptFLOAT0.00–1000End time in seconds for frame extraction window (0 = end of video)
    output_formatoptCOMBOpngOutput image format for extracted frames

    Outputs (4)

    NameTypeDescription
    frame_pathsSTRING
    frame_timestampsSTRING
    frame_infoSTRING
    frames_directorySTRING