程式碼解說影片 是做什麼的?
為開發者製作的帶旁白動畫程式碼導覽。觀看者是工程師:展示真實的程式碼、真實的檔案和函式名稱,解釋「為什麼」和「如何運作」,絕不為了非開發者簡化成比喻。
技術棧:Remotion 的 Code Hike 範本(語法標亮的程式碼在步驟間變形)、Mermaid 用於繪製架構圖、ElevenLabs 用於旁白(使用 ElevenLabs 連接器或帶金鑰的 API),以及內嵌字幕。當你修改 template/ 中的 Remotion 程式碼時,請載入 remotion-best-practices 技能。
與此 SKILL.md 同目錄(「技能目錄」)的檔案:
template/:複製到每個影片專案中的 Remotion 原始檔。references/voice.md:在步驟 8 產生旁白前閱讀。references/long-form.md:當影片長度為 15-30 分鐘時優先閱讀;它將工作拆分為章節,每個章節分別執行步驟 2-9。
1. 前期資訊收集:三個問題,依此順序,開始任何工作前先問
一次問一個(可使用 AskUserQuestion 時)。不要跳過或合併它們。
- 你需要理解什麼? 取得目標(一行、一個區塊、函式、檔案、流程或整個架構),以及原因(修正錯誤、新增功能、審查 PR、新手上路)。如果答案很模糊(例如「那個認證相關的東西」),先閱讀程式碼,然後提供 2-4 個具體方向供選擇,例如「請求從頭到尾如何被認證」vs.「session 如何儲存和過期」。
- 應該花多久時間? 提供選項:約 30 秒(一行或一個區塊)、1-2 分鐘(一個函式或模組)、約 5 分鐘(一個子系統或流程)、15-30 分鐘(程式碼庫入門,由平行代理程式以章節方式建構)。如果他們不知道,根據你在步驟 1 的發現推薦一個。
- 我的理解是否正確? 閱讀程式碼後,回傳:
- 這個影片回答的一個問題,用一句話表達;
- 長度與節拍數;
- 大綱:每個節拍一行(畫面上顯示的內容 + 說明的重點);
- 你刻意省略的任何內容。 只有在得到「是」之後才開始建構。如果得到「否」,則修改並重新確認。這個步驟的存在是因為旁白會消耗 ElevenLabs 的點數,且渲染需要幾分鐘。
當在無人值守模式下執行(沒有人可以回答問題)時,選擇最合理的解讀,在你的回覆頂部說明,然後繼續進行。
2. 在寫任何一個字之前先研究程式碼
- 閱讀實際的程式碼。追蹤函式呼叫到它們的定義;不要從名稱推斷行為。對於大型程式碼庫,如果你的代理程式支援子代理程式,為每個區域啟動一個唯讀的子代理程式,並只保留它們的結論。
- 旁白中的每個聲明都必須對應到你讀過的檔案和行號。在研究過程中,維護一份
notes.md,記錄聲明 → 路徑:行號;在步驟 7 中修正問題時你會用到它。 - 注意開發者可能會卡住的地方:隱藏的副作用、順序假設、錯誤路徑、會改變行為的設定、名不副實的名稱。
3. 根據時間預算規劃節拍
一個節拍是一個視覺畫面加上 1-3 句旁白。旁白速度約為每分鐘 150 個字(2.5 字/秒);每個節拍結尾有 0.6 秒的停頓。
| 預算 | 節拍數 | 字數 |
|---|---|---|
| 30 秒 | 3-4 | 約 70 |
| 1-2 分鐘 | 6-12 | 150-280 |
| 5 分鐘 | 20-30 | 約 700 |
| 15-30 分鐘 | 每章 3-5 分鐘,請參閱 references/long-form.md |
節拍規則:
- 以正在回答的問題開場,並以一句話總結收尾。不要有開場白廢話,也不要說「在本影片中」。
- 先說明架構,再放大細節:圖表,然後是入口點的程式碼,最後是有趣的那一行。
- 解釋目的,而不是逐行解釋程式碼。每個程式碼節拍要說明該程式碼的目的以及它如何與前一個節拍連接,然後指向相關的一兩行。永遠不要逐行講解一個區塊。
- 程式碼節拍:最多 16 行(畫面底部保留給字幕)且每行最多 80 個字元。刪除不相關的行,並用
// ...註解取代。連續顯示相同片段但不同標亮的節拍會平滑動畫過渡,因此請重複使用片段並移動標亮。 - 使用 Code Hike 註解直接放在要標亮的程式碼上方,以標示旁白正在說明的內容:
// !mark(下一行)或// !mark(1:4)(接下來的四行)。使用該語言的註解語法(Python 中為# !mark)。 - 圖表節拍:使用最多 8 個節點的 Mermaid
flowchart。對於超過四個節點的鏈,使用TD。在連續的圖表節拍中保持節點相同,只移動class X hot這一行,這樣版面就不會跳動。 - 旁白是為了聽覺而寫:使用短句,以開發者的方式說出識別碼(例如「handle-request 函式」),不要逐符號朗讀程式碼,不要說出行號。
4. 專案設定(每個影片一次)
設定 SKILL_DIR 變數為技能目錄,然後執行:
npx create-video@latest --yes --code-hike explainer && cd explainer
npx remotion add @remotion/media && npm rm twoslash-cdn && rm public/code*
rm src/calculate-metadata/process-snippet.ts src/annotations/Callout.tsx src/annotations/Error.tsx src/ProgressBar.tsx src/ReloadOnCodeChange.tsx
cp -R "$SKILL_DIR/template/" .
command -v mmdc || npm i -g @mermaid-js/mermaid-cli
Twoslash 被刻意移除:它會將程式碼摘錄中每個未解析的引入標記為紅色錯誤。複製的檔案會取代範本中的 composition,改為由 beats/ 驅動:
scripts/build.mjs將beats/轉換為public/beats/(音訊、渲染的圖表、manifest.json)並測量每個節拍音訊的長度。src/Main.tsx依序播放節拍:標題、程式碼或圖表、音訊、字幕。src/annotations/Mark.tsx實作了!mark標亮功能。src/Captions.tsx根據每個節拍音訊的時間軸來安排字幕片段。
5. 撰寫節拍
每個節拍在 beats/ 中有一對檔案,編號排序(01、02、… 10):
NN.txt:可選的第一行# <螢幕標題>(程式碼節拍使用path/to/file.ts:42-60,圖表使用簡短標題),然後是旁白文字。- 一個視覺檔案:程式碼摘錄使用
NN.<副檔名>(副檔名設定標亮的語言:.ts、.py、.go、…)或 Mermaid 圖表使用NN.mmd。使用classDef hot fill:#facc15,color:#000,stroke:#facc15和class NodeId hot來標亮圖表節點。
範例配對:
beats/04.txt
# src/auth/session.ts:31-44
Session 是懶惰更新的。過期檢查只在請求到達時執行,因此閒置的 session 永遠不會在這裡被清理。
beats/04.ts
export async function getSession(id: string) {
const s = await store.get(id);
// !mark(1:3)
if (s && s.expiresAt < Date.now()) {
return renew(s);
}
return s;
}
6. 草稿檢查(不消耗點數)
- 如果沒有
beats/*.mp3且沒有金鑰,執行node scripts/build.mjs會寫入根據估計長度的靜音佔位音訊,並印出總長度。如果超出或低於預算 15% 以上,立即增減節拍。 - 渲染畫面上內容最多的時刻,以及每個標亮出現的時刻(約節拍開始後 1.5 秒):
npx remotion still Main out/check.png --frame=<n> --scale=0.5。檢查這些靜止畫面。修正超出邊界的行、難以閱讀的圖表以及標亮在錯誤行上的問題。
7. 獨立事實查核(在產生任何旁白之前)
腳本的作者是檢查腳本的最差人選。請讓未參與編寫的審查者針對程式碼檢查每個聲明。即使在無人值守模式下也要這樣做。
- 如果你的代理程式支援子代理程式,啟動一個新的子代理程式。提供它儲存庫路徑、每個
beats/NN.txt及其對應的視覺檔案,以及此簡介,但不要提供notes.md或你的大綱,這樣它才能形成自己對程式碼的解讀:根據程式碼檢查這個解說腳本。列出旁白和螢幕標題中的每個事實陳述。針對每個陳述,找到確認或反駁它的程式碼,追蹤函式呼叫到它們的定義。每個陳述回傳一行:
節拍 | 陳述 | 正確 / 錯誤 / 無法驗證 | 路徑:行號 | 原因。同時標記與原始碼不同的程式碼摘錄(除了// ...刪除和!mark註解之外)、標題中path:line範圍錯誤的部分、腳本對這段程式碼任何重要但陳述有誤導性的內容,以及旁白逐行說明程式碼但沒有說明其目的的程式碼節拍。 - 否則,自己進行第二次檢查:針對每個陳述,重新開啟引用的程式碼並在那裡檢查,而不是根據
notes.md。
修正每個標記為 錯誤 的陳述,刪除或軟化每個標記為 無法驗證 的陳述,並圍繞目的改寫被標記的逐行節拍。重新執行草稿建置,並僅將修改過的節拍送回進行第二次檢查。
8. 語音與渲染
- 閱讀
references/voice.md,並使用第一個可用的選項為每個節拍產生一個旁白檔案:ElevenLabs 連接器、ElevenLabs API 金鑰、其他文字轉語音供應商,或沒有(只有字幕的無聲影片)。整個影片使用同一個語音。 - 再次執行
node scripts/build.mjs。它會在beats/NN.mp3存在時使用它,因此修改一個節拍只需取代那個檔案。 - 渲染一次:
npx remotion render Main out/explainer.mp4。檢查影片和音訊的持續時間是否匹配(ffprobe -v error -show_entries stream=codec_type,duration -of csv=p=0 out/explainer.mp4),並且除非影片預定是無聲的,否則檢查音訊不是無聲的(ffmpeg -i out/explainer.mp4 -af volumedetect -vn -f null - 2>&1 | grep mean_volume;佔位音訊讀數約為 -91 dB)。
9. 交付前
- 觀看,或至少聆聽第一個、最後一個和中間的一個節拍。如果某個識別碼發音錯誤,在
NN.txt中用注音方式重新拼寫它,並僅重新生成該節拍的語音。字幕會顯示旁白文字,因此語音符號重新拼寫也會出現在那裡;保持重新拼寫內容可讀。 - 任何在步驟 7 之後修改的旁白都需要再次通過步驟 7 的檢查。
- 交付 mp4 檔案,並附上一行摘要,說明這個影片回答了什麼問題。未經明確許可,不得在任何地方上傳或發布它。