make-video 是做什麼的?
從一個提示詞製作一部有聲影片。每一幀都是時間 t 的純函數,在畫布 (@napi-rs/canvas) 上繪製並用 ffmpeg 編碼。語音由本地 Kokoro 生成。配樂用 Python 合成。每張圖片的時間點都對應到語音中提及該圖片的單詞。
工作流程是固定的: 提示詞 → 故事板(真實語音、真實配樂、每個場景一張真實幀)→ 使用者反覆調整故事板 → 完整渲染。在使用者核准故事板之前,請勿渲染完整影片。在每一步都抽樣真實幀進行檢查,在展示前修正看到的問題。
以下 <skill> 指的是存放此 SKILL.md 的資料夾。
需求
node 20+、ffmpeg、uv(用於執行 Python 腳本並安裝相依套件)以及 python3。./make.sh setup 會檢查這些項目。Kokoro 模型(約 115 MB)會在首次執行語音時下載一次,存放至 ~/.cache/make-video/models。此專案不附帶字型:請參閱 references/fonts.md。
1. 理解影片(從提示詞出發)
在編寫任何程式碼之前,先閱讀影片的主題:PR、儲存庫、文件、應用程式、公告。找出影片可以展示的真實內容:真實的畫面、真實的程式碼、真實的輸出。決定這些事項,並僅針對你無法自行查明的部分詢問使用者:
- 類型與長度。 功能介紹或公告:30–75 秒,6–10 個場景,真實的應用程式畫面。解說:2–6 分鐘,章節式,包含標題卡、圖表和程式碼。經驗法則:每秒約 2.5 個語音單詞。
- 觀眾與最終目標 他們必須知道或執行的唯一一件事。
- 視覺風格。 使用
theme.mjs中的ink調色盤(接近黑色、紅色強調色)或navy(深藍色、天空色與琥珀色),或使用產品本身的顏色與字型。 - 音樂風格。
pop(明亮、輕快)或chip(安靜的晶片音樂),或none。
2. 建立專案
<skill>/scripts/new-project.sh ~/Developer/<topic>-video <topic>-video
這會複製 <skill>/template(一個可運作的 30 秒範例影片)並執行 npm install。取得字型(references/fonts.md)。專案是自成一體的。編輯以下檔案:
| 檔案 | 說明 |
|---|---|
video.json | 劇本:場景、語音台詞、提示點、時間、音樂、故事板的簡報 |
scenes/*.mjs | 每個場景 ID 對應一個繪製函數 |
theme.mjs | 調色盤、字型、背景 |
music.py | 配樂(和弦、動機、樂器),當預設不符合需求時使用 |
shots/plan.mjs | 要截取的實際應用程式畫面,當影片需要展示應用程式時使用 |
不要編輯 timeline.json。timeline.py 會生成它。
3. 編寫劇本 (video.json)
先閱讀 references/script.md。簡而言之:每個場景一個想法,使用簡短的陳述句,以一個鉤子開場,並以接下來要做什麼結尾。一行文字可以是一個字串,或者當字幕與口語形式不同時使用 {"text", "say"}(例如 "video.json" 口語唸成 "video dot jason")。提示點 命名某個畫面會對應到的單詞:{"label": "badge", "at": "badge", "sound": "chime"}。為每個重要的出現設定提示點。填寫 brief(導言、方法、未解決問題);故事板會顯示它。
4. 繪製場景 (scenes/*.mjs)
閱讀 references/drawing.md(場景 API、輔助函數、佈局和動畫規則)。每個場景會收到 (ctx, t, S)。將每個出現的元素放在 S.cue(label) 或 S.w('word') 上,並讓每個元素透過 S.tout 離開。使用真實素材:
- 應用程式畫面: 使用
shots/capture.mjs擷取真實 UI,並使用screens.mjs(相機、游標、環形)來展示。參閱references/screens.md。 - 程式碼:
code.mjs會按行號讀取真實檔案,因此引用不會出錯。 - 程式輸出: 執行真實的程式並繪製其實際輸出。不要繪製你未曾見過的輸出。
繪製時同時抽樣。 在每個場景之後,執行 ./make.sh scene <id> 並在繼續下個場景前查看 out/sheet.jpg。對於每個棘手的動作或轉場,執行 ./make.sh clip A B 並觀看 out/clip.mp4。references/review.md 中有檢查清單。
5. 故事板:使用者在這裡反覆調整
./make.sh storyboard
這會依序執行:語音 → 時間軸 → 配樂 → 音訊混音 → 每個場景一張幀 → storyboard.html:一個自成一體的頁面,包含真實的語音與配樂混音、每個場景的一幀、標記了每個提示點單詞的劇本、時間碼以及簡報。播放時會高亮顯示當前場景和台詞。
在展示之前,請查看 out/board/ 中的每一幀,並修正任何錯誤。然後將該頁面提供給使用者。如果你的工具可以發布 HTML 頁面或成品,請發布 storyboard.html 並分享連結。如果不能,請提供在瀏覽器中開啟的檔案路徑。
然後與使用者反覆調整。每次修改都小而快:編輯 video.json 中的一行(只有變更的行會重新語音化)、移動一個提示點、改變場景的情緒、重新設定樣式、重繪一個場景。然後再次執行 ./make.sh storyboard。保持簡報中未解決問題的最新狀態。持續此循環,直到使用者核准故事板。
6. 完整渲染
僅在使用者核准之後:
./make.sh film # 或:./make.sh film --blur 4 (動態模糊,約慢 4 倍)
這會寫出 out/<name>.mp4(1920×1080,60 fps,AAC,音量 −16 LUFS)、out/<name>.srt 和 out/<name>.vtt。然後檢查實際輸出,而不是程式碼(參閱 references/review.md 的「最終檢查」):從編碼後的 MP4 擷取幀、確認時長和串流,並在變更的點收聽混音。執行 python3 storyboard.py --final 讓故事板頁面包含完成的影片。交付 MP4、字幕和故事板。如果這部影片是一則公告,請提供一段簡短的貼文來搭配,使用相同的劇本撰寫。
命令
| 命令 | 功能 |
|---|---|
./make.sh storyboard | 語音、時間軸、配樂、混音、故事板幀、storyboard.html |
./make.sh scene ID [0.3,0.6,0.9] | 一個場景在指定比例時的靜態幀,加上 out/sheet.jpg |
./make.sh samples [24] | 分散在整部影片中的靜態幀,加上 out/sheet.jpg |
./make.sh stills 3,20.5 | 在精確秒數的靜態幀,加上 out/sheet.jpg |
./make.sh clip A B | out/clip.mp4:從 A 秒到 B 秒的真實影片片段,含聲音 |
./make.sh voice / music / timeline | 僅執行單一步驟 |
./make.sh film [--blur N] | 完整渲染與混音 |
uv run tts.py --voices | 列出 Kokoro 語音 |
參考資料
references/script.md:如何編寫旁白以及整個video.jsonreferences/drawing.md:場景 API、lib.mjs輔助函數、佈局、動畫、場景模式references/screens.md:擷取真實應用程式畫面並在上面移動相機references/audio.md:語音、音樂風格、提示點音效、混音、額外音訊references/review.md:如何抽樣、修飾檢查清單、最終檢查references/fonts.md:從何處取得字型