OpenMontage

命令行工具

calesthio/OpenMontage

全球首个开源 Agent 视频制作系统。

项目简介

OpenMontage 可将 AI 编程助手变为完整视频工作室,提供 12 条流水线和 52 个工具,支持研究、脚本、素材生成和编辑,兼容免费与付费工作流。

README 预览

\n  \n\n\nOpenMontage\n\nThe first open-source, agentic video production system.\n\n\n  Paste A Video  · \n  Quick Start  · \n  Try These Prompts  · \n  Pipelines  · \n  How It Works  · \n  Providers  · \n  Agent Guide\n\n\n\n  \n\n\nFollow The Build\n\n\n  \n  \n  \n\n\n---\n\nTurn your AI coding assistant into a full video production studio. Describe what you want in plain language — your agent handles research, scripting, asset generation, editing, and final composition.\n\n**Important distinction:** OpenMontage can make image-based videos, but it can also make a real **video video** for free/open-source workflows: the agent builds a corpus from free stock footage and open archives, retrieves actual motion clips, edits them into a timeline, and renders a finished piece. That is not the usual "animate a handful of stills and call it video" trick.\n\n\n  \n\n\n> **"SIGNAL FROM TOMORROW"** — a cinematic sci-fi trailer fully produced through OpenMontage: concept, script, scene plan, Veo-generated motion clips, soundtrack, and Remotion composition.\n\n\n  \n\n\n> **"THE LAST BANANA"** — a 60-second Pixar-style animated short about a lonely banana who finds friendship with a kiwi. 6 Kling v3-generated motion clips (via fal.ai), Google Chirp3-HD narration, royalty-free piano music, TikTok-style word-level captions, and Remotion composition. Total cost: **$1.33**.\n\n\n  \n\n\n> **"VOID — Neural Interface"** — a product ad produced with just one API key (OpenAI). 4 AI-generated images (gpt-image-1), TTS narration, auto-sourced royalty-free music, word-level subtitles via WhisperX, and Remotion data visualizations. Total cost: **$0.69**. Zero manual asset work.\n\n\n  \n\n\n> **"Afternoon in Candyland"** — a Ghibli-style anime animation. A little girl's whimsical afternoon adventure through candy gates, gumdrop rivers, and lollipop gardens. 12 FLUX-generated images with multi-image crossfade, cinematic camera mot

常见问题 (5)

故障排除
如何修复 FFmpeg afade=t=out 导致延迟的 audio_mixer 音轨在最初几秒后变为静音的问题?

发生这种情况是因为 afade=t=out:d=N 默认 st=0,因此淡出从流的起始处就开始。经过 N 秒后,音轨在剩余的时长内(包括被延迟的片段)都保持静音。

修复方法是探测每个源音轨的时长,并显式设置淡出的起始时间。在 adelay 之前,基于源时间轴应用淡入淡出:

import subprocess

duration = float(
    subprocess.check_output([
        "ffprobe", "-v", "error",
        "-show_entries", "format=duration",
        "-of", "csv=p=0",
        track_path,
    ]).strip()
)

if fade_in > 0:
    filters.append(f"afade=t=in:st=0:d={fade_in}")

if fade_out > 0:
    fade_out_start = duration - fade_out
    filters.append(
        f"afade=t=out:st={fade_out_start:.4f}:d={fade_out}"
    )

# 在源时间轴的淡入淡出之后添加 adelay。
filters.append(f"adelay={int(start_seconds * 1000)}|{int(start_seconds * 1000)}")

如果 afade 应用在 adelay 之后,则使用:

fade_out_start = start_seconds + duration - fade_out
filters.append(f"afade=t=out:st={fade_out_start:.4f}:d={fade_out}")

在 _mix() 和 _duck() 中都要应用同样的修正。临时变通方法是移除 fade_out_seconds,或者在 amix 之后放置一个基于最终输出时间轴的单个 afade 滤镜。

来源 Issue #347
故障排除
为什么 hyperframes_compose 会报告 "render exited 0 but output file missing",尽管 MP4 已经成功渲染?

相对路径 output_path 会相对于两个不同的工作目录进行解析。渲染子进程以 cwd=workspace 运行,因此它将文件写入 workspace 目录下,但随后的 output_path.exists() 检查是相对于工具进程的 CWD(通常是仓库根目录)执行的。修复方法是在渲染之前将输出路径一次性解析为绝对路径:

output_path = Path(
    inputs.get("output_path") or (workspace / "renders" / "final.mp4")
).expanduser().resolve()

在 --output 参数和文件存在性检查中都使用这同一个绝对路径。作为临时解决方案,可以传入绝对路径形式的 output_path,或者到 <workspace>/<relative-output> 下查找成功渲染的文件,而不是将该消息当作真正的渲染失败来处理。

来源 Issue #360
故障排除
如何修复 FFmpeg chromakey overlay 生成 1x1 纯色视频并丢失主体的问题?

背景保持为 1x1,因为 scale=iw:ih 使用的是颜色源自身的尺寸,而 overlay 使用其第一个输入的尺寸。在叠加之前,使用 scale2ref 将 1x1 的背景缩放到前景帧的尺寸:

ffmpeg -y -f lavfi -i "color=c=0x0E172A:size=1x1" -i frame.png \
  -filter_complex "[0:v][1:v]scale2ref[bg][fgbase];[fgbase]chromakey=color=0x00FF00:similarity=0.3:blend=0.08[fg];[bg][fg]overlay=0:0" \
  -frames:v 1 out.png

等效的滤镜图:

[0:v][1:v]scale2ref[bg][fgbase];
[fgbase]chromakey=color=0x00FF00:similarity=0.3:blend=0.08[fg];
[bg][fg]overlay=0:0

在 GreenScreenProcessor._process_chromakey 中,将空操作的 [0:v]scale=iw:ih[bg] 步骤替换为此 scale2ref 流程。使用以下命令验证结果:

ffprobe -v quiet -show_entries stream=width,height -of csv=p=0 out.png

它应报告源帧的尺寸,例如 320,240,而不是 1,1。

来源 Issue #336
故障排除
如何修复在 transformers 5 上所有 CLIP 嵌入都失败时,corpus_builder 却报告成功且生成空的 index.jsonl 的问题?

出现此问题的原因是 transformers>=5.0 更改了 get_image_features() 的返回类型,而 lib/clip_embedder.py 期望的是 5.x 之前的张量 API。这会导致每张图像都处理失败,但旧版本的 corpus_builder 即使在 clips_added=0 时也会返回 success=True。

临时解决方法:将 Transformers 降级到最新的 4.x 版本:

pip install "transformers<5"

例如:

pip install "transformers==4.46.3"

然后删除空的 index.jsonl 并重新运行 corpus_builder。在运行 clip_search 或检索之前,请确认结果报告中 clips_added > 0。

永久修复方案:

1. 在 requirements.txt 或安装说明中固定该依赖项:

transformers<5

2. 更新 lib/clip_embedder.py,通过适当地解包张量或 pooler_output 来处理 transformers>=5 的返回值。
3. 使 corpus_builder.execute() 在没有任何候选项被嵌入时执行失败关闭(fail closed):

if candidates_seen > 0 and clips_added == 0:
    return ToolResult(
        success=False,
        error=f"All {candidates_seen} candidates failed to embed",
        data={"errors": errors},
    )

还可以添加高失败率检查,但核心条件是:非空运行若产生零个 clip,则不得报告成功,也不得写入一个看似有效的空语料库索引。

来源 Issue #357
故障排除
如何修复在 ComfyUI 中 WAN 2.2 文生视频生成的有效 MP4 文件里出现闪烁、互不相关的静止画面的问题?

使用时空视频 latent,而不是图像 latent。在自带的 wan22-t2v-4step.json 中,将节点 11 的 EmptyLatentImage 替换为 EmptyHunyuanLatentVideo:

"11": {
  "class_type": "EmptyHunyuanLatentVideo",
  "inputs": {
    "width": 832,
    "height": 480,
    "length": 81,
    "batch_size": 1
  }
}

然后更新 ComfyUIVideo._build_t2v,使其不再将 batch_size 设置为帧数,而是改为修补 length:

node_11["inputs"].update({
    "width": width,
    "height": height,
    "length": num_frames,
    "batch_size": 1,
})

EmptyLatentImage(batch_size=81) 会创建 81 张独立的图像,从而导致频闪效果。EmptyHunyuanLatentVideo(length=81, batch_size=1) 则会创建一个连贯的 81 帧视频 latent。这与 ComfyUI 官方的 WAN 2.2 t2v 模板一致。

ffprobe 无法检测到该问题,因为 MP4 容器、编解码器、时长和帧数都是有效的。请通过观看输出或比较相邻帧来验证;损坏的渲染会呈现出很大的帧间差异,而连贯的运动则呈现微小、平滑的差异。如果使用的是受维护的版本,请应用 workflow/builder PR,并可选择性地添加来自配套验证 PR 的运行时频闪检测。

来源 Issue #526