Nodes/ComfyUI_MetaSaver/Save Video with Custom Metadata (Dynamic)
ComfyUI Node

Save Video with Custom Metadata (Dynamic)

Twenty metadata fields on your video file

By SorenWeile·Created 9 months ago·Updated 6 months ago· 0
Save Video with Custom Metadata (Dynamic)
  • video
  • meta_value_0
  • meta_value_1
  • meta_value_2
  • meta_value_3
  • meta_value_4
  • meta_value_5
  • meta_value_6
  • meta_value_7
  • meta_value_8
  • meta_value_9
  • meta_value_10
  • meta_value_11
  • meta_value_12
  • meta_value_13
  • meta_value_14
  • meta_value_15
  • meta_value_16
  • meta_value_17
  • meta_value_18
  • meta_value_19
    ◄filename_prefixvideo/ComfyUI►
    ◄format▾►
    ◄codec▾►
    ◄meta_name_0►
    ◄meta_name_1►
    ◄meta_name_2►
    ◄meta_name_3►
    ◄meta_name_4►
    ◄meta_name_5►
    ◄meta_name_6►
    ◄meta_name_7►
    ◄meta_name_8►
    ◄meta_name_9►
    ◄meta_name_10►
    ◄meta_name_11►
    ◄meta_name_12►
    ◄meta_name_13►
    ◄meta_name_14►
    ◄meta_name_15►
    ◄meta_name_16►
    ◄meta_name_17►
    ◄meta_name_18►
    ◄meta_name_19►

    The video counterpart to MetaSaverDynamic: twenty label/value pairs instead of ten, written as tags on the video container rather than a PNG chunk. If you're tracking more than ten things per render - seed, both prompts, CFG, sampler, model hash, a couple of LoRA weights, a batch note - this is the one with room for it.

    What it actually wants wired in

    Read the GitHub README before you build this and you'll expect an image-batch input with an fps field. That's not what's on the canvas. The current node takes a single video input - an already-encoded VIDEO object, the kind that comes out of whatever node in your graph assembles frames into a video - not raw frames. There's no fps to set here; whatever framerate the incoming video was built at is what you get. Treat this node as the last stop that re-saves an already-built video with your metadata stapled onto it, not as the thing that builds the video in the first place.

    Inputs and outputs that matter

    • video (VIDEO, required) - the encoded video from upstream.
    • filename_prefix (STRING, default video/ComfyUI) - lands in a video/ subfolder of your output directory by default, not alongside your images.
    • format - auto (match the source container) or force mp4.
    • codec - auto (match the source codec) or force h264.
    • meta_name_0…meta_name_19 / meta_value_0…meta_value_19 - twenty optional label/value pairs. meta_value takes any type - wire in an int, a string, a float, whatever's on hand. Blank pairs are silently skipped.

    No output socket - terminal save node, same as the standard video variant.

    Installing it

    ComfyUI Manager: search "MetaSaver", install, restart - or manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/SorenWeile/ComfyUI_MetaSaver
    

    then restart. The video nodes in this pack need PyAV (pip install av) to actually write the container tags; it ships with most ComfyUI distributions already, but if this node doesn't show up after a restart, that's the first thing to check in the console log.

    Where it trips people up

    The Dynamic-specific gotcha, straight from the author's own notes: pull the individual tags back out (not the JSON blob) and they come out prefixed with meta_ - a field you named cfg_scale reads back as meta_cfg_scale under ffprobe -show_format_tags or exiftool. If a script downstream expects the bare name, that prefix breaks it; read the structured custom_metadata JSON tag instead and you get your literal names back.

    Otherwise the usual suspects: a meta_name with no value wired in (or the reverse) just vanishes rather than erroring, so check both halves of a pair before assuming something's broken. And if you're not actually filling more than ten fields, the plain MetaVideoSaver does the same job with less canvas clutter.

    Categoryimage/video

    Inputs (44)

    NameTypeDefaultDescription
    videoVIDEO—
    filename_prefixSTRINGvideo/ComfyUI—
    formatCOMBO2 options: auto, mp4
    codecCOMBO2 options: auto, h264
    meta_name_0optSTRING—
    meta_value_0opt*—
    meta_name_1optSTRING—
    meta_value_1opt*—
    meta_name_2optSTRING—
    meta_value_2opt*—
    meta_name_3optSTRING—
    meta_value_3opt*—
    meta_name_4optSTRING—
    meta_value_4opt*—
    meta_name_5optSTRING—
    meta_value_5opt*—
    meta_name_6optSTRING—
    meta_value_6opt*—
    meta_name_7optSTRING—
    meta_value_7opt*—
    meta_name_8optSTRING—
    meta_value_8opt*—
    meta_name_9optSTRING—
    meta_value_9opt*—
    meta_name_10optSTRING—
    meta_value_10opt*—
    meta_name_11optSTRING—
    meta_value_11opt*—
    meta_name_12optSTRING—
    meta_value_12opt*—
    meta_name_13optSTRING—
    meta_value_13opt*—
    meta_name_14optSTRING—
    meta_value_14opt*—
    meta_name_15optSTRING—
    meta_value_15opt*—
    meta_name_16optSTRING—
    meta_value_16opt*—
    meta_name_17optSTRING—
    meta_value_17opt*—
    meta_name_18optSTRING—
    meta_value_18opt*—
    meta_name_19optSTRING—
    meta_value_19opt*—

    Outputs (0)

    No outputs