XMediaListGet
Wire up twenty images once and let the graph loop for you
- images
- masks
- image_count
- videos
- video_count
- audios
- audio_count
Stock ComfyUI makes you pick a file. Load Image has one filename field, one browser button, and if you want to process a folder of forty shots you're either re-queuing the prompt forty times or editing the widget between runs. XMediaListGet is the blunt fix: you build a list of files in the node itself, and the list comes out as a ComfyUI list output - so the sampler downstream runs once per enabled image instead of you babysitting the queue.
That's the whole pitch. It's a plumbing node, and the plumbing is what decides whether a workflow is pleasant to run.
How it works, since the node looks empty at first
Drop it on the canvas and you get a panel, not a stack of widgets. The panel has three tabs - images, videos, audio - and you fill a tab by dragging media cards in from XDataHub, this pack's media browser for ComfyUI's input and output folders. Each entry has a toggle, a thumbnail, and pagination at 50 per tab.
The state you're building lives in a hidden string widget called media_items. You never type in it. It holds opaque reference hashes, not file paths, and the node resolves those hashes against that local index at execution time. On the way out:
- images go through the pack's image loader, applying any paint layer you scribbled and any mask you drew in the built-in mask editor, then the stored pan/zoom transform.
- masks come back one-to-one with the images - an image with no edited mask gives you an all-zero mask, which is what you want for "pass through unchanged".
- videos come out as video objects, audios through the pack's audio loader.
Disabled entries are skipped entirely, and panel order is output order. Like rgthree's utility work: no pixels generated, all the friction removed.
The inputs that matter
You'll only fuss over a couple of things. media_type picks which tab is showing and which links get flagged - the panel glows downstream connections whose type doesn't match the current category, and that glow is what type_warning switches off once you're tired of it.
The interesting bit is output_images, output_videos, output_audios. Read the source, not the tooltip: loading is gated by these three booleans, not by media_type. And the panel keeps them honest - each switch mirrors whether any output of that category is actually connected, so if you never wired videos, video loading is skipped and you don't pay for it. Default-on, but you rarely touch them.
What comes out
Seven outputs. images and masks are lists; image_count is a plain integer and, per the author's tooltip, the intended use is feeding it into XListPull's count so that node grows exactly enough split ports for your batch. videos/video_count and audios/audio_count are the same arrangement for the other tabs.
One behaviour to internalise: an empty category outputs a single None placeholder rather than nothing, so downstream still executes once. Sounds friendly, isn't always - a VAE Encode handed None will throw. If you see a confusing NoneType error, check whether your list is actually empty (killed item, unresolved reference) before you blame the sampler.
Install
Manager first, manual if you like pain:
# ComfyUI Manager: search "ComfyUI-Xz3r0-Nodes" and install
cd ComfyUI/custom_nodes
git clone https://github.com/Xz3r0-M/ComfyUI-Xz3r0-Nodes.git
cd ComfyUI-Xz3r0-Nodes
pip install -r requirements.txt
Restart ComfyUI. No model downloads - the only real dependency is ffmpeg-python, and the README's loud warning is about FFmpeg itself on your system PATH, which XDataHub needs for video thumbnails (and which the pack's save nodes need for audio/video writing). Images alone need nothing.
Where it bites
The honest caveat: this pack has essentially no community footprint - no Reddit discussion, no tutorials, roughly 3.5k registry downloads for the whole thing, a bilingual CN/EN interface, and docs that live mostly in the GitHub wiki. You are trusting a single developer's changelog. It is actively maintained and tidy, but you're the QA.
The refs are the real trap. Because media_items stores hashes resolved against your local index, a workflow containing this node is not portable. Send it to someone else, or rebuild your index, and every entry silently skips - you get a log line about an unresolved item and an empty list, not a dialog. Move or rename a file and the same thing happens, since refs are derived from the path. Same for the 50-per-tab cap: the panel refuses the 51st with "Already 50 enabled; turn one off first", and the Python loader truncates beyond 50 anyway.
And because it's a V3-API node (comfy_api.latest, io.ComfyNode), it needs a reasonably current ComfyUI. On an older install the pack imports nothing and the node simply doesn't exist - that's not a bug, that's your version.
Genuinely useful little node, though. If your workflow is "same graph, forty files", this is the least fiddly way to do it.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| media_type | COMBO | image | Which category this node outputs. Only enabled items in this category are loaded; the other two categories are left untouched. |
| media_items | STRING | XDataHub media list state (managed by the node panel) | |
| type_warning | BOOLEAN | true | Enabled: glow downstream links whose type does not match the current category. Disabled: hide the warning effect. |
| output_images | BOOLEAN | true | Enabled: load images and output the image list. Disabled: skip loading images entirely. |
| output_videos | BOOLEAN | true | Enabled: load videos and output the video list. Disabled: skip loading videos entirely. |
| output_audios | BOOLEAN | true | Enabled: load audio and output the audio list. Disabled: skip loading audio entirely. |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | Enabled images in panel order. When there are no images, one empty value (None) is output so downstream still runs. |
| masks | MASK | Mask list matching the images one-to-one. Images without an edited mask output an all-zero mask. |
| image_count | INT | How many images this node outputs. Connect to XListPull's count to size its split ports. |
| videos | VIDEO | Enabled videos in panel order. When there are no videos, one empty value (None) is output. |
| video_count | INT | How many videos this node outputs. |
| audios | AUDIO | Enabled audio files in panel order. When there is none, one empty value (None) is output. |
| audio_count | INT | How many audio files this node outputs. |