Nodes//Nougan Load Video Batch From Folder 🎞️
ComfyUI Node

Nougan Load Video Batch From Folder 🎞️

Caption a folder of clips without hitting Queue 200 times

By WinnouganΒ·Created 3 months agoΒ·Updated about 16 hours agoΒ· 10
Nougan Load Video Batch From Folder 🎞️
    • frames
    • audio
    • filename
    • path
    • index
    • total
    • fps
    • video
    β—„folder_pathβ–Ί
    β—„sort_modeβ–Ύβ–Ί
    β—„index0β–Ί
    β—„auto_run_foldertrueβ–Ί
    β—„force_rate0.0β–Ί
    β—„frame_load_cap0β–Ί
    β—„skip_first_frames0β–Ί
    β—„select_every_nth1β–Ί
    β—„resize_longest_side0β–Ί

    Almost every video node in ComfyUI loads one path per run. Captioning a video LoRA dataset, then, means a hundred clips and a hundred Queue presses - and somewhere around clip forty you lose track of which ones you've done. This node deletes the chore: point it at a folder, press Run once, and it walks the folder itself, one clip per execution, until it runs out.

    The pack ships workflow/Nougan_Video_Captioning_Workflow.json doing exactly that - loader β†’ VLM captioner β†’ the pack's Save Caption node - and the same graph batch-processes clips through an upscale or interpolate graph unattended.

    How it actually works

    folder_path gets listed non-recursively and filtered to video extensions (.mp4 .mov .mkv .webm .avi .m4v .flv .wmv .mpg .mpeg .ts .3gp). Then sort_mode orders the list, index picks one file with a modulo (index % total, so an out-of-range index wraps instead of erroring), and PyAV decodes it into a single IMAGE batch.

    The frames aren't streamed, they're all held in memory as one tensor, which is the honest cost of this node: a 4K/60 clip is a VRAM event. frame_load_cap and resize_longest_side exist for that reason, and select_every_nth thins frames while recomputing the reported fps, so downstream playback timing stays correct. force_rate only ever reduces frame rate (the code only resamples when the target is below the source), so setting it higher than the clip's own fps does nothing.

    Audio is decoded separately, resampled to stereo, and sliced to the same window your frame options selected, so it stays in sync even when you skip into the middle of a clip. Silent clips come back as ten milliseconds of silence rather than None, so audio-expecting nodes downstream don't crash.

    The whole-folder loop is frontend, not backend: web/nougan_folder_batch.js listens for each successful execution, bumps index, and re-queues. So the loop needs a live browser session, and it stops dead the moment a clip errors.

    Inputs worth touching

    • folder_path - quotes, ~ and %ENV% are all stripped/expanded, so a Windows "Copy as path" paste works as-is.
    • sort_mode - numeric is natural order (clip2 before clip10, 001, 002, 10), alphabetical is plain case-insensitive Aβ†’Z. If your dataset is numbered, leave it on numeric.
    • auto_run_folder - the labeled toggle: run whole folder advances itself, single video runs just the current index. Turn it off while you're testing prompts.
    • frame_load_cap / resize_longest_side - your VRAM insurance. Start at something like 121 frames and 720–1024 px longest side, then raise.

    Outputs

    frames is the decoded IMAGE batch - feed it to a captioner, an upscaler, or a video model. audio is an AUDIO dict for the same window. filename is the stem with no extension (nice for naming captions), while path is the full path - wire path, not filename, into anything writing a file next to the source clip. index and total tell you where you are in the folder, fps carries the effective frame rate for reassembly, and video is ComfyUI's native VIDEO type when your build has it.

    Install

    ComfyUI Manager β†’ search Nougan, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Winnougan/Nougan_Nodes
    # restart ComfyUI
    

    The pack declares no Python dependencies (dependencies = [] in pyproject.toml), but the decode path imports PyAV lazily, inside the function. PyAV ships with ComfyUI core, so a normal install is fine; on a hand-built venv you'll meet ModuleNotFoundError: No module named 'av' at execution time, not boot - pip install av into ComfyUI's own environment fixes it.

    Where it bites

    It does one clip and stops. The auto-run loop is the JS extension, so a stale browser cache or a missing web/ file means no loop - hard refresh (Ctrl+F5). The πŸ”„ Refresh folder button it adds hits a backend scan route: it re-counts the folder, resets index to 0 if it was past the end, and previews the current clip's first frame without running the graph.

    Everything queues twice. Two copies of the loader in custom_nodes means two extensions both re-queueing - the pack kept the node ID short so older standalone installs kept loading, which is how the old copy hangs around and fights the new one. Delete one and restart. Also leave the queue's batch count at 1.

    "No videos found in…" is nearly always a subfolder (they aren't scanned) or an extension outside the list above. A folder of .pngs is invisible here by design - that's FolderImageBatchLoader, same pack.

    "video" output is empty on older ComfyUI builds. The console says so plainly and tells you to use frames + audio; do that.

    You swapped a clip and it still renders the old one. Its cache fingerprint is path + mtime + size + file count, so touch the file if your filesystem preserved the original timestamp.

    One last note on the pack: it's a hobbyist suite from the person behind the Krea 2 quantizations, grown out of his own workflow glue. The README doesn't even list these loaders, and the docs cover the image variant far better than the video one. When a detail matters, read the source - it's short and it's what runs.

    Categoryvideo/batch

    Inputs (9)

    NameTypeDefaultDescription
    folder_pathSTRINGβ€”
    sort_modeCOMBO2 options: numeric (001, 002, 10...), alphabetical
    indexINT00–16777215β€”
    auto_run_folderBOOLEANtrueβ€”
    force_rateoptFLOAT0.00–120β€”
    frame_load_capoptINT00–100000β€”
    skip_first_framesoptINT00–1000000β€”
    select_every_nthoptINT11–1000β€”
    resize_longest_sideoptINT00–8192β€”

    Outputs (8)

    NameTypeDescription
    framesIMAGEβ€”
    audioAUDIOβ€”
    filenameSTRINGβ€”
    pathSTRINGβ€”
    indexINTβ€”
    totalINTβ€”
    fpsFLOATβ€”
    videoVIDEOβ€”