ZZX Audio & Subtitles / 音频字幕
The node that holds every audio decision for a transcode
- audio_subtitles
Video settings are the part everyone tunes. Audio is the part everyone forgets until the export is silent, or doubled, or the client says the subtitles are burnt into the wrong place. ZZX Audio & Subtitles / 音频字幕 exists so you make those decisions once, in a node that produces nothing but a wire, and hand that wire to the rest of the transcode chain.
It's a pure settings node. No file in, no picture out - just one output named audio_subtitles of type ZZX_AUDIO_SETTINGS, which plugs into the audio_subtitles input on ZZX Video Settings. Not into the converter directly: the converters take a whole ZZX_TRANSCODE_SETTINGS bundle, and Video Settings is what assembles it. Chain is Audio & Subtitles → Video Settings → Advanced / Batch Converter, which is exactly the workflow the pack ships as workflow-AdvancedVideoConverter.json.
The audio half
audio_encoder is the one that matters. auto picks by container - Opus for WebM/Opus, Vorbis for Ogg, MP3 for MP3, FLAC, pcm_s16le for WAV, AC-3 for MPEG, AAC everywhere else. copy passes the streams through untouched, none strips audio entirely (and is the right answer for GIF output). Beyond that you get AAC, libmp3lame, libopus, libvorbis, FLAC, ALAC, 16/24-bit PCM, AC-3 and E-AC-3, subject to what your FFmpeg build includes.
audio_tracks takes first, all, or zero-based indices like 0,2 - the README points you at Media Info to find out what order your tracks are in, and it's worth doing, because "first" in a file with a commentary track first is not the audio you wanted. audio_bitrate_kbps (8–1536), sample_rate (0 means leave it alone), channels (original / mono / stereo / 5.1), volume_db in a −60 to +30 range, and normalize_audio for a single-pass loudness pass at −16 LUFS / −1.5 dBTP. Upmixing to 5.1 gives you six channels of the same information, not surround - the filter duplicating a stereo field is not a spatial mix.
Two hard rules the code enforces rather than warns about. copy can't also change volume_db, normalize_audio, sample rate, channels or speed - pick re-encoding if you want any of those. And audio-only containers (MP3, M4A, WAV, FLAC, Opus, OGG) accept exactly one track, so all there is an error, not a merge.
The subtitle half
subtitle_mode is the whole story. none drops subtitles. copy carries every embedded subtitle stream across and needs a container that supports the original codec. embed muxes one track - embedded or from subtitle_file - as mov_text in MP4/MOV or SRT in MKV. burn draws it into the picture with libass, keeping styling.
subtitle_track is a zero-based index within the subtitle streams. subtitle_file is a server-side path to an .srt, .ass, .ssa or .vtt; leave it empty to use the embedded track. subtitle_language is the metadata tag like eng or jpn - cosmetic, but players use it to auto-select.
The failure modes here are honest ones. copy with an external subtitle_file errors - use embed or burn. Embedding or copying into anything other than MKV/MP4/MOV errors. Speed changes combined with copy or embed subtitles error out, because the timing would drift; burn them or turn them off. Bitmap subtitles (PGS, VobSub) can't be converted to text or burnt, so those need OCR first. And burn needs an FFmpeg built with the subtitles/libass filter - plenty of minimal Windows builds aren't.
Install
Manager: search ZZX (Comfy Registry: ComfyUI-ZZX). Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/ZZXYWQ/ComfyUI-ZZXYWQ
python -m pip install -r ComfyUI-ZZXYWQ/requirements.txt
Windows portable:
python_embeded\python.exe -m pip install -r ComfyUI\custom_nodes\ComfyUI-ZZXYWQ\requirements.txt
Then ffmpeg and ffprobe on PATH, or ZZX_FFMPEG / ZZX_FFPROBE, and a ComfyUI restart.
What trips people up
Nothing here does anything on its own. If you drop this node in, set it up, and hit queue, nothing happens - you need the Video Settings node downstream and a converter after that. The most common complaint about settings nodes is that they're silent, and this one is silent by design.
The second: embed re-wraps subtitles into a simpler format. Fancy ASS positioning, fonts and effects are lost, and custom attached fonts can render differently or not at all. If the styling is the point, burn instead - and accept that it's now pixels you can't turn off.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| audio_encoder | COMBO | auto | 13 options: auto, copy, none, aac, libmp3lame, libopus, +7 |
| audio_tracks | STRING | first | — |
| audio_bitrate_kbps | INT | 1928–1536 | — |
| sample_rate | INT | 00–192000 | — |
| channels | COMBO | original | 4 options: original, mono, stereo, 5.1 |
| volume_db | FLOAT | 0.0-60–30 | — |
| normalize_audio | BOOLEAN | false | — |
| subtitle_mode | COMBO | none | 4 options: none, copy, embed, burn |
| subtitle_track | INT | 00–100 | — |
| subtitle_file | STRING | — | |
| subtitle_language | STRING | und | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio_subtitles | ZZX_AUDIO_SETTINGS | — |