Join Videos
Stitch your 5-second clips without leaving the graph
- filenames
- videos
- filenames
- video
You asked Wan for 20 seconds, you got 81 frames - five seconds and a shrug. Video is still chunked, and the workaround has been "make short clips and edit them together"; people genuinely cut 50+ three-second clips into music videos. The single-node chunkers (SCAIL-2 Infinity, Bernini Infinity, SVI) now hide the stitching inside the sampler, but when your segments are files on disk - per-segment VACE extensions, a loop rendering one segment per iteration - you need something to concatenate them. ComfyUI core has no "join two finished videos" node, and Video Helper Suite's Video Combine batches a frame sequence rather than joining two encodes. So you either drop to the ffmpeg CLI or grab a node like this one. Join Videos is the least glamorous node in zyd232's pack and probably the most useful.
What it actually does
The node takes two autogrow groups. filenames holds paths, one per slot - or several per slot, separated by commas or newlines, deliberately, so it can swallow the comma-prefixed accumulator string a forLoopEnd-style loop hands you. videos holds ComfyUI VIDEO objects. filenames merges first, then videos, each group in slot order. In-memory VIDEO inputs get dumped to a temp file first, because underneath it's all one ffmpeg concat-demuxer call.
There are two modes here. Leave crf at -1, keep pingpong off, don't pick GIF, and make sure every source already has the target container's extension - then the join is -c copy, a byte-level stream copy. No re-encode, no generation loss, and it takes a second or two however long the clips are. Anything else re-encodes with your chosen format and crf. If the copy fails - drifted codecs between segments, usually - the node warns and retries as a re-encode.
The re-encode path also applies scale=out_color_matrix=bt709, normalising every segment to the same colour matrix VHS's Video Combine writes - the fix for the familiar "my reversed clip came out darker" colour-range mess. And save_metadata embeds the prompt/workflow as an FFMETADATA1 sidecar rather than a command-line argument, dodging Windows' command-line length limit. Someone shipped that bug for real.
The knobs that matter
crf- the only one you'll touch most days.-1means "don't touch the quality, and take the lossless path". Set it and you're re-encoding, clamped to the format's range (0–51 for H.264/H.265, 0–63 for VP9/AV1; ProRes ignores it entirely).format-video/h264-mp4(libx264, CRF 19) by default; h265-mp4, h264-mkv, webm (VP9), av1-webm (SVT-AV1), prores-mov and gif are the rest.frame_rate- only used when re-encoding. If you're stream-copying, each source keeps its own timing and this setting does nothing at all. That trips people up constantly.filename_prefix- defaults tozyd232_merged, and expands%date/%timeitself, so they work via the API too.
pingpong appends a reversed copy for a forward-then-backward loop; loop_count repeats the result afterwards. Both force a re-encode of the affected part. save_output off sends the file to temp/ instead of output/. Both input groups cap at 32 slots.
The filenames output is a VHS_FILENAMES value - the (save_output, [path]) shape VHS nodes expect - so it wires into Prune Outputs and friends. video is a plain VIDEO for core nodes.
Install
No models, no heavyweight deps. Manager → search ComfyUI-zyd232-Nodes, or:
cd ComfyUI/custom_nodes
git clone https://github.com/zyd232/ComfyUI-zyd232-Nodes.git
Restart; it's under the zyd232 Nodes category. requirements.txt pulls torch, numpy, Pillow and imageio-ffmpeg - that last one is where ffmpeg comes from. Caveat: the pack is built on ComfyUI's V3 node API with autogrow inputs, so it wants a reasonably current ComfyUI - on an old checkout it won't import at all.
Where it goes wrong
"Join Videos: ffmpeg was not found." Install imageio-ffmpeg into ComfyUI's env, or put ffmpeg on PATH. Mind the lookup order: the bundled static build wins and PATH is only the fallback - so if you picked AV1 or ProRes and that build lacks the encoder, you get an ffmpeg error, not a hand-off to your system ffmpeg.
It re-encoded when you wanted a lossless join. Three suspects: crf isn't -1, or one source isn't the target container (a single .webm among .mp4 re-encodes the whole thing), or the copy failed on mismatched codecs and fell back. The console warning names it.
"video file not found: X (searched: output, temp)" - relative paths resolve against output/ then temp/; a path from a folder elsewhere needs to be absolute.
A flash or colour jump at the seam. This is a sore spot across the whole video pipeline, not a concat bug - it comes from sources with inconsistent or missing colour flags, the same thing people hit joining Wan clips in a video editor. Stay in copy mode where you can. And since the pack is young and small, there won't be a forum thread for every error: read the console output.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| filename_prefix | STRING | zyd232_merged | Output filename prefix. Supports date placeholders: the core style %date:yyyy-MM-dd%, or the shorthand %date / %time. |
| frame_rate | FLOAT | 24.01–240 | Frame rate used when re-encoding and reported in the preview. A lossless stream copy keeps each source's own timing. |
| format | COMBO | video/h264-mp4 | Output container / codec |
| crf | INT | -1-1–63 | Lower is better quality and a bigger file. -1 keeps the quality untouched, which enables the lossless stream-copy path. The usable range and the default value depend on the selected format (0-51 for H.264/H.265, 0-63 for VP9/AV1; ProRes ignores CRF). |
| save_metadata | BOOLEAN | true | Embed the prompt / workflow metadata into the output container |
| pingpong | BOOLEAN | false | Append a reversed copy of the merged video (play forward, then backward). The reversed half is re-encoded. |
| loop_count | INT | 00–100 | How many extra times to repeat the merged video (0 = play once) |
| save_output | BOOLEAN | true | Save into the output directory. When off, the result goes to the temp directory. |
| filenamesopt | COMFY_AUTOGROW_V3 | Video file paths to merge. A slot may also hold several paths separated by commas or newlines. | |
| videosopt | COMFY_AUTOGROW_V3 | VIDEO inputs to merge, appended after the filenames group. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| filenames | VHS_FILENAMES | — |
| video | VIDEO | — |