AetherScale • Video Combine
The encoder node that stopped growing vertically
- images
- audio
- video_path
- stats
If you've copied a video workflow off the internet, you already have VHS Video Combine in it - it's the default terminal node of the genre. AetherScale • Video Combine is a drop-in replacement for that slot: an IMAGE batch (plus optional AUDIO) in, an MP4/MKV/MOV out, with NVENC, x264 or ProRes doing the encoding.
Two reasons to reach for it over the incumbent. It never holds more than a bounded chunk of frames in RAM, which matters when your batch is 1500 frames of upscaled video. And the preview widget behaves: v0.9.2 of the pack was largely a fix for this node growing taller after every execution - the most annoying bug class in the video-node space, if you've ever left one sitting in a graph overnight. The preview is now one LiteGraph DOM widget, sized from the node width and the real aspect ratio.
How the fast path works
It isn't frame-by-frame Python. Frames are packed several at a time into one contiguous RGB8 buffer in a single Torch operation, handed to FFmpeg through the buffer protocol (no separate .tobytes() copy), and a small producer thread pre-converts the next chunk while FFmpeg/NVENC consumes the current one. Memory stays flat because chunk_mb caps the chunk and pipeline_depth caps how many are in flight - the README's own numbers are chunk_mb = 64 and pipeline_depth = 2, and those defaults are fine.
Before a single frame is streamed, the node runs an NVENC preflight: a real test encode on the physical GPU, with the actual pixel format and geometry. If the encoder can't do it, it either falls back to another NVIDIA encoder (nvenc_codec_fallback, on by default) or fails in a second instead of twenty minutes in. Odd dimensions get padded where yuv420p demands it.
Inputs that matter
frame_rate - the number that decides whether your clip is the right length. If you loaded with AetherScale • Video Loader, wire its frame_rate output straight in. codec - h264_nvenc is the default and the right choice most of the time; hevc_nvenc and av1_nvenc for smaller files, libx264 when there's no NVIDIA hardware, and the prores_* ladder when you're handing off to an editor. container is mp4/mkv/mov, but pick any prores_* codec and it forces .mov with the matching prores_ks profile - ProRes ignores bitrate_mbps, preset and nvenc_gpu entirely, and 4444/XQ preserve alpha if you handed it a 4-channel image.
bitrate_mbps (default 20), preset (p3 for speed, p4 for a little more compression), pixel_format (yuv420p for anything you'll play in a browser), nvenc_gpu - leave it on auto unless you have two cards, where the multi-GPU handling is genuinely the nice bit: the chosen physical adapter is isolated for the FFmpeg child and remapped to logical CUDA GPU 0, so a PyTorch-restricted device list and nvidia-smi's physical ordinals stop disagreeing.
save_output - flip it off and the preview goes to ComfyUI's temp folder, still viewable, not littering your output dir. save_metadata and metadata_target are the interesting ones: the node walks upstream from the images link, finds the nearest seed/sampler/scheduler/model, and writes them into a <video>.metadata.json sidecar, into the container as readable tags, or both. Override any of it with the seed, sampler_name, scheduler and model_name inputs. The encode is where a workflow's provenance usually dies, and this node tries not to let it.
audio and audio_bitrate_kbps mux an AUDIO input as AAC via a temporary WAV. save_silent_copy is off by default and you almost never want it on - it just adds a second, silent file.
Outputs are video_path and stats, both strings; stats carries the encoder, routing and frame counts.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/vizart-vj/ComfyUI-AetherScale.git
or Manager → search AetherScale → install → restart. No pip packages; NVIDIA's VFX wheel is bootstrapped inside the pack rather than installed into your environment.
Where people get burned
FFmpeg must exist. AetherScale checks PATH, then the binary bundled with VideoHelperSuite and a few known VHS paths - so on a machine that already has VHS there's nothing to fix. Without it you get a plain "FFmpeg was not found" error and no output.
ProRes won't preview in the node on most browsers, because browser support for MOV/ProRes is what it is. The file is fine; open it in a player.
Windows and NVIDIA, effectively. The generic path is just FFmpeg and will work elsewhere with libx264, but the NVENC routing layer assumes nvidia-smi, and the rest of the pack is Windows-only.
Inputs (22)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| frame_rate | FLOAT | 24.000.01–1000 | — |
| filename_prefix | STRING | AetherScale/%date:yyyy-MM-dd%/AetherScale | — |
| container | COMBO | mp4 | 3 options: mp4, mkv, mov |
| codec | COMBO | h264_nvenc | 10 options: h264_nvenc, hevc_nvenc, av1_nvenc, libx264, prores_proxy, prores_lt, +4 |
| preset | COMBO | p3 | 7 options: p1, p2, p3, p4, p5, p6, +1 |
| nvenc_gpu | COMBO | auto | 1 options: auto |
| bitrate_mbps | INT | 201–1000 | — |
| pixel_format | COMBO | yuv420p | 2 options: yuv420p, yuv444p |
| save_output | BOOLEAN | true | — |
| chunk_mb | INT | 648–512 | — |
| pipeline_depth | INT | 21–4 | — |
| audioopt | AUDIO | — | |
| audio_bitrate_kbpsopt | COMBO | 192 kbps | 10 options: 64 kbps, 96 kbps, 128 kbps, 160 kbps, 192 kbps, 256 kbps, +4 |
| nvenc_codec_fallbackopt | BOOLEAN | true | — |
| save_silent_copyopt | BOOLEAN | false | — |
| save_metadataopt | BOOLEAN | true | — |
| metadata_targetopt | COMBO | sidecar_json | 3 options: sidecar_json, video_container, both |
| seedopt | INT | -1-1–18446744073709550000 | — |
| sampler_nameopt | STRING | — | |
| scheduleropt | STRING | — | |
| model_nameopt | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video_path | STRING | — |
| stats | STRING | — |