H3 Locked Audio Select
The ten-line node that decides whose audio ships
- generated_audio
- locked_audio
- audio
The whole node, in one sentence
It passes your locked audio through if that audio is real, and quietly hands back the model's generated audio if it isn't. Two AUDIO inputs, one AUDIO output, and that's the entire feature.
Why does that deserve a node? Because MiniMax H3 generates audio with the picture - dialogue, room tone, effects, from the same sampling pass, not a bolted-on second stage (minimax-h3.json). That's the model's headline trick, and it's why overriding it takes plumbing: locked audio in an H3 project isn't a reference, per the pack's own distinction - "the input audio constrains visual generation, and the delivered video uses the original task audio instead of regenerating it." Your track drives the mouth shapes and then ships as-is: dubbing and music videos in one graph, instead of the usual TTS → talking-head chain people run on Wan or LTX (audio-generation.md splits the field into models that invent audio and models that consume it; locked audio is the seam).
And the "if it isn't real" clause does real work. A locked track can legitimately be missing - muted, or a source video with no audio stream - and something still has to be on the audio wire, or the save step downstream gets nothing.
How it works
generated_audio is required - in practice the decoded H3 audio, after the project trimmed it back to the delivered segment length. locked_audio is optional.
At execution the node inspects the locked audio and accepts it only if three things hold: the waveform is a tensor with three dimensions, its last dimension is non-empty, and its sample rate is a positive integer. Anything else - None, an empty waveform, a malformed dict - and generated_audio goes straight through instead. No selector widget, no error, no silence.
That's the "optional inputs that aren't connected arrive as nothing, so nodes read None as not connected" convention, and this node is the textbook fallback-pick shape from comfyui-node-plumbing.md: walk the candidates, return the first one that isn't empty.
Equally important is what it doesn't do: no trim, no resample, no pad. Segment length is set by the video - H3 wants a 17k+5 frame pattern, and the project reserves frames for its temporal grid before stripping the repeated context prefix off the delivered clip. Sibling dev nodes handle that side: H3 Locked Audio Duration Align stretches a locked waveform onto the delivered frame count, and refuses outright if the mismatch is beyond its limit rather than smearing your audio. By the time the select node runs, everyone has agreed on a length.
Wiring it
Normally you don't wire it at all. easy multitrackProject builds one per segment that has a locked track, inside the graph it generates. The category is EasyUse/H3/dev and the schema is flagged is_dev_only=True, which in ComfyUI means what it says: hidden from search and menus unless dev mode is on. So if you went looking after spotting it in someone's workflow and couldn't find it, that's the answer - nothing is broken. A graph that already contains it renders and runs fine, and you can enable dev mode if you want to place one by hand.
Install is the pack. Manager, search ComfyUI-Easy-Media, restart; or:
cd ComfyUI/custom_nodes
git clone https://github.com/yolain/ComfyUI-Easy-Media
No pip dependencies - the pack ships none. But this node sits on the H3 path: you need the H3 model, CLIP, video VAE and audio VAE loaded in the model_loader feeding the project, and ComfyUI 0.34.0 or newer for the native H3 audio/video keyframes context continuity is built on. Keep FFmpeg on your PATH too - the README asks for it up front, and the pack's video and audio utilities really do call it.
Where people get burned
"My locked track isn't in the output." Check the lock is actually in effect. A muted track, or a video with no audio stream, doesn't lock - so the node correctly passes generated audio and you blame the wrong node. Version 1.3.3 tightened exactly this: muted tracks and videos without audio "no longer lock audio or repeat audio probing, while their video timeline timing remains unchanged."
Don't skip it and wire locked audio straight to your save node. This node is the fallback. Going direct gets you an error on the empty case instead of a graceful drop back to generated audio.
Audio out of sync at a join? This node moves a reference around and touches no samples, so look upstream: length alignment, the 22-frame context trim, or whether your locked track was ever the same duration as the clip you locked it to.
One non-code caveat before you invest a weekend in H3 graphs: the community licence excludes the US, EU, UK and South Korea from its applicable territory. Nothing to do with this node, everything to do with whether you're licensed to run the weights.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| generated_audio | AUDIO | — | |
| locked_audioopt | AUDIO | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |