Audio Dynamics
Compressor, gate, limiter, de-esser — one node, four ways to stop your audio misbehaving
- audio
- video
- audio
- fx_spec
Almost every audio problem is a dynamics problem in disguise: the voiceover peaks then vanishes, the music punches through the mix, the room tone never stops, the "s" sounds sizzle. Audio Dynamics is the one node that covers all four classic fixes - compressor, gate, limiter, and de-esser - behind a mode switch. If you only add one audio stage to your ComfyTV pipeline, make it this one.
Pick the mode for the job:
- compressor (default) - pulls the loud parts down so the whole track sits more evenly. The workhorse for voice and music.
- gate - cuts off everything below the threshold, killing room tone and mic hiss between words.
- limiter - a safety net that stops peaks from clipping or exceeding a target. The "put this last in the chain" mode.
- deesser - tames harsh sibilance on vocals via an
intensitycontrol.
How it works
The source maps each mode to a real FFmpeg filter - acompressor, agate, alimiter, and deesser - run through the pack's PyAV runner. The shared controls are the standard compressor vocabulary:
threshold_db(-60–0, default -20) - the level at which processing kicks in. Lower = more signal gets affected.ratio(1–20, default 4) - how aggressively the signal is reduced above threshold. Compression: 2–4 is gentle, 8+ is glue. For the gate it's the downward ratio; for the limiter it's effectively infinite (that's the point).attack_ms/release_ms(defaults 20 / 250) - how fast the processor responds and recovers. Slow attack lets transients through; fast release can pump.makeup_db(0–24, default 0) - gain added back after reduction, to restore loudness.knee(1–8, default 2.83) - how soft or hard the transition into compression is. Soft knee sounds musical; hard knee is more aggressive.intensity(0–1, default 0.5) - only used by the deesser.
Feed audio (COMFYTV_AUDIO) or video (its soundtrack). Outputs are audio plus an fx_spec (COMFYTV_FXSPEC) - a machine-readable record of the applied filter chain for the pack's FX Chain. Internal inputs (force_run_token, project_id, parent_output_id) are frontend plumbing; ignore them.
Installing ComfyTV
cd ComfyUI/custom_nodes
git clone https://github.com/jtydhr88/ComfyTV
Full backend restart, then ComfyTV → AudioFX; ComfyUI Manager finds "ComfyTV". Zero extra Python deps - the filters run through FFmpeg via PyAV, bundled with ComfyUI. No models.
The pack-wide install trap: on macOS / ComfyUI Desktop / multi-install machines, cd ComfyUI/custom_nodes can clone into the wrong instance - clone succeeds, stages never appear. Read the running instance's path from the startup log, clone into that instance's custom_nodes by absolute path (quote paths with spaces/parentheses), verify ComfyTV/__init__.py is top-level, restart the backend fully.
Common issues
- Limiter errors out. The code checks for FFmpeg's
alimiterfilter and raises if your build lacks it - pip-installedavwheels normally include it, but some distro builds don't. If you hit it, that's an FFmpeg build issue, not a node bug. - Compression makes everything quiet. You reduced the peaks but didn't add makeup gain.
makeup_dbexists for exactly this - bring the level back up after compressing. - Gate cuts off word tails.
release_msis too short, so the gate slams shut on the decay of words. Lengthen it, or raisethreshold_dbslightly so it's not fighting for every syllable. - De-esser barely does anything.
intensityis the only de-esser control here, and 0.5 is conservative. Crank it and listen - sibilance is very frequency-specific, so it's a "sounds right" dial, not a set-and-forget. - You're not sure what to set. Start with the defaults, compress 3:1 with a 20ms attack and 250ms release, then only touch what sounds wrong.
Compressor, gate, limiter, de-esser in one stage. That's the whole mix section of a DAW condensed into a single ComfyTV node.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| force_run_token | INT | 00–2147483647 | Internal — bumped on Run to invalidate ComfyUI's input cache. |
| project_id | STRING | Internal — populated by the projectStore on the frontend. | |
| parent_output_id | INT | 00–2147483647 | Internal — lineage parent set by spawn handlers on the frontend. |
| mode | COMBO | compressor | 4 options: compressor, gate, limiter, deesser |
| threshold_db | FLOAT | -20.0-60–0 | — |
| ratio | FLOAT | 4.01–20 | — |
| attack_ms | FLOAT | 20.000.01–2000 | — |
| release_ms | FLOAT | 250.000.01–9000 | — |
| makeup_db | FLOAT | 0.00–24 | — |
| knee | FLOAT | 2.831–8 | — |
| intensity | FLOAT | 0.500–1 | — |
| audioopt | COMFYTV_AUDIO | — | |
| videoopt | COMFYTV_VIDEO | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| audio | COMFYTV_AUDIO | — |
| fx_spec | COMFYTV_FXSPEC | — |