Nodes/Save Images to Video (FFmpeg) for ComfyUI/Save Images to Video (FFmpeg)
ComfyUI Node

Save Images to Video (FFmpeg)

Turn your frame pile into an actual MP4 without leaving ComfyUI

By San4itos·Created about a year ago·Updated 12 months ago· 5
Save Images to Video (FFmpeg)
  • images
  • audio
    filename_prefixVID
    fps24
    codeclibx264
    pixel_formatyuv420p
    crf23
    output_formatmp4
    audio_codecaac
    audio_bitrate192k
    output_file_opt-preset medium

    Every video workflow ends the same way: you've got 81 beautiful frames sitting in RAM and nothing watchable on disk. This is the node that fixes that. Save Images to Video (FFmpeg) takes an IMAGE sequence - from a Wan or LTX decoder, an AnimateDiff pass, a frame-interpolation chain, whatever - and runs it through a real FFmpeg encode into an MP4, WebM, MOV, AVI, or MKV. It's the last mile of ComfyUI video, and it's refreshingly boring about it.

    How it works

    The mechanism is exactly what it looks like: the node writes your frames out as PNGs into a temp folder, then shells out to FFmpeg with -framerate <fps> -i frame_%06d.png, applies your encode settings, and drops the result in your normal ComfyUI/output directory with the usual auto-counter filename (VID_00000_.mp4). No new Python dependencies to fight - the pack's requirements.txt is literally just Pillow; torch, numpy, and torchaudio all ship with ComfyUI already.

    One nice touch buried in the code: it embeds your whole ComfyUI workflow into the file as an FFmpeg comment metadata tag, the same trick ComfyUI uses for PNGs. Drag that MP4 back into the canvas later and the graph that made it comes with it. If you pass an AUDIO input (say, from an audio-gen node), it's muxed in as a WAV before encode.

    The inputs that matter

    • images - the only thing you have to wire. Feed it any IMAGE output; it doesn't care how many frames.
    • fps - default 24, range 1–120. Set this to match what you generated at, or you'll get that "why is my video sped up" panic.
    • codec - default libx264 is the one you'll use 90% of the time: plays everywhere. libx265 gets smaller files but is slower and less player-friendly; libvpx-vp9 is for WebM; libsvtav1 is the fancy AV1 option and it is slow on CPU, budget accordingly.
    • pixel_format - default yuv420p for a reason: it's the compatibility baseline. The yuv420p10le / yuv422p10le / yuv444p10le 10-bit options give you better gradient quality for HDR-ish work but some players and social sites choke on them.
    • crf - 0–63, default 23. Lower is higher quality, and 23 is a fine starting point. 18–20 if you're archiving, 28+ for throwaway drafts.
    • output_format - mp4, webm, mov, avi, or mkv.
    • audio (optional) plus audio_codec / audio_bitrate - mux in a soundtrack; AAC at 192k is the sane default.
    • output_file_opt - free-form FFmpeg flags, one per line, e.g. -preset slow. These override the GUI settings, so if you set -crf here it wins.

    Installing it

    Via ComfyUI Manager, search "Save Images to Video" and install. Or manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/San4itos/ComfyUI-Save-Images-as-Video
    cd ComfyUI-Save-Images-as-Video
    pip install -r requirements.txt
    

    Then restart ComfyUI and find it under Add Node → San4itos. There are no model downloads.

    The thing that actually breaks

    FFmpeg itself. The node looks for it in this order: a path in ffmpeg_config.ini, then an ffmpeg binary in the node's ffmpeg_bin/ folder, then the system PATH. If none of those pan out, every encode dies on startup. The fix is usually just dropping ffmpeg (or ffmpeg.exe) into ffmpeg_bin/ - that's the zero-friction option on Windows where nothing is ever on PATH by default. Watch the console on first load; the resolver logs exactly which source it picked.

    Two more real gotchas. First, if you connect audio, the encode uses -shortest, so a soundtrack that doesn't match your video length gets cut off at the shorter of the two. Second, the FFmpeg call has a 300-second timeout - a long 4K libsvtav1 encode can blow past it and error out mid-encode. For big jobs, drop the resolution or reach for libx264. Compared to the video-helper-suite option most people start with, this is the leaner, less magical alternative: fewer features, no imageio dependency, but dead simple to reason about when something goes wrong.

    CategorySan4itos

    Inputs (11)

    NameTypeDefaultDescription
    imagesIMAGE
    filename_prefixSTRINGVID
    fpsFLOAT241–120
    codecCOMBOlibx2644 options: libx264, libx265, libvpx-vp9, libsvtav1
    pixel_formatCOMBOyuv420p7 options: yuv420p, yuv422p, yuv444p, yuv420p10le, yuv422p10le, yuv444p10le, +1
    crfINT230–63
    output_formatCOMBOmp45 options: mp4, webm, mov, avi, mkv
    audiooptAUDIO
    audio_codecoptCOMBOaac4 options: aac, mp3, libopus, copy
    audio_bitrateoptCOMBO192k6 options: 96k, 128k, 160k, 192k, 256k, 320k
    output_file_optoptSTRING-preset mediumCustom FFmpeg output options. One option per line, e.g., -preset slow

    Outputs (0)

    No outputs