Nodes/Video Combine (Custom Path)/Video Save Plus (Custom Path) 🎬
ComfyUI Node

Video Save Plus (Custom Path) 🎬

The save node that doesn't throw away your video's audio

By Slartibart23Β·Created 25 days agoΒ·Updated 9 days agoΒ· 3
Video Save Plus (Custom Path) 🎬
  • video
  • images
  • audio
  • filepath
β—„filename_prefixvideoβ–Ί
β—„custom_output_pathβ–Ί
β—„frame_rate24.00β–Ί
β—„video_codech264β–Ί
β—„crf19β–Ί
β—„presetmediumβ–Ί
β—„pixel_formatyuv420pβ–Ί
β—„audio_bitrate192β–Ί
β—„save_workflow_pngtrueβ–Ί
β—„save_workflow_jsonfalseβ–Ί
β—„png_compression4β–Ί
β—„save_framenoneβ–Ί
β—„frame_formatjpgβ–Ί
β—„frame_quality95β–Ί
β—„copy_to_folderβ–Ί
β—„source_video_pathβ–Ί
β—„prompt_textβ€”β–Ί
β—„seed0β–Ί

ComfyUI's default video output has a hole: it saves the pixels and, depending on which node you grabbed, quietly drops the soundtrack. That used to be fine - most video models were silent. Then MiniMax H3 landed with native stereo audio built in (the first serious open answer to Veo's audio gap), and "where's the sound?" became the most annoying question in the room. VideoSavePlus is the answer. It's a video output node that writes an MP4 with H.264/H.265 plus AAC audio to any folder on any drive, aimed squarely at the new class of models that hand you a VIDEO tensor with audio already attached.

Why v2 exists

This pack is a rewrite, and the changelog is the story. The old node, VideoCombineCustomPath, wrote audio through torchaudio.save, which silently drops the track on newer torchaudio versions - you'd get a pristine silent MP4 and never know. v2 pipes raw float32 PCM and raw RGB frames straight into ffmpeg over pipes: no torchaudio, no temp PNG sequence, and if an audio input can't be processed it raises a clear error instead of quietly succeeding. "Fails loudly" is the right design for a save node, because a silent "successful" render is worse than a red one. One-time cost: old workflows have to be re-wired to the new node name once.

What to plug in

  • video (VIDEO) - the output of native-audio models like MiniMax. Frames, audio, and frame rate are all pulled from it.
  • images (IMAGE) - the fallback for classic image-batch workflows; frame_rate only applies here, since a VIDEO input brings its own.
  • audio (AUDIO) - overrides the track inside a VIDEO input, handy for dubbing a silent generation.
  • filename_prefix - supports subfolders (scene1/take) and the placeholders %date%, %time%, %seed%, %date:yyyy-MM-dd hh-mm-ss%. A 5-digit counter is always appended.
  • custom_output_path - any folder on any drive; created if missing, empty falls back to ComfyUI's output dir.
  • crf (default 19) - the main quality knob: 17–19 is visually lossless, 0 is lossless, 28 is small.

The output is a single filepath string with the full path of the saved MP4 - wire it to a Text or a "Show Text" node if you want to see it in the UI.

The stuff that makes it a keeper

Beyond the video itself, each run writes a workflow PNG (drag it back onto the canvas to rebuild the graph - the same workflow-in-the-file convention ComfyUI's own SaveImage uses), an optional name.txt with your prompt, and optionally frames as first/last/all in jpg or png. That's the whole training pair in one folder, which is exactly what the Save Training File button is for: it copies the mp4 + png + txt + frames to copy_to_folder under identical names. There are also buttons to reveal the file in your file manager, play it with sound, grab the last frame losslessly, and delete the whole set - and the server endpoints only ever touch files this node saved in the current session, not arbitrary paths.

Install

Via ComfyUI Manager, search for Video Save Plus, or:

cd ComfyUI/custom_nodes
git clone https://github.com/Slartibart23/ComfyUI-CustomVideoSave

Restart ComfyUI and hit Ctrl+F5 in the browser once. The only hard dependency is ffmpeg on your PATH (or pip install imageio-ffmpeg as a fallback - the node checks both); requirements.txt is just pillow, so no torchaudio install to fight.

Gotchas

  • h265 is ~40% smaller at the same CRF but many players and browsers refuse it - h264 plays everywhere, and yuv420p is the compatibility-safe pixel format. yuv444p looks sharper on text/edges but is a browser no-go.
  • Odd frame dimensions get auto-scaled to even numbers for yuv420p - a classic ffmpeg footgun this node just handles for you.
  • If ffmpeg is missing, you get a loud error, not a silent file. That's the feature.
Categoryvideo/custom

Inputs (21)

NameTypeDefaultDescription
filename_prefixSTRINGvideoBase filename. May contain subfolders (scene1/take) and placeholders: %date% (2026-08-21), %time% (143012), %seed% (from the seed input), %date:yyyy-MM-dd hh-mm-ss%. A 5-digit counter (_00001) is always appended.
custom_output_pathSTRINGAny folder on any drive. Created if missing. Empty = ComfyUI's default output folder.
frame_rateFLOAT24.001–120Only used for the 'images' input. With a VIDEO input or source_video_path the video's own frame rate is used.
video_codecCOMBOh264h264 = plays everywhere (Windows, web, phones). h265 = ~40% smaller at the same quality but not every player/browser supports it. Ignored in passthrough mode.
crfINT190–51Constant quality. Lower = better and larger. 0 = lossless, 17-19 = visually lossless, 23 = ffmpeg default, 28 = small. Main quality control. Ignored in passthrough mode.
presetCOMBOmediumEncoding speed vs. file size at the SAME quality (CRF). Does not change picture quality. Slower = smaller file, longer encode. Ignored in passthrough mode.
pixel_formatCOMBOyuv420pyuv420p = maximum compatibility (standard). yuv444p = full colour resolution, sharper edges/text, but many players and all browsers refuse to play it. Ignored in passthrough mode.
audio_bitrateINT19264–320AAC bitrate in kbit/s. 128 = speech, 192 = very good, 256-320 = music/transparent. In passthrough mode only used when 'audio' replaces the original track.
save_workflow_pngBOOLEANtrueSave the first frame as PNG with the complete workflow embedded. Drag & drop into ComfyUI restores the workflow.
save_workflow_jsonBOOLEANfalseAlso save the workflow as name.json (plain JSON, loadable via Workflow > Open; readable without image tools).
png_compressionINT40–9PNG is ALWAYS lossless. This only trades file size against write time: 0 = fastest/largest, 9 = smallest/slowest. 4 is a good balance.
save_frameCOMBOnoneAutomatically save frames as images next to the video (name_first Frame / name_last Frame / name_frame_00001). The 'Save Last Frame' button works independently of this. 'all' needs frames (images/VIDEO), not available for passthrough without frames.
frame_formatCOMBOjpgImage format for saved frames. jpg = small, lossy. png = lossless, larger (uses png_compression).
frame_qualityINT9510–100JPEG quality for saved frames (ignored for png). 90-95 = excellent, 100 = near lossless but large.
copy_to_folderSTRINGTarget folder used by the 'Save Training File' button. Copies mp4 + png + json + txt + frames with identical names.
videooptVIDEOVIDEO output of models/nodes with native audio (e.g. Grok Imagine Video, MiniMax). Frames, audio and frame rate are taken from it and RE-ENCODED with the settings above. A connected 'audio' input overrides its audio track.
imagesoptIMAGEFrames as IMAGE batch (used when no VIDEO is connected). In passthrough mode optional: only used for the PNG/frames.
audiooptAUDIOAudio track. Overrides the audio contained in a VIDEO input. In passthrough mode it REPLACES the file's own soundtrack (video stream is still copied, not re-encoded).
source_video_pathoptSTRINGPASSTHROUGH: path of a finished MP4 (e.g. the video_path output of Grok Imagine Video). The file is copied 1:1 to the destination - no re-encoding, no quality loss, audio kept - and renamed/numbered like everything else. Codec/CRF/preset/pixel_format are ignored. Leave unconnected to encode video/images as usual.
prompt_textoptSTRINGSaved as name.txt next to the video (training pair). Nothing is written if empty.
seedoptINT00–18446744073709550000Only used for the %seed% placeholder in filename_prefix.

Outputs (1)

NameTypeDescription
filepathSTRINGβ€”