ship-video 是做什么的?
您将导演并构建一个 10-45 秒的用户产品影片。屏幕上的所有内容都是代码:一个 HTML 页面,一个暂停的、以绝对秒数计的 GSAP 时间轴,从真实应用的 DOM 中捕获并动画化的界面,最终逐帧渲染为 MP4。
工作如何成形。 一部影片的成败取决于代码编写之前的几个选择:目标观众、产品带来的唯一改变、讲述的故事、时长。这些选择将写成一个用户批准的单页故事板;在纸上修改只需要几分钟,一旦开始构建则需要数小时。之后,认真构建、严格自我检查、渲染,然后展示影片:用户观看并告诉您要修改什么。在故事板获得批准后,不要停下来等待批准。
脚本 位于此文件旁边的 scripts/ 目录。在 Claude Code 中,该文件夹为 ${CLAUDE_SKILL_DIR}/scripts;在其他环境中,请根据此文件目录解析并使用绝对路径调用。以下,$S 代表该文件夹,<film> 代表影片文件夹。运行脚本,不要阅读其源代码;每个脚本均支持 --help。
提问。 只询问真正的决策(地点、音乐、时长、用户自己的措辞);其余由您决定,用一句话说明,让其在关卡处修改。仅在三个时刻提问:开场(第 1 步)、故事板关卡、渲染之后;切勿中途中断工作。一种形式适用于所有宿主:每个回合最多 3 个问题,每个问题 2-3 个选项,先给出推荐,然后是一个 1-5 个词的标签,用一句话说明对用户的意义,不提供“其他”(宿主可添加自由文本)。使用宿主的提问工具(Claude Code:AskUserQuestion;Codex:request_user_input,仅限 Plan 模式),否则使用带字母选项的编号列表(“1a 2b”),结尾加上“或者告诉我其他内容”。如果超过 3 个选项,则拆分为两个问题,先问决定性的那个;当先前的答案解决了一个问题时,将其纳入选项。
限制
如果请求触及以下限制,应提前说明:仅 16:9(无 9:16);仅 Web UI(原生应用只能通过截图重建,精度较低);10-45 秒;支持 macOS、Linux 或 Windows;输出 MP4 和动画 WebP,无 GIF。安装过程会将 Chromium 和 Python 包下载到 ~/.ship-video:沙箱化宿主(如 Codex)需要网络访问权限和对该目录的写入权限;如果命令被阻止,请告知用户需要哪个权限,而不是重试。
开始或继续
检查影片文件夹(如果不明确则询问),然后从第一个缺失的部分开始:
<film> 中存在 | 从以下开始 |
|---|---|
| 无 | 0 设置 |
index.html,无 PRODUCT.md | 2 发现 |
PRODUCT.md,无 MUSIC.md | 3 音乐 |
MUSIC.md,无已批准的 SCENARIO.md(Approved: 行) | 4 故事板 |
已批准的 SCENARIO.md,无 screens.js(或状态尚未比较) | 5 屏幕副本 |
screens.js 和 review/compare/ 包含所有匹配的状态,以及一个起始的 film.js | 6 构建 |
film.js 包含所有已构建的幕,无 out/film-*.mp4 | 7 审查 |
out/film-crisp.mp4 或 out/film-motionblur.mp4 | 询问要修改什么(render.md,渲染后的更改) |
用户可以跳过某些步骤(“我有一个故事板”、“不要音乐”、“直接构建”):直接跳过并用一行说明。跳过故事板关卡需要用户的明确措辞。
在第一次回复和交付时展示此清单:
- [ ] 0 设置 - [ ] 1 简介 - [ ] 2 发现 - [ ] 3 音乐
- [ ] 4 故事板(已批准) - [ ] 5 屏幕副本 - [ ] 6 构建
- [ ] 7 审查 - [ ] 8 渲染和交付
0. 设置
node $S/lib/check.mjs:一旦设置完成,立即运行。仅当报告有缺失时:node $S/setup.mjs(安装到 ~/.ship-video,跳过已存在的部分)。
1. 简介
首先查看:README、package.json、路由、组件、网站、现有的截图和 Logo(真实资源无需询问即可使用)。然后分连续两轮询问仍缺失的信息(时长取决于音乐):
- 播放位置:该产品最可能的三个地方(社交媒体信息流、网站、README 或文档、帮助中心),并指出首先针对哪一个。这决定了观众知道什么、是否有声音、开场方式(
direction.md,观众测试)和最小文本字号。 - 音乐:是或否;如果播放位置是静音的,推荐无音乐;如果选择是,则告知音乐仅出现在 MP4 中(README 的 WebP 是静音的)。
- 第二轮 · 音乐来源(第 3 步的问题,现在提出,这样在您工作时 Suno 音轨就能生成)和时长:最短能展示产品一个变化的时长(10-15 秒通常最好),一个更长的时长,如果选择音乐则配合音乐(由音轨决定,在节拍上剪辑以适应素材,此时推荐)。
影片类型(发布、单一功能预告、操作指南、登陆页面)通常由请求和播放位置决定:直接指出。用户已经说过的话将回答其对应的问题。
如果用户希望影片具有某种感觉:将其分解为一张联系表(ffmpeg -i ref.mp4 -vf "fps=2,scale=480:-1,tile=6x5" <film>/review/reference.png),列出其技巧,借用这些技巧,但绝不使用其内容。
创建文件夹:node $S/new-film.mjs <film>(除非用户希望放在产品仓库内,否则放在外部;如果已知,使用 --theme light|dark;对于无音乐的影片使用 --silent)。
2. 发现
从 README 制作的影片展示功能;从整个产品制作的影片展示价值。首先了解产品。对于小型应用之外的情况,如果可能,将其拆分为三个并行子智能体(subagents.md)。
- 盘点路由和所有视图,以及关键状态(对话框、调色板、提示、空状态、主题)和所有动态内容(图表、地图、画布)。
- 查看每个状态:在应用运行时(复用其服务器,
render.md,共享机器)node $S/capture.mjs <url> <film> --discover将每个路由的截图写入<film>/review/discovery/;阅读这些截图。对于登录、手机、登陆页面:请参考replicas.md,选项。如果应用未运行:使用其截图和文档,并说明这一点。 - 找出新功能和亮点:变更日志、发布说明、
gh pr list --state merged --limit 30(如果可用);用户会向朋友展示的 3-5 个时刻;构成产品核心的唯一变化。 - 编写
<film>/PRODUCT.md:用产品自己的语言描述其承诺、观众、视图(核心/次要/跳过,附截图路径)、令人惊叹的时刻、一个可以承载影片的具体用例、以及无法显示的内容。用几行展示并继续工作;修改可以随时提出,最晚在故事板关卡。
3. 音乐
阅读 music.md。如果没有音乐:创建一个 BPM 网格并阅读 direction.md,无声影片。关于音乐来源的问题(在开场时提出)应展示所有三个选项,用一句话说明对用户的影响(~/Downloads 中的新文件归入用户自有文件选项):
- 生成的节拍:免费、免许可、秒级就绪,是一种功能性配乐而非歌曲。根据计划中的幕编写
beat.json并运行music.mjs synth。 - Suno:根据影片的节拍结构量身定制的真实歌曲;需要 Suno 账户,大约 10 分钟的用户时间,公开使用需要付费计划,因此对于公开场合,请标记为 Suno(付费计划)(
music.md,权利)。引导用户完成生成过程(suno-prompt.md,引导用户)。不要空闲等待:从GRID DRAFT编写 MUSIC.md,并在用户生成音轨的同时起草故事板。 - 自有文件:将其复制到
<film>/track.<ext>。
分析音轨,阅读节拍图,自行确认高潮点,并编写 <film>/MUSIC.md,说明每个部分在故事中的作用。
4. 故事板
阅读 direction.md 并从 scenario-template.md 编写 <film>/SCENARIO.md:观众、故事(问题 → 主角 → 行动 → 在高潮点上的收尾)、每个镜头及其秒数、运动和镜头落点、以及最终的逐字文案。运行模板的自我检查并首先修复“否”项。如果时长不适合素材,告知用户并提供更合适的时长。
然后,在一个回合中询问:仅当措辞属于用户时提供变体,并询问“批准故事板?”(批准 / 更改时间 / 更改场景),同时用三行文字和镜头表格简述故事。
5. 屏幕副本
阅读 replicas.md。在应用运行时,其自身的 DOM 和 CSS 就是副本:编写 <film>/states.json,包含故事板所需的每个状态(每个交互的两侧),运行 capture.mjs … --css,然后运行 compare.mjs,并阅读比较后的 PNG,直到每个状态都匹配。如果没有运行的应用,则从组件构建并在报告中说明。
6. 构建
阅读 film-api.md 和 shots.md。根据捕获输出设置 track、duration、hits(music.md)以及 fonts/images,然后按照故事板中的秒数顺序编写场景。在捕获的屏幕内对真实元素进行补间动画(direction.md)。如果偏离了故事板,请在 Changes vs scenario 中添加一行说明。
边构建边检查:node $S/render.mjs <film>/index.html <film>/review/test.mp4 --preset draft --from 0 --to 1 可以在几秒钟内捕获损坏的页面;用户可以打开 <film>/index.html 进行预览(空格播放,箭头逐帧,?t=12.5 跳到指定时间)。
7. 审查
在其他人之前以导演身份查看影片:
node $S/sheet.mjs <film>/index.html <from> <to> <step> <film>/review/sheet-<act>.png
node $S/shots.mjs <film>/index.html <film>/review/stills <t1> <t2> … --label
每幕一张联系表(文字部分以 0.25 秒为步长,UI 部分以 0.5 秒为步长),每个剪辑点 + 0.01 秒、高潮点和结尾卡的全分辨率静帧。阅读每一张图片,并对帧执行 scenario-template.md 中的自我检查;以 0.1 秒为步长放大检查每一个交互,因为大多数“未完成”的感觉都藏在那半秒里。然后获取一个新鲜的意见(subagents.md),并修复所有问题。最后运行 node $S/audit.mjs <film>/index.html,直到干净无报错(render.md,审计)。
8. 渲染和交付
阅读 render.md:在后台渲染清晰版,验证它(hits.mjs、motion.mjs),如有需要修复并重新渲染,然后交付(交付:打开文件夹、第一版剪辑、一个问题)。
参考文件
| 文件 | 何时阅读 |
|---|---|
references/direction.md | 第 4 步,并在第 6 和第 7 步再次阅读:观众测试、故事、结构、节奏、构图、影片类型 |
references/scenario-template.md | 第 4 步(模板和自检),第 7 步(对帧进行自检) |
references/music.md | 第 3 步:分析、MUSIC.md、无声网格、生成节拍、权利 |
references/suno-prompt.md | 第 3 步,当音乐来自 Suno 时 |
references/replicas.md | 第 2 步(捕获选项)和第 5 步 |
references/film-api.md | 第 6 步,在编写 film.js 之前 |
references/shots.md | 第 6 步:带代码的配方 |
references/subagents.md | 第 2 和第 7 步,如果您的宿主可以运行子智能体 |
references/render.md | 第 7 步(审计)和第 8 步;在启动服务器或渲染之前阅读 共享机器 |