Community编程与开发github.com

gbax316/make-ai-short

构建一个端到端的 GENERATIVE-pixels 竖屏短视频(1080×1920,约 35-40 秒)——使用 fal 视频模型(默认 Seedance 1.5 Pro)生成一个循环锁定的角色动画,配合哲理性/故事性旁白,在 Remotion 中合成,包含词同步字幕、音效试听和帧 0==最后一帧无缝循环。

make-ai-short 是什么?

该技能是 `make-ai-short` 的完整工作流,用于生成由视频模型驱动像素、Remotion 负责合成的竖屏短视频(1080×1920,约 35-40 秒)。它与完全由 TSX 动画驱动的 `make-short` 以及基于拼贴的 `make-vox` 不同,其核心像素来源于视频模型(如 Seedance 1.5 Pro)。技能严格遵守三条铁律:1)**角色锁定**:所有角色图像和视频均基于 `character.json` 和 `character.png` 生成,避免同一角色出现不同外观;2)**先报价后生成**:在生成任何视频片段前,使用 fal 定价 API 计算并告知用户成本(约 $0.0583/秒);3)**约束循环**:通过将第一个镜头的真实帧 0 作为最后一帧的结束图像 URL 传入,实现精确循环,而非依赖运气。 该技能支持 `fal` 和 `kie.ai` 两种视频生成提供商,并包含完整的音画工作流程:先创建脚本和节拍,再使用 ElevenLabs 生成旁白/对话(支持多角色口型同步),然后逐帧 QA 起始帧和视频片段,最后在 Remotion 中合成字幕、进度条和淡出效果。对于对话场景,还提供 `mouth_sync.py` 工具自动覆盖模型生成的口型。最终输出需通过 `check_text.py` 的文本检查,并记录成本和经验教训。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/gbax316/shorts-director/tree/main/.claude/skills/make-ai-short

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

make-ai-short — 生成式短视频,端到端

像素来源于视频模型;Remotion 仅负责合成片段 + 字幕。已在 blue-man 第 1 集“The Door”上验证。 与 /make-short(纯 TSX)为兄弟技能——遵循相同纪律,外加 TSX 从未需要的三道关卡:生成前表明成本、从 character.json 锁定角色、通过结束帧条件固定循环。

所有操作在仓库根目录执行。需要 .env 中的 FAL_KEY(片段 + 图像)和 ELEVENLABS_API_KEY(语音)。

三条铁律

  1. 切勿从文本重复生成角色。 ai-shorts/<char>/character.json + character.png 是锁定的参考。每个需要该角色的静态图像都使用 gen_image.py --ref character.png;每个片段都是从已包含该角色的帧进行图像到视频的转换。如果角色表尚不存在,则在其他任何步骤之前,制作一个(并获得用户确认)是其自身的独立步骤。
  2. 在花费之前说明成本。 推导得出,非引用:Seedance 1080p 无音频 = h×w×24×dur/1024 tokens × $1.2/1M ≈ $0.0583/秒(fal 定价 API 已验证至 2026-07-14——完整表格及 Wan/Veo-Lite 陷阱请参见 ai-shorts/IDEAS.md)。始终使用 generate_audio:false——语音由 ElevenLabs 负责,音效使用我们的 SFX 管线。
  3. 通过约束而非运气实现循环。 镜头 1 的真正帧 0(从片段中提取,而非提示图像)是循环目标。最后一个镜头将其作为 end_image_url 传入(Seedance/Kling),合成在最后约 10 帧上稳定到该确切静态帧(remotion/src/shots/ai-1/Ai1Door.tsx 中的 LoopSettle 模式)。

产物约定

ai-shorts/<name>/
  script.md · beats.json            — 与 /make-short 相同约定(vo[] 包含真实单词时间)
  character.json                    — 锁定参考(+ video_model 块 = 所选模型)
  shots/NN-slug.png                 — 每个镜头的起始帧(gen_image.py --ref character.png [--ref scene])
  shots/NN-slug.json                — gen_clip 侧车文件(model, payload, request id)
  shots/upload-urls.json            — fal 存储 URL(上传在同一组重新生成中可重复使用)
  voice/ · sfx-plan.json · output/                                [voice/output 在 gitignore 中]
remotion/src/shots/ai-N/            — composition + vo.gen.ts
media/projects/<name>/              — 用于 staticFile() 的片段副本(已提交——像素不可重现;shots/*.mp4 工作副本在 gitignore 中)

操作顺序(语音优先于像素)

  1. 脚本 — script.md + beats.json。钩子在帧 0 处合成;主题应需要循环(blue-man 第 1 集:“到达是一个神话”→ 结尾 = 走向同一扇门)。约 80-100 单词,窗口 2.5-2.7 wps。绝无吸引互动的片尾,永远没有——在回报处结束,循环就是结局。
  2. 语音优先 — python tools/gen_voice.py --beats ... --emit-ts remotion/src/shots/ai-N/vo.gen.ts(语音和模型来自 .env,或当系列需要解说员(如 George JBFqnCBsd6RMkjVDRZzb,带 eleven_v3 标签)时来自 beats.json 的 "voice" 块;在生成任何片段之前,像 make-short 阶段 4 那样处理 LINE CHECK 标志)。真实单词时间决定镜头窗口;Seedance 接受整数 4-12 秒时长,因此从窗口向上取整镜头长度。 对话(两个或更多角色): beats.json 的 "cast" 将每个说话者映射到其 character.json(使用其 "voice" 块),每个旁白行在其 "who" 中指定说话者,--pack 0.3 根据真实长度将各行首尾相连,而不是将它们挤入估算的窗口。每个角色一个语音,存放在其 character.json 中,别无他处。 对话中的口型: 视频模型不知道谁在说话;它会让听众说话,冻结说话者,并在下一句上延长笑声。生成片段后,运行 python tools/mouth_sync.py ai-shorts/<name>(beats.json 的 "shots" 为每个片段提供全局起始和长度;每个 character.json 的 "mouth" 块提供侧面、半径、区域、样式和 keep_above)。它会擦除模型的口型,并根据语音轨道的响度绘制每个角色自己的口型。以相同方式进行 QA:每半秒检查两个面部与说话者的对应关系。一行内的动作变化(大笑,然后说话)需要两个片段,第二个片段从第一个片段在剪切时刻的帧开始。然后逐帧扫描每个口型同步片段:超过片段中位数四倍的尖峰是剪切点、快速手势或带有鬼影特征的两帧变形;在该镜头的 "hold" 中列出变形帧并重新运行,以便跳跃表现为干净的剪切。
  3. 起始帧 — 每个镜头一个,python tools/gen_image.py --model pro --aspect 9:16 --ref character.png(+ 当场景/道具需跨镜头匹配时,镜头 1 的场景静态帧作为第二个参考)。在任何视频调用之前对所有 PNG 进行 QA——在这里修复漂移成本最低。
    • 注意手部、衣物细节、比例——在重新生成时在提示中明确命名它们。
    • 几何形状必须可步行(镜头 6 的教训,花费 2 次重新生成):使用结束帧固定时,起始帧必须允许动作通过向前步行到达结束状态——如果结束帧的角色比起始帧的离镜头更近,模型会生成一个克隆角色而非移动。从起始角色比结束状态更/近开始,以便向前运动使其缩小到结束状态。
  4. 片段 — 说明总派生成本,然后并行运行 python tools/gen_clip.py 每个镜头(--set image_url=<fal storage url> --set 'duration="N"' --set resolution=1080p --set generate_audio=false,最后一个镜头添加 --set end_image_url=<frame0 url>)。通过 bakeoff_clip.upload_ref 一次性上传参考;将 URL 保存在 shots/upload-urls.json 中。 以上 fal 形式是此签出的默认配置(CLIP_PROVIDER=fal,.env 中的 FAL_VIDEO_MODEL)。 使用 kie.ai 代替(--provider kie): 字段名称遵循 kie 模型,而非 fal。对于 bytedance/seedance-2:--aspect none --set first_frame_url=@ai-shorts/<name>/shots/NN-slug.png --set duration=N --set resolution=1080p --set generate_audio=false,最终镜头 --set last_frame_url=@<frame0.png>。@path 上传本地文件(kie 保留 24 小时,因此 upload-urls.json 的重复使用仅在一天内有效)。成本:kie.ai/pricing,而非 fal 表;运行时会打印使用的积分。bakeoff_clip.py 仍仅限 fal。 为每个片段编写提示:精确的角色短语 + “整个镜头中场景内恰好一个角色”(克隆是头号失败原因)+ 镜头移动 + “无变形” + 风格行。
  5. 片段 QA,逐帧进行 — 每个片段起始/中间/结束帧条 + 最终片段最后一帧与循环目标的并排对比。重新生成失败片段(说明重新生成成本);5 秒 1080p 重新生成约 $0.29——相比交付一个克隆的代价要低。
  6. 合成 — 单时间轴上 OffthreadVideo 序列,约 8 帧交叉淡入淡出重叠(片段比其窗口长约 1 秒——这部分是余量),根目录的 Captions + ProgressBar,尾部 LoopSettle 溶解。将最终片段复制到 media/projects/<name>/。运行 npm run gen,在边界和关键帧处使用 frames.mjs 读取每个 PNG,然后 render-all --scale=1 并混入 voice.wav。
  7. 音效 — 遵循 /suggest-sfx 流程。空隙旁白校准(blue-man 第 1 集): 旁白空隙中的提示音效不进行掩蔽和闪避——它们需要比密集旁白表低约 7-8 dB(空隙嗖嗖声 -9..-13,而非 -3..-5)。使用 volumedetect RMS 对照语音均值参考进行验证;主层音量可能达到语音级别。试听混音等待用户耳朵(硬门限)。
  8. 保存回传 — 记录 used_in,beats.json 真实时间(gen_voice 写入),提交侧车文件,成本账目记录在最终报告中。

“完成”的定义 =

每个片段的每一帧中角色一致(已逐帧 QA)· 循环已验证(最后一帧与帧 0 并排对比)· 字幕在真实单词时间上 · 每次花费前已说明成本且总成本已汇总 · 音效试音已渲染,等待用户耳朵 · 无吸引互动片尾。 · tools/check_text.py 对口语和屏幕上的文本检查通过 · 使用 tools/export_phone.py 制作手机副本 · LESSONS.md 中有日期记录(如果经验教训改变了工作方式,技能以通用术语更新)。

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

gbax316/shorts-director

Directs a faceless vertical short from idea to finished, mastered file, and gets better with every run. Picks a format, writes the episode in a writers' room (three premises judged as the buyer), voices it, gates on an animatic, then decides beat by beat how each moment is made: drawn in code in Remotion, a cut-out from a generated still, a generated clip, or one of the engine tracks. Modes: series, writers-room, produce, sound, finish, bakeoff, effects (/effects), improve (the learning loop after every short). Formats so far: character skit with dialogue and synced mouths, photoreal mini documentary with sourced figures. Triggers on "make a short", "next episode", "make a video about X", "faceless video", "reel for this offer". Do NOT trigger for editing an existing video file, for a pure code-drawn explainer with no writers' room (make-short), or for collage (make-vox).

gbax316/vidtsx-2d-generator

Generate production-ready 2D TSX video files for VidTSX (Remotion-based) from a shot, scene, or video description. Use whenever the user wants to create or generate a VidTSX video, a 2D TSX shot or scene, an animated clip, title card, or rendered motion graphic — including when they describe a visual animation they want built, or say "make a shot", "build this scene", "generate the TSX", or "turn this into a video". Covers the mandatory file structure and composition config, dimension presets (horizontal/vertical/square), six style presets (minimalist, memphis, neo-brutalism, glassmorphism, neon, corporate), and the hard rules that keep renders from crashing, covering frame-based animation only (no useState/useEffect/setTimeout), strictly monotonic interpolate ranges, Easing.bezier not wrapper syntax, and the chroma-js and @remotion/paths import gotchas. Not for 3D/three.js compositions, general React work, or editing video files.

相关技能