Nodes/MediaForge/πŸ“€ Save Video Frames
ComfyUI Node

πŸ“€ Save Video Frames

Write an IMAGE batch to disk as H.264, HEVC, AV1, ProRes β€” or a proper GIF

By leon80148Β·Created 4 months agoΒ·Updated 2 months agoΒ· 0
πŸ“€ Save Video Frames
  • frames
  • audio
  • final_video_path
β—„filename_prefixMediaForge/videoβ–Ί
β—„fps30.0β–Ί
β—„codech264 NVIDIA GPU (h264_nvenc)β–Ί
β—„encode_modecrfβ–Ί
β—„crf18β–Ί
β—„bitrate_kbps4000β–Ί
β—„target_size_mb8.0β–Ί
β—„presetmediumβ–Ί
β—„pix_fmt_overrideβ–Ί

MF_SaveVideoFrames is the tensor-to-file endpoint of MediaForge: it takes an IMAGE batch (plus an optional AUDIO dict) and writes an actual encoded video. It's the flip side of MF_LoadVideoFrames, and together they give you a symmetric rawvideo roundtrip at PSNR > 38 dB. Where VideoHelperSuite's save node tops out at H.264, this one hands you H.264 / HEVC / AV1 / ProRes plus NVENC variants and even a two-pass GIF encoder - which is the "export a proper animated GIF" feature people don't expect from ComfyUI.

The rate-control story is where it earns its "broadcast-grade" label. encode_mode has three exclusive modes: crf (quality-driven, default), bitrate (target a kbps number), and target_size (auto-compute bitrate so the file lands at a given MB). The frontend hides the widgets you're not using, so you don't stare at bitrate_kbps while in CRF mode. And the smart codec default applies here too: NVENC picked automatically when available, libx264 otherwise.

How it works

The tensor is piped to FFmpeg as rawvideo and encoded per your settings. A few deliberate behaviors: ProRes outputs .mov (10-bit yuv422p10le), everything else .mp4, and gif (palette) outputs .gif via a two-pass palettegen/paletteuse with diff-stats palette and Bayer dithering - meaningfully better than FFmpeg's default GIF. An audio dict muxed in is respected except for GIF, which has no audio track (the node warns you). NVENC variants use -cq instead of -crf internally, but the UI stays unified - and the pack's warning is worth heeding: the same CRF number is not the same quality across codec families. Treat your value as a starting point, encode a short sample, compare, adjust.

The inputs that matter

  • frames - the IMAGE batch. Required.
  • fps - source fps for the pipe. Use MF_LoadVideoFrames's fps output for roundtrips.
  • codec - the eight-way choice, including gif (palette).
  • encode_mode - crf / bitrate / target_size; the widgets switch with it.
  • crf - 18 default; lower = higher quality/bigger file, within the family's meaning of CRF.
  • preset - ultrafast … veryslow; the trade is encode time vs. size/quality.
  • pix_fmt_override - leave empty for codec defaults (yuv420p for x264/x265, yuv422p10le for ProRes); only touch it if you know pixel formats.

Output: final_video_path.

Install

Part of MediaForge:

cd ComfyUI/custom_nodes
git clone https://github.com/leon80148/comfyui_MediaForge.git
# restart ComfyUI

Or ComfyUI Manager β†’ "MediaForge". System ffmpeg preferred; fallback binaries come via requirements.txt.

Common issues

If you export a GIF and it's silent, that's expected - GIF can't carry audio. If an NVENC encode fails on an older NVIDIA card, that's the hardware: av1_nvenc needs Ada Lovelace (RTX 4000+), and the pack auto-falls back to CPU encoders when it can't. And the CRF-across-codecs trap is the one that produces "why is this AV1 file 5Γ— the size?" - compare per-family, don't carry a number from x264 to x265 or SVT-AV1. When in doubt, crf=18 + medium on libx264 is the boring, correct baseline.

CategoryMediaForge/Video

Inputs (11)

NameTypeDefaultDescription
framesIMAGEβ€”
filename_prefixSTRINGMediaForge/videoβ€”
fpsFLOAT30.01–240β€”
codecCOMBOh264 NVIDIA GPU (h264_nvenc)8 options: h264 (libx264), hevc (libx265), av1 (libsvtav1), prores (prores_ks), h264 NVIDIA GPU (h264_nvenc), hevc NVIDIA GPU (hevc_nvenc), +2
encode_modeCOMBOcrf3 options: crf, bitrate, target_size
crfINT180–51β€”
bitrate_kbpsINT4000100–200000β€”
target_size_mbFLOAT8.00.5–4000β€”
presetCOMBOmedium9 options: ultrafast, superfast, veryfast, faster, fast, medium, +3
pix_fmt_overrideSTRINGβ€”
audiooptAUDIOβ€”

Outputs (1)

NameTypeDescription
final_video_pathSTRINGβ€”