Nodes/Dream Video Batches/πŸ—˜ For Each Filename
ComfyUI Node

πŸ—˜ For Each Filename

Batch a whole folder of clips without babysitting the queue

By alt-key-projectΒ·Created 3 years agoΒ·Updated 7 months agoΒ· 95
πŸ—˜ For Each Filename
    • filepath
    • name
    • foreach
    β—„idβ–Ύβ–Ί
    β—„directory/tmp/ComfyUI/inputβ–Ί
    β—„pattern*.jpgβ–Ί

    For Each Filename [DVB] is the node you drop in when you're tired of feeding ten input files into the same video workflow by hand. It's file iteration: point it at a folder, give it a glob pattern, and every time you hit queue it hands you the next matching file - one per run - and remembers where it is between runs. The pack is built by "Alt Key Project", a YouTube creator who's been shipping ComfyUI animation packs since 2023, and this is the node that turns a single-image workflow into a folder-crunching batch machine.

    How the loop works

    The trick is that the loop state lives in a file, not in the graph. When the node runs it writes a foreach_<id>.json state file next to the directory you're scanning, records every file matching your pattern, and pops one off the queue. That path comes out as the filepath output, and the foreach output is the handle to that state file - you thread it forward so the loop knows where it is.

    The node marks itself always-changed, so it re-executes even when nothing upstream changed. When the queue finally empties, it deletes the state file and throws "No more files to process" - that's the node telling you the batch is finished, not a crash. Restart ComfyUI mid-loop and it picks up where it left off, because the state is on disk.

    The inputs that matter

    Three inputs, and the id one is the one people trip on:

    • id - a codename (it's a fixed list of fruit and animal words like "apple", "dog", "eagle"). This is your loop's unique key. Two For Each Filename nodes with the same id share a queue, which is almost never what you want. Give each loop its own id.
    • directory - the folder to scan, defaulting to ComfyUI's input directory.
    • pattern - a glob like *.jpg. The globbing is recursive, so **/*.png reaches into subfolders.

    Outputs: filepath (the full path to the next file), name (the filename with the extension stripped, handy for naming outputs), and foreach (the state handle to wire into For Each Done).

    Pair it with For Each Done

    For Each Filename is the start of the loop; For Each Done [DVB] is the end. Done takes your processed image and the foreach handle and marks that file as handled, which is what actually advances the queue. Skip it and nothing progresses - you'll just process the same first file forever. Done is an output node that produces nothing visible; it's a checkpoint.

    Installing and gotchas

    From the ComfyUI Manager you can search "Dream Video Batches"; the README hedges on Manager availability, so the guaranteed route is:

    cd ComfyUI/custom_nodes
    git clone https://github.com/alt-key-project/comfyui-dream-video-batches.git
    cd comfyui-dream-video-batches
    pip install -r requirements.txt
    

    Then restart ComfyUI. The requirements are lightweight (imageio, pilgram, scipy, numpy, torchvision, evalidate) - no model downloads, nothing heavy.

    Where people get burned: forgetting For Each Done, reusing an id across two loops, and pointing directory at a folder that's not actually readable. Also, each pass in the loop is a full queue run - if each file's workflow takes a minute of sampling, a hundred files is a hundred runs. That's the point, but set expectations.

    One more thing worth knowing: the state file lives inside the folder you're scanning, so the node filters out anything ending in foreach_<id>.json - otherwise a loop would try to process its own bookkeeping.

    Category🎭 DVB/πŸ›  utils

    Inputs (3)

    NameTypeDefaultDescription
    idCOMBO22 options: apple, banana, book, car, cat, chicken, +16
    directorySTRING/tmp/ComfyUI/inputβ€”
    patternSTRING*.jpgβ€”

    Outputs (3)

    NameTypeDescription
    filepathSTRINGβ€”
    nameSTRINGβ€”
    foreachFOREACHβ€”