recipes
食譜是經過研究並記錄下來的已發佈 LaunchFilm,讓代理可以為其他產品重建其手法。
它位於 <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……)、使用者實際擁有的輸入素材(標誌、螢幕截圖、螢幕錄影、可重建的 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");}'
沒有索引?使用 Glob 模式 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 |
文字 vs 程式碼是速度獎勵,不是品質過濾器:符合簡報需求的文字食譜勝過不符合的程式碼食譜。 選取最高分的一個用於整部影片,或選取最多三個用於不同的節拍(鉤子來自 A、功能來自 B、結尾卡來自 C)。
4. 顯示選擇結果
對於每個選擇,向使用者顯示:
- 標題(
id)以及是text還是code; - 一行說明為什麼它符合使用者的簡報(長寬比、長度、它涵蓋的節拍、使用者擁有的輸入素材);
- 從 recipe.md 摘要出的 3 到 6 行短分鏡表(
0–3.1 秒 鉤子:名稱逐字模糊淡入……); - 來源連結(
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 會列印 TODO 清單。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。絕對不要使用原始影片的文案或示範品牌的文字。
- 文字食譜場景:將每個
TodoScene替換為使用src/presets和src/components建立的場景(先閱讀API.md;scene-build技能擁有這些規則的所有權)。使用 recipe.json 列出的元件;精確保留該行命名的彈簧、幀數、交錯和轉場 ID;動態持續時間不會隨影片長度縮放。食譜在「缺少的元件」下列出的元件,會根據其規格在films/<slug>/scenes/中建立。 - 音效:
audio.sfx中的每個事件和每一行的sfx都會在新幀數處保留其聲音(黏合規則,craft/02)。 - 在任何渲染之前,為每個鏡頭先產生靜止畫面(scene-build 步驟 4),然後執行
film-qa。
規則
- 食譜是起點,不是最終輸出:影片承載的是使用者的故事(STORYBOARD 必須先獲得批准)。
- 原始影片的任何內容都不會進入最終影片:沒有原始文案、沒有原始品牌、沒有原始素材。來源連結是給使用者觀看的,它會保留在
recipe.json和你的訊息中,絕不會進入影片。 - 缺少的元件 → 在
films/<slug>/scenes/中建立,而不是在食譜資料夾或共享預設元件中。 - 在 STORYBOARD.md 中記錄使用了哪些食譜、哪些行數、縮放因子和參數,以便可以重現。