Load ZIP file
Load a whole ZIP of images, masks, captions and video without unzipping anything
- batch_cursor
- IMAGE
- MASK
- PROMPT WORD
- VIDEO
- AUDIO
- TEXT
- Naming
- batch_cursor
The usual way to get a folder of images into ComfyUI is a small ceremony: unzip on your desktop, copy the folder into ComfyUI/input, refresh, and hunt for the right Load node. This node skips all of it. Drop a ZIP file onto a button inside the node and it reads the archive straight into the graph - images, masks, captions, video and audio at once, each as its own typed output. It's the centerpiece of this pack and the reason the pack exists.
How it works
The upload button is a real browser upload: it POSTs the file to ComfyUI's /upload/image endpoint, and the archive lands under ComfyUI/input/uploaded_zips/. On RunPod or Colab the same thing happens - your browser pushes the ZIP to the remote server, so there's no ssh/drive dance for getting data in.
On execution the node walks every member of the archive and sorts it by extension:
- Images - png, jpg/jpeg, webp, bmp, tif/tiff
- Video - mp4, webm, mkv, avi, mov, m4v, gif
- Audio - wav, mp3, flac, ogg, m4a, aac
- Text - txt, json, srt, vtt, csv, md, log
That file is not decompressed to input - members are read in memory (video gets extracted to a temp dir and becomes a proper ComfyUI VIDEO object).
The pairing conventions that make it a dataset node
This is where it stops being "load a folder" and becomes genuinely useful. The pack uses filename stems to pair things up, the same way a training dataset is laid out on disk:
cat.png+cat_mask.pngin the same ZIP → the mask gets loaded and wired to the MASK output.cat.png+cat.txt→ the txt becomes that image's PROMPT WORD (and also shows up raw in the TEXT output, since all.txtfiles are loaded).- A PNG that carries an alpha channel with no
_masksibling gets its alpha turned into a mask (1 − alpha, so transparent areas read as mask=1).
Then the sequences are aligned by stem and zipped together, so batch element i of IMAGE, VIDEO, AUDIO and TEXT all come from the same logical slot. That alignment is the whole point: feed the outputs to a sampler and each element is one job in the batch.
The outputs that matter
You'll use IMAGE, MASK, PROMPT WORD and TEXT most. Two outputs are plumbing:
- Naming - a dict of the original filenames inside the ZIP. Wire it into Save to ZIP's
naminginput and your original file names come back out the other end. - batch_cursor - an accumulator. Feed it into a second Load ZIP node's
batch_cursorinput and you can chain several archives into one combined batch. Theloadtoggle (default on) controls whether a node reads its ZIP; flip it off for a pure pass-through.
Installing
ComfyUI Manager → Install Custom Node → search for jayhuang-zip-unpack-images, or:
cd ComfyUI/custom_nodes
git clone https://github.com/aixqueen/jayhuang-zip-unpack-images.git
Then restart ComfyUI. No models to download. The one dependency is soundfile, and it only matters for non-WAV audio in your ZIPs - WAV decodes with the Python stdlib. If you load an mp3 or flac and hit a "Missing 'soundfile' package" error, that's it:
pip install soundfile
Gotchas
The node re-runs whenever the ZIP's size or mtime changes, so re-uploading a same-named archive does trigger a fresh read - that's a feature for iteration, but it means a zip sitting on a synced drive can fire the node when you least expect it. A corrupted archive fails with a clear "ZIP file is corrupted" error, and if the archive contains none of the supported extensions it raises "No supported content found."
One honest caveat: this is a tiny, single-commit pack from an author with effectively no community footprint. The mechanism is straightforward and reads cleanly, but with ComfyUI custom nodes you're executing arbitrary Python - give it the same glance-over you'd give any unknown node, then enjoy the part where your workflow finally stops treating a folder as a problem.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| zip_file | COMBO | 1 options: | |
| batch_cursoropt | * | — | |
| loadopt | BOOLEAN | true | — |
Outputs (8)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| MASK | MASK | — |
| PROMPT WORD | STRING | — |
| VIDEO | VIDEO | — |
| AUDIO | AUDIO | — |
| TEXT | STRING | — |
| Naming | * | — |
| batch_cursor | * | — |