从 AI 生成视频中自动找出最短无缝循环单元——用尽可能少的帧构成一个首尾自然相接的环,重复播放即可得到任意时长的无限循环视频。
产出物是「最短环」本身(几十帧甚至更少),不是长视频���辑。设计文档见 docs/plan.md。
把本仓库克隆到 ComfyUI 的 custom_nodes 目录,然后安装依赖:
cd ComfyUI/custom_nodes
git clone <this-repo-url> ComfyUI-MinLoop
cd ComfyUI-MinLoop
pip install -r requirements.txt重启 ComfyUI 即可在节点菜单的 MinLoop 分类下找到所有节点。
视频后端:至少需要安装一个视频后端。默认推荐
imageio[ffmpeg](最轻量、纯 pip、跨平台,已在 requirements.txt 中)。若需要光流运动门槛(motion_metric=optical_flow)或备选后端,额外安装opencv-python。
| 节点 | 作用 |
|---|---|
| Load Video Frames | 视频 → IMAGE batch([T,H,W,C] float RGB),可改帧率/裁帧/缩放 |
| Find Minimal Loop | 最短环搜索:输出最优环单元 + start/end/length + 视觉分/运动分 + 接缝预览 |
| Extract Loop Unit | 按 start/end 切环(去重与起点重复的末帧) |
| Tiny Seam Blend | 可选 0–4 帧接缝 crossfade(环已很短时建议 0–1 帧,避免拖影) |
| Repeat Loop | 把环单元重复 N 圈,方便预览 3–4 圈判断是否闪烁 |
| Save Loop Video | 写出循环单元视频(mp4/gif/webp/...) |
Load Video Frames
│
▼
Find Minimal Loop ──(loop_unit)──► Repeat Loop (3~4) ──► Save Loop Video
│
└──(start/end)──► Extract Loop Unit ──► Tiny Seam Blend ──► Save Loop Video
- 想要更短/更稳:在 Find Minimal Loop 调
l_min、visual_threshold、motion_threshold。 - 在最短可行层的 Top-K 之间切换:调 Find Minimal Loop 的
candidate_index。 - 精修切点:把
start/end接到 Extract Loop Unit 手动覆盖,或 ±几帧微调。
对帧序列 F[0..T-1] 找一对索引 (s, e):
- 硬约束:
visual(F[s], F[e]) ≥ visual_threshold且(开启运动时)motion(seam) ≥ motion_threshold - 主目标:最小化环长
L = e - s - 次目标:相同
L下选接缝分更高者
搜索从短到长扫 L,一旦某层出现可行解就停在该层,收集该层全部可行解、按分排序取 Top-K(最短优先,质量只作门槛)。两段式筛选避免假短环:
- 粗筛:低分辨率(默认 64px)批量 SSIM 找候选;
- 复核:高分辨率(默认 160px)SSIM + 可选直方图相关复核;
- 运动:接缝处
F[e-1]→F[s]的运动一致性作硬门槛——默认用帧差(纯 torch),opencv-python在场时可用光流。
导出约定:循环播放 [s, e),不含与起点重复的 F[e],成片约 L 帧。
「AI 选」在本插件里指自动最短环搜索(约束优化、本地、可复现),不是生成式模型挑帧。
| 维度 | 方法 | 说明 |
|---|---|---|
| 视觉 | 向量化 SSIM(高斯窗) | [0,1],1=完全相同 |
| 视觉 | 颜色直方图相关 | ssim_hist 模式下与 SSIM 各 0.5 权重 |
| 视觉 | MSE 相似度 1/(1+mse) |
mse 模式,粗筛/快速 |
| 运动 | 帧差一致性 | 默认,纯 torch |
| 运动 | 光流一致性(Farneback) | 需 opencv-python,方向+幅度 |
核心算法(search / metrics / motion / loop_ops)只依赖 numpy/torch,可在无 ComfyUI 环境下用合成数据单元测试:
python tests/test_metrics.py
python tests/test_loop_ops.py
python tests/test_search.py合成测试用「按帧滚动的随机纹理」(真实周期精确为 P)验证:搜索能精确找到最短可行环长度 = P、运动门槛能放行/拦截、门槛过高返回空。
ComfyUI-MinLoop/
├── __init__.py # 顶层注册:NODE_CLASS_MAPPINGS(经典 API)
├── requirements.txt
├── minloop/
│ ├── nodes.py # 6 个 ComfyUI 节点(经典 API)+ 接缝预览
│ ├── search.py # 最短环搜索:粗筛 + 高分辨率复核 + 硬门槛
│ ├── metrics.py # 向量化 SSIM / 直方图相关 / MSE
│ ├── motion.py # 帧差一致性 + cv2 光流可选
│ ├── loop_ops.py # 切环 / 去重 / 极短 crossfade / 重复
│ ├── io_video.py # imageio/cv2/torchvision 后端回退的视频读写
│ └── utils.py # 张量转换 / 降采样
└── tests/ # 合成序列单元测试
- 过短导致闪烁:强制
l_min;预览时至少用 Repeat Loop 重复 3–4 圈再判断。 - 找不到短环:逐步增大
l_max;仍失败说明源视频周期性不足或门槛过高。 - 假短环(低分辨率误判):候选必须经高分辨率复核。
- 运动周期 ≠ 画面周期:运动一致性为硬门槛,避免「像但动作接不上」。
MIT