加载批量音频
Twenty audio loaders, one node, and a real gap it fills
- 音频A
- 音频B
- 音频C
- 音频D
- 音频E
- 音频F
- 音频G
- 音频H
- 音频I
- 音频J
- 音频K
- 音频L
- 音频M
- 音频N
- 音频O
- 音频P
- 音频Q
- 音频R
- 音频S
- 音频T
ComfyUI's core audio story is "load one file." If you're doing anything with a set of clips - a folder of dialogue lines, several takes, a music bed plus stems - you end up duplicating a loader node once per file and re-plumbing every time you add one. 加载批量音频 (YanhuoMultiAudio) replaces the wall of loaders with a single node that has twenty independent outputs, one per track.
The gap it's filling
This isn't a hypothetical need. People have been asking for a batch audio loader for a while, and the workaround that circulated was pushing multiple mp3s through a wildcard on a data-handling node with a directory glob. That works. It also means your loader is a string-manipulation puzzle. A node where you drop in files and get tracks out is the thing they were asking for.
How it works
The node has exactly one input: tracks_data, a multiline STRING holding JSON like:
[{"name":"音频A","paths":["a.mp3","b.wav"]}]
You never type that. The pack's frontend maintains it - you click to pick files, drag them in, or paste them, and the field fills itself. But it is just a JSON string, which matters if you're driving ComfyUI from the API or scripting a workflow build; you can write the track list directly.
Each track can hold multiple clips, and that's the subtle bit: one track that holds three files isn't three tracks, it's an audio batch of three on a single output. The output ports are 音频A through 音频T - twenty of them - each typed AUDIO and marked as a list. Rename a track in the UI and the port label follows, so you can have dialogue, music, sfx on the node instead of letters.
Decoding is done with PyAV, and each clip keeps its own sample rate and channel count. No normalization, no resampling, no assumption that everything is 44.1k stereo. If you need a uniform rate, that's a decision to make downstream, not something the loader does quietly.
Paths resolve flexibly: output:, input: and temp: prefixes map to ComfyUI's three standard directories, absolute paths work, and a bare relative path is resolved against the input directory. Which is exactly the three-directory convention the rest of the ecosystem uses - if you're unclear on which of the three a file has to be in for a node to find it, that's usually the whole bug.
Empty tracks are the other design decision. Rather than erroring, an empty track outputs one second of silence. That keeps a graph running when only some of your clips exist yet, and it's why the pack's 音频批次合并 has a 跳过静音占位 toggle: silence-as-placeholder is a convention, and the batch node knows how to see through it.
Wiring it
Each output is a batch, so it goes to 音频批次合并 (to pool several tracks into one batch), 筛选音频 (to pick specific clips), 音频批次预览/保存 (to listen or write files), or anything that declares INPUT_IS_LIST on AUDIO. 音频拼接 takes one clip per port, so for a splice you'd filter a track down to the segments you want first.
Install
One of 16 nodes in yanhuo-easy-use - category yanhuo, Chinese node labels, MIT, v1.3.1. ComfyUI Manager → search the pack title. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/yanhuoxunxianren/yanhuo-easy-use
# restart ComfyUI
This pack's audio half does call PyAV - but av ships with ComfyUI itself (it's what SaveAudio uses), and the pack imports it defensively, so no pip install is needed on a normal install. If it's somehow missing you'll get a message naming the library rather than a mystery. No model downloads.
Common issues
"A track loads as a second of silence." Either the track is empty (expected), or every file in it failed to load. Failures are per-file, printed to the console with the track name and the reason, and skipped - so a track with one bad path among three loads the two good ones. Check the console; the node deliberately doesn't stop the run.
"File not found" on a path you know exists. A bare relative path resolves against ComfyUI's input directory, not your project folder. Use output:, input:, temp:, an absolute path, or just confirm where the file actually lives.
"The sample rates don't match downstream." They aren't supposed to. This loader preserves each clip as-is; normalize after, or handle it in whatever you're muxing into.
"I renamed a track and the port name is stale." Reload the workflow, or nudge the track list - port labels are rebuilt from the JSON.
"I need more than twenty tracks." Two nodes. That's the ceiling, and it's a lot of audio.
"The JSON field is empty after I load a shared workflow." The paths are stored in the node, not copied into input/. If the files aren't on your machine, the tracks are references to nothing. Loaders that reference files rather than embedding them are the standard here - the same reason a workflow PNG with an embedded graph still doesn't contain your checkpoints.
Where audio actually stands in this ecosystem - good models, thin and bolt-on plumbing - is the subject of docs/knowledge/audio-generation.md.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| tracks_data | STRING | JSON 格式音轨数据,由前端自动维护。格式:[{"name":"音频A","paths":["a.mp3","b.wav"]}] |
Outputs (20)
| Name | Type | Description |
|---|---|---|
| 音频A | AUDIO | 音轨 1 的音频批次(列表,每段音频独立)。 |
| 音频B | AUDIO | 音轨 2 的音频批次(列表,每段音频独立)。 |
| 音频C | AUDIO | 音轨 3 的音频批次(列表,每段音频独立)。 |
| 音频D | AUDIO | 音轨 4 的音频批次(列表,每段音频独立)。 |
| 音频E | AUDIO | 音轨 5 的音频批次(列表,每段音频独立)。 |
| 音频F | AUDIO | 音轨 6 的音频批次(列表,每段音频独立)。 |
| 音频G | AUDIO | 音轨 7 的音频批次(列表,每段音频独立)。 |
| 音频H | AUDIO | 音轨 8 的音频批次(列表,每段音频独立)。 |
| 音频I | AUDIO | 音轨 9 的音频批次(列表,每段音频独立)。 |
| 音频J | AUDIO | 音轨 10 的音频批次(列表,每段音频独立)。 |
| 音频K | AUDIO | 音轨 11 的音频批次(列表,每段音频独立)。 |
| 音频L | AUDIO | 音轨 12 的音频批次(列表,每段音频独立)。 |
| 音频M | AUDIO | 音轨 13 的音频批次(列表,每段音频独立)。 |
| 音频N | AUDIO | 音轨 14 的音频批次(列表,每段音频独立)。 |
| 音频O | AUDIO | 音轨 15 的音频批次(列表,每段音频独立)。 |
| 音频P | AUDIO | 音轨 16 的音频批次(列表,每段音频独立)。 |
| 音频Q | AUDIO | 音轨 17 的音频批次(列表,每段音频独立)。 |
| 音频R | AUDIO | 音轨 18 的音频批次(列表,每段音频独立)。 |
| 音频S | AUDIO | 音轨 19 的音频批次(列表,每段音频独立)。 |
| 音频T | AUDIO | 音轨 20 的音频批次(列表,每段音频独立)。 |