ComfyUI Node

Video Merge

Concatenate two mp4s without the duplicated frame stutter

By DadoIrie·Created 2 years ago·Updated a day ago· 10
Video Merge
    • mp4_path
    mp4_path_1
    mp4_path_2

    If you've ever glued two video clips together and watched a single frozen frame flicker at the seam, you know exactly why this node exists. Video Merge concatenates two mp4 files end to end - and deliberately drops the first frame of the second video so that the last frame of clip one doesn't duplicate with the first frame of clip two. That deduplication is the whole point; it's the difference between a seamless cut and a stutter.

    The use case that makes it click is chained generation. Generate clip A, extract its last frame with the pack's Video Last Frame node, feed that frame into an i2v model to make clip B, then merge A+B. Repeat, and you've built a long continuous video out of model-sized chunks - with no visible hitch where they join.

    How it works

    Two inputs, both mp4_path_1 and mp4_path_2 (file paths on disk), and it calls ffmpeg under the hood:

    ffmpeg -y -i a.mp4 -i b.mp4 \
      -filter_complex "[1:v]select='gte(n\,1)',setpts=PTS-STARTPTS[v1trimmed];[0:v][v1trimmed]concat=n=2:v=1:a=0[outv]" \
      -map "[outv]" output.mp4
    

    Reading that filter: it takes video 1's frames, selects only frames from index 1 onward in video 2 (gte(n\,1) - skipping frame 0), resets video 2's timestamps to start at zero (setpts=PTS-STARTPTS), then concatenates. Audio is explicitly dropped (a=0) - this is a video-only merge, so don't expect sound to survive. The result is written to ComfyUI's temp directory with a generated name, and the output is the resulting mp4 path as a STRING.

    The caveats

    • ffmpeg must be on PATH. Same story as the sibling Video Last Frame node: the code shells out to the ffmpeg command directly. If the merge fails with a "No such file or directory" in the logs, that's your missing ffmpeg binary, not the videos.
    • Both files must exist and be real paths. The node validates both before running; a bad path gives you a clear error naming the file.
    • It drops audio. a=0 means any soundtrack from either clip is gone. If you need sound, re-mux after the merge.
    • Same codec/resolution assumption. A naive concat filter needs compatible streams; merging radically different resolutions or codecs can fail or look wrong. For the chained-generation use case (same model, same settings) this is a non-issue.

    Where it fits

    Honestly, this is a specialist node. If you just need to join two arbitrary files, ffmpeg on the command line does the same job with more control. The node earns its keep inside a workflow - when the merge has to happen automatically between generation steps, when the paths come from other nodes rather than from your hands, and when you want the result to land back in ComfyUI's tree so a preview node can play it. That's a narrow slot, but it's a real one, and the frame-drop is the detail that makes it better than a naive concat.

    Install

    Same pack, same drill: ComfyUI Manager → "Dados Nodes", or

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

    then restart. Needs an on-PATH ffmpeg; no models, no keys.

    Common issues

    The frame-drop is frame one of the second clip - if your clip B starts with a fade-in or a very different scene, dropping its first frame is irrelevant and the cut may still look abrupt; that's a content problem, not a node problem. And if the merged file doesn't appear, check the temp directory (ComfyUI/temp) - the output path lands there, so wire it straight into a video preview node (like the pack's Preview Image) to confirm it worked.

    CategoryDado's Nodes/Video

    Inputs (2)

    NameTypeDefaultDescription
    mp4_path_1STRING
    mp4_path_2STRING

    Outputs (1)

    NameTypeDescription
    mp4_pathSTRING