Build Media IO Basename
Stop naming your bbox, mask and latent files after 00007
- basename
This is a two-widget node that fixes bookkeeping, not generation. It takes a video filename, optionally a timestamp, and spits out one STRING - a basename - that you wire into the basename input of the pack's save nodes. So instead of bboxes_00007.cbbox and MiniMaxH3_00003.h3latent and masks_00012.cmask from one run, all three files come out named after the clip you were working on: surf_clip_01_20260925_104402.
If you have ever scrolled an output/ folder trying to remember which set of boxes belonged to which video, that's the entire reason this node exists.
Why you'd bother
Detection and tracking are the expensive part of a video workflow - SAM3 tracking or a YOLO pass over a hundred frames - and the artifacts they produce are tiny by comparison. So you save them, once, and reuse them across render iterations. That plan falls apart the moment the files stop being self-describing. ComfyUI's default answer to "what do I call this" is filename_prefix plus an auto-incrementing counter, and a counter tells you the order of writes and nothing else. Three save nodes in one graph each mint their own counter, and now three independent numbering schemes describe one run.
So the pack gives every save node the same optional basename input, and this node is the thing that produces it.
How it works
video_filename goes through a normalizer: it takes the basename only (a full path is fine, the path is dropped), strips the extension, replaces spaces with underscores, and scrubs characters a filesystem won't take. Then it appends a timestamp - your timestamp if you typed one, otherwise datetime.now() in %Y%m%d_%H%M%S.
The interesting part is what happens when you leave video_filename empty, which you can. The node reads the hidden graph prompt it was executed in, walks the ancestors of its own node looking for a video loader - the VHS loaders, LoadVideo, LoadVideoPath, LoadVideoUpload - and pulls the filename the user selected there. If it can't find one that way, it looks at the whole graph and only trusts the answer when exactly one video filename is present. Ambiguity returns nothing rather than guessing.
Timestamps are also shared per run. ComfyUI's prompt cache is keyed per prompt, so every save node in the same execution reuses one timestamp instead of each stamping a slightly different second - which is exactly what you want when the files have to line up by name later.
One honest caveat about the output: when the node can't resolve a fixed name, it returns an empty string, not a fallback. That's deliberate and it doesn't break anything - the save nodes treat "no basename" as unset and fall back to filename_prefix_00001 naming. You get a counter, not a crash.
Inputs and output
video_filename- the clip name. Type it, or leave it blank and let the node sniff the graph.timestamp- optional. Blank means now.
Output is a single STRING named basename. Wire it into basename on Save Bounding Boxes, Save MiniMax H3 AV Latent, or Save Mask Tensor from the same pack. All three take the same trio (basename, video_filename, timestamp), so wiring this node into all three is how you keep one run's artifacts on one stem.
Install
ComfyUI Manager, search for the pack title - or:
cd ComfyUI/custom_nodes
git clone https://github.com/swanjohn99/comfyUIcostumNodes
Restart ComfyUI. There is nothing to download and no pip install: the pack's pyproject.toml declares no dependencies and everything it uses (torch, folder_paths, safetensors) ships with ComfyUI.
Gotchas
The repo's README only documents the pack's mask nodes, so don't be surprised when the node you googled isn't in it - BuildMediaIoBasename lives in nodes_io_basename.py and is registered in __init__.py alongside the rest.
The frontend extension that ships with the pack already auto-fills video_filename on save nodes and auto-selects the matching load file by stem, so on a current ComfyUI you may find the wiring does itself. This node is the explicit version of that behaviour - reach for it when you want the name pinned rather than inferred, or when you're wiring several saves and want one obvious source of truth. And if you're going to set timestamp by hand, set it once, here, and leave it blank on the save nodes; typing different values in each is the fastest way to get three files that no longer match.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| video_filename | STRING | — | |
| timestampopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| basename | STRING | — |