Communitygithub.com

手工舞台短片

把品牌自己的战役静帧剪成 15–20 秒的定格舞台短片:纸偶、撕纸字幕,最后一卡落在产品和字标上。

手工舞台短片 是什么?

把真实照片扩成 9:16,只做几下发僵的动作,道具从照片里抠出来,再在本地渲染 12 步一拍的运动、八音盒圆舞曲和结尾卡。脸、产品和印刷标签保持原样。七张静帧的模型费用大约两三美元,成片在本机免费剪完。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/DarthManly/handmade-stage-film-skill/tree/HEAD

在你喜欢的 AI 中提问

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

文档

手工分镜头影片

万圣节夜晚,没什么可看:一个黑色波波头的女孩坐在一个手绘纸板沙发上,手拿粉色饮料,点击纸板遥控器。纸板电视打开,屏幕出现雪花,一个小幽灵在屏幕上跳舞,然后从屏幕上剥离并飘走。它盘旋在她的杯子旁("它想喝一口。"),降落在格子桌上,一把巨大的叉子戳着盘中的手绘浆果("栀子花。浆果。酸奶。"),喝了一口后,她坐在一顶巨大的女巫帽上,星星在她周围闪烁("……满满的魔法。")。杯子特写,画着涂鸦的"神奇漂亮水"和箭头,最后一张卡片上有品牌标志、杯子、幽灵、"万圣节限量版"及购买信息。每一帧都来自品牌自己的七张活动照片。

它由四个部分组成:

  • scripts/generate.mjs 将静帧转化为素材:9:16关键帧(Nano Banana 2绘制额外场景,原始像素覆盖在上面),Kling剪辑片段,抠出的道具,重新放置的标签和品牌标志。
  • scripts/reel.mjs 将剪辑片段按影片时间线合并为一个文件。
  • scripts/sfx.mjs 合成音效:一首原创音乐盒华尔兹和每个事件对应的音效。
  • scripts/render.mjs 将全部内容作为舞台剧播放:12帧/秒的步进运动、手持抖动、动态颗粒、纸偶、撕纸字幕、带箭头的标签、开关电视屏幕以及最后一张卡片。它使用headless Chrome和FFmpeg在本地渲染。

设置(每台机器一次)

在该技能文件夹内运行:

npm install

这将安装puppeteer-core和ffmpeg-static。必须安装Google Chrome,或设置CHROME_PATH指向一个Chrome/Chromium可执行文件(npx @puppeteer/browsers install chrome-headless-shell@stable会打印一个路径)。

素材需要Nano Banana 2和Kling 2.5 Turbo的API密钥;脚本通过模型API网关调用它们,密钥在这个页面创建(https://fal.ai/dashboard/keys)。用户在自己的终端中设置`FAL_KEY`(例如在shell配置文件中)。永远不要要求他们将密钥粘贴到聊天中,也不要打印它。

费用

模型使用费用,计入你自己的API密钥:每张扩展到9:16的静帧(以及每次edit)0.08美元,每段5秒剪辑片段0.35美元,每个抠图不到0.01美分(2026年10月价格)。7张静帧、5个剪辑片段的短片大约2.30美元。合成文件、纸偶、字幕、音效和最终MP4文件在本地免费处理。在生成前告知用户费用。

成功要点

  • 他们自己的照片,关键部分原封不动。 扩展和每个剪辑片段都从品牌的真实静帧开始;extend将原始像素覆盖回AI生成的版本,relabel将清晰的标签覆盖回任何剪辑片段模糊了标签的帧。
  • 一个故事,而不是幻灯片。 在几张照片之间规划一个小情节,有一个东西贯穿其中(这里是一个从电视里逃出来的幽灵纸偶)。字幕是简短的情节节拍,而不是口号。
  • 刻意笨拙。 所有动作都以1/12秒的步进运动,并带有轻微抖动,纸偶在关键帧上摇晃,字幕分三步弹出,箭头分三笔画完。不要平滑它。
  • 一半产品,一半品牌。 产品出现在大多数镜头中,并有一个带标签的特写;最后一张卡片是品牌标志、产品、名称和购买方式。

工作流程

  1. 收集 来自同一拍摄的4-8张静帧(3:4、4:5或9:16),产品名称,一行描述(口味、材质),一个注释("万圣节限量版")和行动号召。询问静帧底部是否印有品牌标志或徽章(它会被从画面中清除,并作为最后一张卡片的背景素材)。
  2. 剧本(生成前展示):镜头顺序、情节、每个剪辑片段中的动作(一个或两个小动作,产品保持静止)、哪些道具需要抠图成为纸偶及其动作、字幕和标签,以及费用。保持15-20秒。
  3. 关键帧:对于每个不是9:16的静帧,运行 node scripts/generate.mjs extend --in still.jpg --out keys/<shot>.png --cover <rows>(--cover = 原始照片底部印刷标志条带的高度,以像素为单位,如果有的话)。以全尺寸查看每个关键帧:如果模型在新扩展的区域留下了镜像或重复的物体,用同一张照片中的纯色纹理覆盖它。
  4. 试拍:一个剪辑片段,选择有情节钩子的镜头:node scripts/generate.mjs clip --start keys/<shot>.png --prompt "…" --out clips/<shot>.mp4。提示词只描述动作("她用一个手指按下遥控器上的一个按钮;杯子保持直立且静止");一个固定的后缀保持镜头锁定,场景、面部和产品不变。展示它,然后继续其余部分。
  5. 剪辑片段:其他需要动作的镜头。逐帧观看每个片段:记录动作落点(以便放置音效和纸偶),以及产品上的小文字模糊的地方。使用 relabel --clip … --key keys/<shot>.png --box x,y,w,h(标签在关键帧中的矩形框)修复标签,或者只使用产品移动前的帧。并非每个镜头都需要剪辑片段:产品特写静帧配合缓慢推进(still、box、boxTo)通常效果更好。
  6. 道具:对于每个纸偶(角色、星星、花朵、浆果、手中的产品),运行 cutout --in keys/<shot>.png --box x,y,w,h --out props/<name>.png;对于去除某些元素的盘子(如没有幽灵的电视屏幕),运行 edit。品牌标志:wordmark --in still.jpg --box x,y,w,h --out props/wordmark.png。最后一张卡片的背景是从一个关键帧中裁剪出的手绘墙区域。
  7. 构建 effect.json 参考 examples/example.json(参见“镜头”和“最后卡片”部分),然后运行 node scripts/reel.mjs effect.json --out reel.mp4 并设置 "reel": "reel.mp4"。
  8. 音效:运行 node scripts/sfx.mjs effect.json --out stage.m4a,然后设置 "music": "stage.m4a"。在时间线有任何更改后重新运行。--no-bed --music track.mp3 将华尔兹替换为用户拥有使用许可的音轨。
  9. 验证:运行 node scripts/validate.mjs effect.json — 修复所有错误并向用户解释警告。
  10. 草稿:运行 node scripts/render.mjs effect.json --quality draft --width 540 --out draft.mp4,并检查每个镜头的一帧:确保没有字幕、标签或纸偶遮挡面部或产品,所有内容避开右侧14%的区域(平台按钮所在位置)。
  11. 最终版:运行 node scripts/render.mjs effect.json --out film.mp4 --poster poster.png。对于小红书,裁剪出3:4版本:ffmpeg -i film.mp4 -vf crop=720:960:0:160 -c:a copy film-3x4.mp4(在默认720宽度下;确保无重要内容位于顶部或底部的160像素内)。

镜头

所有位置单位为1080×1920像素帧。每个镜头是以下类型之一:

  • 剪辑镜头:clip(reel.mjs使用的文件),from和to(在剪辑中的秒数),speed(0.5=半速,与12步播放一起使用短但好的动作片段的每一帧),hold(第一帧在移动前保持的秒数)。
  • 静帧镜头:still(一张图片),len,box和boxTo([x, y, width] 9:16窗口在图片像素中的位置;视图从一个窗口移动到另一个窗口)。

每个镜头可以包含:

  • captions:{ "text", "at", "out", "x", "y", "rot", "size" } — 撕纸碎片上的手写字幕;\n换行。
  • tags:{ "text", "at", "x", "y", "to": [x, y], "ink": "dark" | "light", "rot", "size" } — 带箭头的标签,箭头自动绘制指向to。
  • puppets:{ "image", "path": [[t, x, y, width, rotation], …], "sound", "exit", "flip", "wobble" } — 一个抠图纸偶,在其关键帧之间移动(t为镜头内的秒数,x、y为其中心点)。一个宽度为0的关键帧紧接着一个全宽度关键帧表示弹入。它保持其最后一个关键帧,除非设置"exit": true。sound在第一个关键帧时播放。
  • screen:{ "rect": [x, y, w, h], "off", "static", "plate", "plateAt" } — 电视或手机屏幕,在off之前为黑色,static之前为雪花,从plateAt开始显示plate(同一关键帧但屏幕内容被清空),因此纸偶可以从里面爬出来。
  • sounds:[[t, "kind"], …] — click、tvon、static、ghost、boing、tap、pop、whoosh、land、stab、sip、sparkle、chime、paper、scribble、cut。剪辑、字幕、标签、屏幕和带有sound设置的纸偶会自动获得对应的音效。

最后卡片

end:len、bg(一个9:16的手绘墙)、wordmark(wordmarkY、wordmarkWidth)、name(nameY、nameSize)、line(lineY)、note在碎纸片上(noteX、noteY)、cta在药丸形按钮上(ctaY),以及puppets(与镜头类似,例如产品从边缘滑入手中的纸偶、角色、星星)。每个都有对应的…At时间。

字段

字段必需说明
reel是视频文件路径,相对于JSON文件——由scripts/reel.mjs将所有剪辑镜头合并成一个无声的9:16合成文件(reel.mp4)
shots是2-10个条目列表:clip、from、to、speed、hold、still、len —— 按顺序的影片镜头:剪辑镜头(你的一张静帧的AI剪辑片段)和静帧镜头(带有缓慢移动的静帧);见SKILL.md的“镜头”部分
end.bg否图片路径,相对于JSON文件 —— 最后卡片的背景:来自你照片的手绘墙或背景,9:16
end.wordmark否图片路径,相对于JSON文件 —— 透明背景上的品牌标志(由scripts/generate.mjs wordmark生成)
end.name否文本,少于4个单词 —— 产品名称,在最后卡片上手写字体
end.line否文本,少于6个单词 —— 名称下方的一行短文字,例如口味
end.note否文本,少于4个单词 —— 在撕纸碎片上,例如“万圣节限量版”
end.cta否文本,少于12个单词
music否音频文件路径,相对于JSON文件 —— 来自scripts/sfx.mjs的原声音乐(stage.m4a)
palette否颜色值为#RRGGBB;键值:ink(字幕和深色标签)、paper(纸片和浅色标签)和accent(CTA按钮)

提示

  • 写好剪辑提示词:一个或两个小动作,面无表情,“杯子保持直立且静止,标签面向镜头”。大动作会模糊面部和标签。
  • Kling自己控制时机:观察动作落点,并将点击、切换和纸偶放在那一帧,而不是整数值。
  • 给故事一个贯穿物:从一张照片中抠出的纸偶出现在后续镜头中,将七张静帧连成一个影片。
  • 纸偶从照片本身中抠出,而不是新创作的艺术:相同的颜料、纸张和光线使它们融为一体。
  • 字幕保持三到四个单词;图片能讲述大部分内容。

输出

H.264 MP4,1080×1920,30fps(画面以每秒12步运动),15-20秒含音效,外加一个封面帧(PNG)。

相关技能