Save Video
The Writer That Finds the Perfect Loop Point for You
- images
- audio
- images
What it is
Save Video is ComfyUI's built-in video saver, done the Eclipse way: it accepts an IMAGE batch plus optional AUDIO plus an fps straight from any generator - no separate VIDEO type required - and it writes an mp4 to your output folder. That alone would be worth having, but the reason you'd actually choose it is the loop machinery. This node can find the frame where your clip loops seamlessly and cut there.
Video generation at 16 fps doesn't loop. A video loop that jumps when it restarts is a failed loop, and fixing it by hand means scrubbing frames and eyeballing. This node automates the eyeball: it scans the tail of your clip for the frame that best matches frame 0, trims there, and optionally crossfades the tail back into the start.
How it works
Two feature sets. The first is straightforward encoding: frames + optional audio → mp4 via PyAV (h264 by default, CRF-controlled quality, a preset that trades encode speed against file size). The trim_mode widget is the alignment layer - when you have both video and audio, it decides which wins: video_to_audio shortens the frame batch to fit the audio, audio_to_video shortens the audio to fit the frames, shortest clips both to the shorter side. Without audio it's ignored.
The second feature set is the loop finder. In loop_match mode the node searches the frame batch's tail (the loop_search_pct, default 50% - so the back half) for the frame most similar to frame 0, and trims there, giving you a cut where the clip restarts seamlessly. loop_match_blend goes further: same search, then crossfades the last loop_blend_frames (default 8) into the start. The loop_metric dropdown picks how "similar" is measured - ncc (normalized cross-correlation, invariant to brightness/color drift and the recommended default), mse, luminance_mse, or gradient_mse (edge-magnitude only, color-blind, matches structure). And loop_trim_start optionally scans the start of the clip too, for when neither end is a clean match.
The inputs that matter
- images - the batch of frames.
- fps - output frame rate.
- filename_prefix - where it lands; default
video/ComfyUI_Eclipse. - format / codec - mp4 / h264 by default.
- crf - quality, 0–51, lower is better; 18–23 is the sweet spot.
- trim_mode - video_to_audio / audio_to_video / shortest / loop_match / loop_match_blend.
- loop_metric, loop_search_pct, loop_blend_frames, loop_trim_start - the loop-finder tuning.
- audio (optional) - track to mux.
Output: images - the frame batch after any trim or loop processing, passed through as a list.
When you'd use it
Whenever your video pipeline ends in a file: straightforward Wan/LTX render → mp4, image-batch + audio → synced clip, and especially seamless-loop work - background loops, GIF-style repeaters, anything that plays on a cycle. If you've ever rendered a "perfect loop" that visibly snaps, the loop matcher is worth a try before you hand-fix it.
Installing it
Part of ComfyUI_Eclipse:
cd ComfyUI/custom_nodes
git clone https://github.com/r-vage/ComfyUI_Eclipse
pip install -r ComfyUI_Eclipse/requirements.txt
then restart, or use Manager (search "Eclipse"). This node needs PyAV (av) - ComfyUI ships it for its own video nodes, but a stripped environment may need pip install av into the ComfyUI Python. And as everywhere in the pack (formerly RvTools_v2), old pre-v4.0.0 workflows may need the bundled migration tool.
Common issues
The loop finder isn't magic - a clip with no self-similarity (a cut, a scene change, heavy motion) has no good loop point, and the node will pick the least-bad match. For seamless loops, start with ncc and raise loop_search_pct if the tail doesn't contain a good match. And loop_blend_frames: 0 disables blending even in blend mode, so a "blend did nothing" mystery usually means that widget. Finally, remember the output is the trimmed frames - if you expected the full-length clip back, check trim_mode.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | Batch of frames to save. | |
| fps | FLOAT | 24.001–240 | Output video frame rate. |
| filename_prefix | STRING | video/ComfyUI_Eclipse | Filename prefix in the output directory. |
| format | COMBO | mp4 | Output container format. |
| codec | COMBO | h264 | Output video codec. |
| crf | INT | 190–51 | Quality factor (lower = higher quality, larger file). 18–23 is a good range. |
| preset | COMBO | veryfast | Compression preset. Does not affect visual quality (controlled by CRF). Faster presets encode quicker but produce larger files; slower presets compress better at the same CRF. |
| trim_mode | COMBO | video_to_audio | Align frame batch and audio duration before saving (ignored when no audio). loop_match: trim to the end-frame closest to frame 0 for a seamless loop. loop_match_blend: same as loop_match but crossfades the tail into the start. |
| loop_search_pct | INT | 501–99 | Percentage of the frame batch (tail) to scan when searching for a loop point. Only used by loop_match and loop_match_blend modes. |
| loop_blend_frames | INT | 80–60 | Number of frames to crossfade at the end of the loop. Only used by loop_match_blend mode. 0 disables blending. |
| loop_metric | COMBO | ncc | Similarity metric used to find the best loop point. ncc: normalized cross-correlation — invariant to brightness/color drift (recommended). mse: raw per-pixel MSE — fast but sensitive to brightness differences. luminance_mse: grayscale MSE — ignores hue/saturation shifts. gradient_mse: edge-magnitude MSE — color-blind, matches structure only. |
| loop_trim_start | BOOLEAN | false | When enabled, also scans the beginning of the batch for the frame that best matches the tail cut-point, then trims the start there. Produces a tighter loop when neither end of the clip is a perfect match. Only used by loop_match and loop_match_blend modes. |
| audioopt | AUDIO | Optional audio track to mux. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | The saved frame batch after any trim or loop processing. |