配方
配方即一个已发布的启动片,经过研究和记录,以便代理能够为另一款产品重新构建其工艺。
它位于 <studio>/src/recipes/<id>/:
| 文件 | 始终 | 提供内容 |
|---|---|---|
recipe.md | 是 | 何时使用、节拍表(时间、帧数、画面、镜头、运动、过渡、音效)、与工艺关联的技巧、需要调整的部分、注意事项、缺失的组件 |
recipe.json | 是 | 相同数据(遵循模式 schemas/recipe.schema.json):structure[], techniques, audio, inputs, components, source |
Recipe.tsx + index.tsx | 仅 status: "built" 时 | 就绪代码:一个以 brand + content 参数化的组件,并附带演示品牌注册 |
大多数配方仅为文本(status: "studied"),这已足够用来构建:从节拍表编写场景,配合工作室的预设和组件。配方绝不包含源影片、其帧画面或文案;源链接用于让用户自行查看参考。
命令从 launch-video/(用户)或 studio/(launchfilm 仓库)运行。recipes/ 和 schemas/ 位于工作区根目录(用户项目中的 launch-video/,launchfilm 仓库中的仓库根目录)。
1. 明确需求(来自 BRIEF.md / STORYBOARD.md)
在搜索之前记录:预设(画幅)、目标时长、模式(产品片 / 发布片 / 混合)、主题(来自 brand.json 的深色/浅色)、是否需要旁白、需要覆盖的节拍(hook, feature, logo…)、用户实际拥有的输入素材(Logo、截图、录屏、可重建的 UI、统计数据、URL)。
2. 搜索
浏览 recipes/CATALOG.md(每个配方一行,按系列分组:格式、主要技巧、输入、来源、文本/代码),
或执行搜索:
npx launchfilm ref search "statement vertical dark" # 自由文本搜索标题、摘要、标签、技巧
npx launchfilm ref search "launch aspect:9:16 max:30 theme:dark" # 筛选:family: aspect: tech: theme: max: min: status:
或直接筛选 recipes/index.json(字段说明:references/index-format.md):
node -e '
const idx=JSON.parse(require("fs").readFileSync("recipes/index.json","utf8")).recipes;
const want={aspect:"9:16",dur:30,techniques:["statement-sequence","end-card"],theme:"dark"};
for(const r of idx){const t=r.techniques.filter(x=>want.techniques.includes(x)).length;
if(r.format.aspect===want.aspect||t>0) console.log(r.id,r.format.aspect,r.format.duration_s+"s",r.theme,r.vo?"vo":"-",t,r.code?"code":"text");}'
没有索引?则全部搜索 src/recipes/*/recipe.json 并读取它们。
3. 评分并选取 1–3 个
| 评分标准 | 分数 |
|---|---|
format.aspect 等于主要预设的画幅比例 | +3(可重组但增加工作量) |
format.duration_s 在目标时长的 ±30% 范围内(或配方覆盖所需的节拍) | +2 |
| 每个与故事板需求重叠的技巧 | 每个 +1(最多 +4) |
所需的所有 inputs 字段用户均已拥有 | +2;任何无法提供的缺失输入 |
theme 与 brand.json 的 theme 匹配 | +1 |
vo 与计划匹配 | +1 |
code: true(就绪的 Recipe.tsx)且用户在赶时间 | +1;status: "reviewed" |
render_cost 过高而用户在使用笔记本电脑或赶时间 | −1 |
文本与代码是速度加分项,而非质量筛选:一个符合需求的文本配方胜过编码但不符合需求的配方。 对于完整影片选择最高分的一个,或针对不同节拍选取至多三个(A 开头、B 功能、C 结尾)。
4. 展示挑选结果
对每个挑选结果,向用户展示:
- 标题(
id)以及text或code; - 一行说明它为何适合需求(画幅、时长、覆盖的节拍、用户的输入);
- 用 3–6 简短行概括的节拍表(
0–3.1 s hook: name blurs in word by word…),源自 recipe.md; - 源链接(
source.url)供他们自行观看原片。没有托管预览。
在交互式会话中让用户选择。如果用户说“你决定”,则选取最高分并在一行中说明。
5. 读取配方
完整阅读所选 recipe.md:节拍表、以帧数和命名弹簧表示的运动、过渡、每个事件上的音效、“需要调整的部分”、“注意事项”、“缺失的组件”。读取 recipe.json 的 structure[]、audio、inputs、components。这些数值是您要复用的工艺;画面和文案将来自用户。
6. 搭建
npx launchfilm new <slug> --recipe <id> --preset x-16x9 [--title "Product"] [--dry-run]
- 含代码的配方:
films/<slug>/Film.tsx获得一个recipe场景,该场景使用其默认值渲染配方的组件;您更改其content属性(recipe.json中的params)并传入品牌。 - 文本配方:
film.json为节拍表的每一行获得一个镜头(配方的时长、过渡和音效),Film.tsx为每个镜头获得一个TodoScene,其中包含该行的画面、镜头、运动和音效作为注释。CLI 打印待办列表。只要还有一个 TodoScene 未处理,npx launchfilm qa就会失败(B1)。 - 两者都将
recipe.md复制到films/<slug>/RECIPE.md并预填STORYBOARD.md为配方的各行内容。 - 组合配方:从占用最多运行时长的配方搭建,然后将其他配方的行添加为镜头(若它们有代码则为
Recipe组件作为场景,否则为 TODO 场景)。
7. 构建(详情:references/remix.md)
- 首先根据用户时长和节拍网格重新调整骨架(remix.md §3):保持节拍顺序和比例,将每个边界对齐至强拍或旁白短语。更新
film.json镜头和 STORYBOARD 行;在场景构建前用户需批准故事板(关卡 3)。 - 品牌:通过
useBrand()将 brand.json 应用于每个场景(代码配方:通过brand属性)。切勿编辑配方文件夹。 - 内容:用户的产品名称、台词、统计数据、UI。绝不能使用源影片的文案或演示品牌的文本。
- 文本配方场景:用从
src/presets和src/components构建的场景替换每个TodoScene(先阅读API.md;scene-build技能拥有规则)。使用配方所列的组件;保持行的命名弹簧、帧数、交错和过渡 ID 不变;运动时长不随影片长度缩放。配方“缺失的组件”清单下的组件,需按其规格在films/<slug>/scenes/中构建。 - 音效:
audio.sfx中的每个事件和每行的sfx都保持其在新帧上的声音(胶水规则,craft/02)。 - 任何渲染前每个镜头都要有静态帧(scene-build 步骤 4),然后执行
film-qa。
规则
- 配方是起点,而非输出结果:影片承载用户的故事(先批准 STORYBOARD)。
- 源影片的任何内容不得进入影片:无源文案、无源品牌、无源素材。源链接供用户观看,并保留在
recipe.json和您的消息中,绝不进入影片。 - 缺失的组件 → 在
films/<slug>/scenes/内构建,不在配方文件夹或共享预设中。 - 在 STORYBOARD.md 中记录使用了哪些配方、哪些行、缩放因子和参数,以便可重复运行。