MiniMax H3 Audio Lock (TJ)
Actually making H3 keep the audio you gave it
- av_latent
- audio
- audio_vae
- av_latent
- audio
- report
Here's the thing nobody warns you about with MiniMax H3: it treats reference audio as a reference. You can hand it a song, write "keep the original audio exactly as-is" in the prompt, and the model will still invent its own version - same vibe, different performance. That's great for creative remixes and infuriating for lip-sync, music videos, and dubbing, where the audio has to be exactly what you fed in. MiniMax H3 Audio Lock (TJ) is the node that forces the issue.
The mechanism is genuinely elegant and it's pure ComfyUI-standard behavior. H3 samples video and audio together in one combined latent - a NestedTensor with two streams, video at [B,24,T,H,W] and audio at [B,32,2,T_a]. The sampler applies the latent's noise_mask every step as result = result * mask + original_latent * (1 - mask). So a mask of 0 means "denoise nothing here, keep restoring the original." This node encodes your source audio into the H3 audio VAE, splices that latent into the audio stream's slot, and sets the audio mask to 0 while leaving the video mask at 1 (full generation). Result: the video is created fresh around an audio track that is mathematically forced to stay the input.
The inputs that matter:
av_latent- the H3 AV latent from a conditioning node. Mandatory.audio- your source audio (AUDIO type, from a loader or the pack's own nodes). Mandatory.audio_vae- the H3 audio VAE. Mandatory. If you connect the wrong VAE, encoding fails loudly.mode-lock(audio fully frozen, mask=0) orremix(audio keepsstrength-worth of the original; the model fills the rest). Remix is the fun one - it's a dial between "exact copy" and "reimagine it."strength- remix-only. 0 = preserve original, 1 = model recreates. Ignored in lock mode.fit- what to do when your audio is shorter than the target length:pad_silence,loop, orstretch_none(pad but warn). Longer audio is always trimmed.
It also has the pack's wireless inputs (get_name_av_latent, get_name_audio, get_name_audio_vae, auto_set) for receiving from TJ Set nodes. Outputs are the locked av_latent, a pass-through audio (the original source, unmodified - use this for final muxing), and a report string.
Now the part that trips everyone up, and the author calls it out in the report: the H3 audio VAE is a neural codec, and encode→decode does not reproduce the original waveform. Content survives; phase doesn't. So if you check "did the lock work" by comparing waveforms, you'll see near-zero correlation even on a successful lock. Compare spectrograms instead, and trust the mask math - a 0 mask on audio is algebraically exact preservation in the latent, not an approximation.
Install
Ships in ComfyUI-TJ_NODE:
cd ComfyUI/custom_nodes
git clone https://github.com/designloves2/ComfyUI-TJ_NODE
or ComfyUI Manager → "ComfyUI-TJ_NODE", then restart. No extra Python deps for this node; it needs ComfyUI's built-in H3 support and the H3 audio VAE weights. And the usual H3 license reminder: the local-weights path is excluded in the US, EU, UK and South Korea.
Troubleshooting
- "H3 AV latent가 아닙니다" - the latent isn't the two-stream H3 format. It must come from an H3 conditioning node, not a generic empty latent.
- Audio encode error - wrong or missing audio VAE. Confirm it's a
minimax_h3_audio_vae_*model. - Audio longer than the clip - it's trimmed to the target; if the tail matters, shorten the source first or bump the clip length.
- Silence in the padded section - expected when
fitpads and your source is short.loopinstead if you want it filled with audio. The report warns if the source is under half the target length. - Decoded output "doesn't match" the original - see the waveform-vs-spectrogram note above. Use the node's
audiooutput for the final mux and it'll be the true original.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| get_name_av_latent | COMBO | (none) | 1 options: (none) |
| get_name_audio | COMBO | (none) | 1 options: (none) |
| get_name_audio_vae | COMBO | (none) | 1 options: (none) |
| auto_set | BOOLEAN | false | — |
| mode | COMBO | lock | lock: 오디오를 원본 그대로 고정(mask=0). remix: strength 만큼만 원본을 유지하고 나머지는 모델이 생성. |
| strength | FLOAT | 0.500–1 | remix 전용. 오디오 스트림의 mask 값. 0에 가까울수록 원본 유지, 1에 가까울수록 모델이 새로 생성. lock 모드에서는 무시됩니다. |
| fit | COMBO | pad_silence | 오디오가 목표 길이보다 짧을 때의 처리. pad_silence: 뒤를 무음으로 채움 / loop: 원본을 반복 / stretch_none: 무음 패딩하되 리포트에 경고. 길면 항상 잘라냅니다. |
| av_latentopt | LATENT | — | |
| audioopt | AUDIO | — | |
| audio_vaeopt | VAE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| av_latent | LATENT | — |
| audio | AUDIO | — |
| report | STRING | — |