Nodes/ComfyUI-MediaUtilities/MediaUtilities_SaveVideo
ComfyUI Node

MediaUtilities_SaveVideo

The node that routes around your codec problems and actually muxes audio

By ThanaritKanjanametawatAU·Created about a year ago·Updated about a year ago· 3
MediaUtilities_SaveVideo
  • frames
  • audio
    fps30
    filename_prefixvideo/media_url_loader
    formatmp4
    codecauto
    quality85
    convert_from_gifTrue
    loop_count0
    pingpongFalse

    Core ComfyUI will happily save your frames as WEBP or PNG sequences, but it won't write an H.264 mp4 and it definitely won't put audio on one. That's this node's job. It's the heavy lifter in ComfyUI-MediaUtilities: feed it IMAGE frames, optionally an AUDIO wire, and it writes a real video file into your output folder - mp4, webm, avi, mov, or gif - with looping and pingpong built in.

    Why you'd reach for it

    You've generated a clip (Wan, LTX, Hunyuan, AnimateDiff - pick your poison) and you want something you can actually send to a group chat or drop into an edit. It's also the natural endpoint for this pack's chain: load audio from a URL, generate frames to it, and save the two together with the sound intact.

    How it works

    The mp4 path is a small pipeline, and it's the part people don't expect. Instead of encoding H.264 directly, it writes a GIF first (via imageio, falling back to Pillow), then shells out to the ffmpeg binary to transcode that GIF to libx264 (crf 23, yuv420p). If you passed an audio wire, it runs ffmpeg again to mux AAC in. Webm, avi, and mov skip the GIF detour and go through OpenCV's VideoWriter with a fallback chain of fourcc encoders - VP90 for webm, XVID then MJPG for avi, avc1 then mp4v for mov. If every encoder refuses, it falls back to a GIF, and with convert_from_gif set to True it then tries ffmpeg to convert back into the format you actually asked for.

    Inputs that matter

    • frames (IMAGE) and audio (AUDIO, optional) - the only wires in.
    • format (mp4/webm/avi/mov/gif) and codec (auto, h264, vp9, avc1, xvid, mjpg) - leave codec on auto unless you know exactly why you're overriding it.
    • fps (default 30) - match your generation's frame rate or the playback speed will lie to you.
    • filename_prefix (default video/media_url_loader) - output lands in ComfyUI/output/video/.
    • loop_count (0–10) and pingpong (True/False) - preprocess the frames into a loopable clip with no extra nodes.

    Outputs: none - it's an output node. It saves the file and returns preview info to the UI.

    Installing it

    Part of ComfyUI-MediaUtilities. ComfyUI Manager: Manager → Install Custom Nodes → search "ComfyUI-MediaUtilities". Or manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/ThanaritKanjanametawatAU/ComfyUI-MediaUtilities
    cd ComfyUI-MediaUtilities
    pip install -r requirements.txt
    

    Then restart ComfyUI. No model files to download. The requirements list requests, numpy, Pillow, torch, torchaudio, and opencv-python; the first two and torch/torchaudio are usually already in your environment. The two things that aren't in requirements and will bite you later: the ffmpeg binary (needed for mp4 and for muxing audio) and imageio (used for GIF writing, with a Pillow fallback).

    Gotchas

    • mp4 needs ffmpeg on your PATH, and it leaves litter. Every mp4 save writes an intermediate GIF and never cleans it up, so you'll find a stray .gif in your output folder next to each .mp4. Annoying, harmless, and easy to miss until your folder looks like a screensaver.
    • pip-built opencv wheels often lack H.264 and VP9 encoders - which is exactly why the mp4 path routes around OpenCV through ffmpeg. If avi works but mp4 doesn't, the node's own error message tells you the fix: install a conda build of OpenCV.
    • Failures are quiet. If ffmpeg is missing, the node returns an empty result rather than a loud exception. The pack logs with DEBUG on by default, so watch the console - "ffmpeg not found" will be sitting right there.

    For the common case - generated frames out, playable mp4 with audio back - it just works. Just remember the GIFs and the ffmpeg dependency.

    CategoryMediaUtilities

    Inputs (10)

    NameTypeDefaultDescription
    framesIMAGE
    fpsINT301–120
    filename_prefixSTRINGvideo/media_url_loader
    formatCOMBOmp45 options: mp4, webm, avi, mov, gif
    codecCOMBOauto6 options: auto, h264, vp9, avc1, xvid, mjpg
    qualityINT851–100
    convert_from_gifCOMBOTrue2 options: True, False
    audiooptAUDIO
    loop_countoptINT00–10
    pingpongoptCOMBOFalse2 options: True, False

    Outputs (0)

    No outputs