Nodes/MiniMax H3 Preview/MiniMax H3 Audio Preview
ComfyUI Node

MiniMax H3 Audio Preview

Your MiniMax H3 clip has audio you've been silently throwing away

By Brioch·Created about a month ago·Updated about a month ago· 2
MiniMax H3 Audio Preview
  • model
  • audio_vae
  • MODEL
window_seconds3.0
start_at_percent50
every_n_steps1
max_preview_overhead15

MiniMax H3's whole party trick is that it generates stereo audio in the same forward pass as the picture - dialogue, sound effects and room tone, synced to the video it was denoised next to. And then every live preview in the ecosystem throws that half away. ComfyUI's built-in preview literally keeps x0.tensors[0] (the video) and drops the audio stream, and the preview socket has no audio event to carry sound on anyway. This node is the fix: it sits in your H3 workflow, decodes the audio half of the latent as the sampler runs, and draws a waveform in the node you can play before the render even finishes. No API, no key, nothing to sign up for.

How it works

The clever part is how it finds the audio. H3 ships a packed audio+video latent - one tensor with both streams - and the pack deliberately reads H3's numbers rather than hard-coding them. The audio stream is found by matching your VAE's latent channel count, not by assuming it's stream number two. The sample rate comes from the decode itself, and the latent frame rate behind window_seconds is measured from the first decode (frames in versus samples out). So a VAE variant at a different rate or channel count decodes correctly instead of quietly producing nonsense, and mono stays mono instead of getting doubled.

It also undoes a scale trick that would otherwise bite you. H3 denoises audio and video on different flow shifts, and ComfyUI reconciles that by scaling the audio latent onto the video schedule (ModelSamplingAV.audio_scale, typically 4.0). Decode without dividing that back out and the audio VAE gets a latent several times too large - which comes back as loud noise at every step, while the video decodes perfectly. That's the kind of bug that looks like a broken model.

The node registers itself as an outer-sample wrapper with its own key, so it chains with whatever draws your frames instead of replacing it. You keep KJNodes' Preview Override with Kijai's taeh3 for video and add this alongside. The decoded clip is served from ComfyUI's own server over HTTP (the author tried data: and blob: URLs; browsers refused both), and the panel draws a per-channel envelope - blue left above, green right below.

The inputs that matter

Only two of the six need real thought. model is the model to attach to - and this is the trap: its output is what the sampler must read, or nothing happens. A node whose output goes nowhere is never executed. audio_vae gets minimax_h3_audio_vae, the real decoder. Wire the video VAE here and the preview logs which two channel counts didn't match.

The rest are quality-of-life. window_seconds (default 3, up to 15) decodes from the start of the shot - the part that lines up with a looping preview; 0 does the whole clip (~520 MB). Cost scales with it, but a three-second window is only ~110 MB and a fraction of a second, so there's no need for a "tiny audio VAE" like video's taeh3. start_at_percent (default 50) skips the early steps, when the audio stream is still mostly noise and every decode would be spent on hiss. every_n_steps and max_preview_overhead (default 15%) are throttles.

Install

From ComfyUI Manager, search "MiniMax H3 Preview", or:

cd ComfyUI/custom_nodes
git clone https://github.com/Brioch/ComfyUI-MiniMaxH3-Preview

then restart ComfyUI. There are no Python dependencies beyond what ComfyUI already installs, but you need ComfyUI 0.30.0+ - that's where H3's packed audio+video latent landed. You also need the audio VAE, minimax_h3_audio_vae_fp32.safetensors, in ComfyUI/models/vae/. It's the same file your finished render decodes with, so if you've rendered an H3 clip you likely already have it.

Gotchas

  • Sound is off until you click it. Browsers refuse audio on a page you haven't interacted with, and a queued render shouldn't start talking. The button tells you which is happening: 🔇 click for sound means a click fixes it; ⚠ clip unplayable means the browser refused the audio itself - check the console.
  • Nothing plays and the log says "no audio stream found" means your latent isn't H3's packed one. It has to come from EmptyMiniMaxH3LatentAV, MiniMaxH3ImageToVideo, or MiniMaxH3ReferenceToVideo.
  • H3 itself is the real prerequisite, and it's heavy - roughly 42 GB reported for the weights, with no verified consumer-hardware floor yet. And check the MiniMax H3 Community License: the open weights exclude the US, EU, UK and South Korea from its Applicable Territory, so in those regions the local-weights path isn't licensed at all.

There's also a bundled offline test (test_audio_preview.py) that runs with no GPU, model or server - handy before committing to a long H3 render.

CategoryMiniMax H3

Inputs (6)

NameTypeDefaultDescription
modelMODELModel to attach the audio preview to.
audio_vaeVAEminimax_h3_audio_vae. The real decoder, and the one that says how many channels the audio stream has so it can be picked out of the pack. H3's audio has no tiny equivalent of taeh3, and does not need one: a three-second window is ~110 MB and a fraction of a second.
window_secondsFLOAT3.00–15Seconds of audio to decode, from the START of the shot — the part that lines up with a preview animation looping from frame one. Cost scales with it. 0 decodes the whole clip (~520 MB at 15s).
start_at_percentINT500–100Don't decode until this share of the steps is done. Early on the audio stream is still mostly noise, so the decodes would be spent on hiss.
every_n_stepsoptINT11–50Never update more often than every N sampler steps.
max_preview_overheadoptINT150–100Cap on how much of the render time this may use, in percent. Updates are also never sent faster than the clip plays, so you always hear one through. 0 disables the cap.

Outputs (1)

NameTypeDescription
MODELMODELModel with the audio preview attached.