ComfyUI Node

⬡ Polyhedron Save

The output node that writes stills, video, audio and masks from one place

By PolyhedronAI·Created 3 months ago·Updated a day ago· 2
⬡ Polyhedron Save
  • image
  • video
  • audio
  • mask
  • path
  • fps
filename_prefixPolyhedron
media_kindauto
image_formatpng
image_quality100
video_presetH.264 MP4 (delivery)
quality17
frame_rate24.00
autoplayfalse
pingpongfalse
loop_count0
trim_to_audiofalse
save_metadatatrue
save_outputtrue

The Polyhedron Save is the counterpart to this pack's Media Loader, and it does something most save nodes don't: it picks the writer from what you actually wire into it. Feed it a VIDEO and it writes a video; an IMAGE and it writes stills; an IMAGE plus audio and it muxes a clip; a MASK alone and it writes grayscale stills. media_kind is set to auto and infers all of that, so you don't swap nodes when a job changes shape - you rewire.

Two details make it genuinely useful. First, it embeds the workflow into whatever it writes (PNG text / MP4 metadata), so a file can be dragged back into ComfyUI to restore the graph. And second, when it writes a clip it drops a still frame beside it as a control image - because an .mp4 can't carry a workflow, but a PNG can. That little habit has saved more "which run was this again?" moments than any log.

The inputs

  • image - stills or frames.
  • video - native VIDEO. This is where the loader pairing shines: video_audio from the Media Loader carries its trimmed companion track along, muxed into the written clip. A wired audio replaces a video's audio.
  • mask - alpha, kept for png/webp stills and alpha-capable presets (ProRes 4444).
  • Outputs: path (full path of the written file) and fps (the rate it was written at) - the fps output is handy for wiring Interpolate's output into a Save that builds video from an image batch.

Naming is a path, not a label

filename_prefix is the sleeper feature. Every / creates a subfolder under ComfyUI/output/, and tokens expand before the path is built: %date:yyyy-MM-dd%, %date:hhmmss%, %width%, %height%, even %KSampler.seed% (ComfyUI core expands other nodes' widgets). So %date:yyyy-MM-dd%/PH_%date:hhmmss% gives you one folder per day with files stamped to the second. The one trap: uppercase MM is the month, lowercase mm is the minute. A counter is always appended, so files never overwrite.

Video presets

video_preset spans delivery to archive: H.264 MP4 (small, universal, ComfyUI's own tested writer), H.265 MP4 (10-bit, grain-tuned so particles don't smear), ProRes 422 HQ and ProRes 4444 masters for editing, FFV1 lossless .mkv, WebM VP9, and animated WebP/GIF with a loop_count (0 = forever). The masters encode through bundled PyAV with a 16-bit intermediate, so the diffusion float precision reaches the encoder - less banding. quality is crf-style for the lossy presets (~17–20 is visually lossless); ProRes and FFV1 ignore it.

The levers

image_format picks png (lossless, embedded workflow) / webp / jpg (no alpha). frame_rate is only used when a video is built from an IMAGE batch - a wired VIDEO keeps its own rate. pingpong appends the reversed frames for a seamless boomerang loop; trim_to_audio cuts the longer of clip and audio so they end together; save_output off writes to a temp dir - preview only - which keeps output/ clean while you iterate.

Installing it

Part of the Polyhedron Suite pack:

cd ComfyUI/custom_nodes
git clone https://github.com/PolyhedronAI/ComfyUI-PolyhedronLoRAStack.git
# restart ComfyUI

or Manager, search "Polyhedron Suite". The masters need PyAV - recent ComfyUI builds ship it; if a preset errors, pip install "polyhedron-lora-stack[media]". The one thing that trips people: save_output defaults to writing real files, but if you're iterating a workflow you'll want it off, or you'll spend an afternoon emptying output/.

CategoryPolyhedron/IO

Inputs (17)

NameTypeDefaultDescription
filename_prefixSTRINGPolyhedronName under ComfyUI/output/. A '/' makes a subfolder. Optional tokens are expanded here: %date:yyyy-MM-dd% / %date:hhmmss%, %width%, %height% (illegal path characters are stripped so a token can never break the path). A counter keeps files unique.
media_kindCOMBOautoauto: infer from what's wired (VIDEO -> video; IMAGE+audio/fps -> video; IMAGE alone -> image; AUDIO alone -> audio). Or force 'image' / 'video'.
image_formatCOMBOpngStill format. png = lossless + embedded workflow (drag back to reload). webp = smaller / optional lossless. jpg = no alpha.
image_qualityINT1001–100webp / jpg quality (100 on webp = lossless). png ignores this (it uses lossless compression).
video_presetCOMBOH.264 MP4 (delivery)Delivery (small, universal) vs Master (edit/archive). H.264 uses ComfyUI's own tested writer; the masters use our bundled-PyAV encoder (10-bit via a 16-bit intermediate, intra keyframes).
qualityINT170–100crf-style quality for the lossy presets (lower = better/larger; ~17-20 is visually lossless). ProRes/FFV1 ignore it.
frame_rateFLOAT24.000–240fps when a video is built from an IMAGE batch. A wired VIDEO keeps its own rate (this is ignored then). Convertible to an input -- wire Interpolate's fps output here so interpolated frames keep their true duration.
autoplayBOOLEANfalseIn-node video preview: off = show first frame with play controls (a single-frame clip never jumps). On = play automatically (muted); loops only when the clip has >1 frame.
pingpongBOOLEANfalseAppend the reversed frames (forward then back) for a seamless boomerang loop.
loop_countINT00–1000GIF / animated-WebP loop count (0 = loop forever).
trim_to_audioBOOLEANfalseMatch the clip length to the wired audio (trim the longer of the two) so video and sound end together.
save_metadataBOOLEANtrueEmbed the workflow + prompt (PNG text / MP4 metadata) so the file can be dragged back into ComfyUI.
save_outputBOOLEANtrueOn: write to ComfyUI/output/. Off: temp dir (preview only, keeps output/ uncluttered while iterating).
imageoptIMAGEStill(s) or video frames [N,H,W,3|4].
videooptVIDEONative VIDEO (frames + audio + fps ride through). Takes the Media Loader's `video` or `video_audio` output alike -- a `video_audio` wire carries its trimmed companion track along and it is muxed into the written clip.
audiooptAUDIOOptional audio to mux with image frames, or to replace a wired video's audio.
maskoptMASKOptional alpha [N,H,W] (opaque->0). Wired ALONE, the mask itself is saved as grayscale stills. Kept for png/webp stills and alpha-capable video presets (ProRes 4444).

Outputs (2)

NameTypeDescription
pathSTRING
fpsFLOAT