Under the hood
將一個主題(或使用者的程式碼)轉化為有旁白、有動畫的解釋性影片。視覺風格溫暖且帶有手繪感:
- 奶油色點狀網格「紙張」背景搭配墨水線條藝術
- 藍色代表請求,橘色代表回應,綠色代表加密或成功
- 頂部有步驟追蹤器,底部有大字幕
- 在方塊之間飛行的資料包,以及在不同「世界」之間的攝影機平移
參考結果在 ${CLAUDE_SKILL_DIR}/assets/example-cookie/,展示了當你在 Google 輸入「cookie」時會發生什麼事。當你需要複雜模式的靈感時,請打開其 scenes.js。
一切都是由程式碼驅動的。一個 Canvas 頁面以確定性方式渲染影格,旁白剪輯設定每個場景的長度,音樂和音效則從相同的時間軸合成。腳本變更會重新同步所有內容,一部 60 秒的影片約在 30 秒內渲染完成。
主題要求:$ARGUMENTS
各項資源的位置
- 腳本:
${CLAUDE_SKILL_DIR}/scripts/(稱之為SCRIPTS)。 - 執行環境:
UTH_HOME(預設~/.local/share/under-the-hood)存放 node 模組、TTS 虛擬環境以及已儲存的語音。doctor.sh會印出確切路徑,包括PY(TTS 的 Python)。 - 專案: 如果使用者未指定其他位置,則放在目前工作目錄下的
./explainers/<slug>/。如果工作目錄是家目錄,請詢問要將專案放在哪裡,避免弄亂~。
一個專案資料夾看起來像這樣:
index.html engine.js scenes.js script.json timeline.js
narration/ (語音剪輯:<id>.wav, <id>_take2.wav,加上預覽檔案)
audio/ (音軌與 mix.wav)
.shots/ (螢幕截圖,每次執行一個新資料夾)
<slug>.mp4
工作流程
0. 檢查設定(準備好時執行單一行指令)
bash ${CLAUDE_SKILL_DIR}/scripts/doctor.sh # 如果影片無旁白,加上 --no-tts
如果印出 READY,請記下 PY 和 VOICES 並繼續。如果印出 MISSING 行,載入 under-the-hood-setup 技能並依照指示操作,然後再次執行 doctor 腳本。
1. 簡短的初步了解
如果 $ARGUMENTS 為空,請詢問主題。接著僅詢問你無法合理決定的內容,且只需一次訊息,並提供合理的預設值:
-
切入角度: 僅當主題很廣泛時需要。例如「網際網路如何運作」需要一個焦點,而「當你執行 git push 時會發生什麼事」則不需要。
-
語音: 務必提供此選項,因為使用者不知道他們也能用自己的聲音。以類似以下方式呈現:
- 內建語音(預設,立即可用)
- 已儲存的語音(如果
VOICES列出了) - 你自己的聲音: 用手機錄製約 20 到 30 秒的音檔並傳送。你的聲音只會留在你的機器上。
- 無旁白(僅音樂和音效)
如果他們選擇自己的聲音,請先閱讀
${CLAUDE_SKILL_DIR}/references/voice.md並提供其中的錄製技巧和範例段落。他們可以在你撰寫腳本時錄製。 -
長度: 預設 30 到 60 秒,16:9 比例。
不要把它變成問卷調查。最多問兩三個簡短的問題。
2. 理解主題並確保資訊正確
如果使用者提供了程式碼,請閱讀它並追蹤真實流程。技術觀眾會指出錯誤。因此:
- 確保事件順序正確。例如:在已載入的頁面上,DNS 和 TLS 握手已經發生,因此請將它們放在首次接觸時,或標記為「首次造訪」。
- 優先採用現代系統實際運作的方式。例如:Chrome 通過 QUIC 和 TLS 1.3 與 Google 通訊,而不是教科書上的 TCP 三向握手。
- 當你簡化時,在副標題中說「已簡化」。
- 使用說明性的數值(範例 IP、
.example域名、虛構的分數),避免像精確毫秒數這種虛假的精確度。 - 不要重新建立真實產品的標誌或像素級精確的 UI。線條風格的替代品無論如何都更符合這種風格。
3. 分鏡腳本與劇本,然後在開始建置前取得批准
規劃 4 到 8 個編號步驟,大約 30 到 60 秒,加上開頭的 title 場景和結尾的 end 場景。為每個場景撰寫:
- 旁白(
script.json):{"id", "text", "gap"}。gap是該行之後的停頓,0.25 到 0.45 秒。 - 字幕(
cap):8 個字以內,靜音時可讀。副字幕(sub):一行簡短的文字。 - 視覺節拍: 出現和移動的內容,以及每個聲音是什麼。
在撰寫旁白前,請先閱讀 ${CLAUDE_SKILL_DIR}/references/narration.md。文章式的旁白聽起來像 AI 在讀文章。要寫得像一個人向朋友解釋的方式。
以一個簡短的表格向使用者展示劇本和分鏡腳本,並等待批准。現在修改文字是免費的。語音生成後就需要重新執行。
旁白或螢幕文字中不要使用 em dash 和分號。TTS 讀起來會很奇怪,而且短句無論如何聽起來更自然。
4. 建立專案骨架
bash SCRIPTS/new_project.sh ./explainers/<slug> "<頁面標題>"
這會複製 engine.js、一個入門的 scenes.js(一個可運作的「按下發送」小範例)和 script.json。它不會覆蓋非空的資料夾。將入門內容替換為你的實際分鏡腳本。
5. 建立 scenes.js
首先閱讀 ${CLAUDE_SKILL_DIR}/references/engine-api.md。它涵蓋了時間模型、每個輔助函式、佈局區域、聲音名稱和啟動設定。關鍵概念:
- 使用
defineScenes([...])搭配設計時長。使用prog(t, S.id + a, S.id + b)在設計時間內製作動畫。引擎會自動拉伸每個場景以配合其語音剪輯的長度,因此永遠不要手動調整以配合剪輯長度。 - 將世界保持在 y 150 到 800 的範圍內。追蹤器位於其上,字幕位於其下。
- 應該持續存在的物體(例如瀏覽器、伺服器)在一個場景中出現,並在其後繼續繪製。
- 對於第二個「地點」,例如資料中心內部,在 x + 1920 處繪製,並使用
camera(t)平移。在平移過程中開始揭示其內容,這樣螢幕在移動過程中就不會是空的。 - 每個可見事件都在
sfx(add)中配上一個聲音。按鍵對應key,飛行的資料包對應whoosh*,到達對應thunk或pop,成功對應chime或success。這是讓影片感覺完整的重要原因。
6. 不帶語音預覽,檢查影格
node SCRIPTS/shots.js <project> # 每個場景的中間影格,儲存到新的 .shots/<time>/ 資料夾
查看每張螢幕截圖。在閱讀前先縮小圖片(macOS 上用 sips -Z 960,其他系統用 ffmpeg -i in.png -vf scale=960:-1 out.png)。檢查:
- 文字是否重疊或超出邊緣
- 平移過程中是否有空的影格
- 元素是否畫在它們本該在的物體之上
修正問題並重新拍攝。如果頁面無法啟動,腳本會印出頁面錯誤。
7. 語音
內建語音(不帶 --voice):
$PY SCRIPTS/narrate.py --script <project>/script.json --out <project>/narration --takes 2
已儲存的語音:加上 --voice <UTH_HOME>/voices/<name>.wav。
來自錄音的新語音:請依照 ${CLAUDE_SKILL_DIR}/references/voice.md 操作。它涵蓋了 prep_voice.sh、一個快速測試行以及同意事項。只能克隆使用者自己的語音,或他們確認已取得同意使用的語音。
然後讓使用者聆聽:<project>/narration/narration-preview_take1.wav(macOS 上用 open,Linux 上用 xdg-open)。
- 第一次執行會下載約 1 GB 的模型權重。之後在 Apple Silicon 或 GPU 上運行速度約為即時,在 CPU 上較慢。
- 你無法聽到音訊。 告知使用者這一點,並請他們用耳朵判斷各次錄音。他們可以逐行混合不同次錄音。使用
--only <id>重新錄製單一行。 - Turbo 支援 [chuckle]、[laugh]、[sigh]、[gasp] 和 [surprised] 等標籤。每部影片最多使用一兩個。
無旁白:跳過此步驟和 build_timeline.py。場景將保持其設計時長,影片將只有音樂和音效。
8. 時間軸、渲染、驗證
python3 SCRIPTS/build_timeline.py <project> [--pick dns=2,enter=2]
node SCRIPTS/render.js <project> [--music-db -12] [--sfx-db 1] [--silent] [--audio-only]
render.js 會建構語音、音樂和音效的音軌,並將它們混合,在語音下降低音樂音量,並正規化至 -16 LUFS。它會渲染為 <slug>.partial.mp4,只有在 ffprobe 確認完整長度後,才會重新命名為 <slug>.mp4。
在告訴使用者完成之前,請驗證實際檔案:
- ffprobe 顯示預期時長以及視訊和音訊串流
ffmpeg -ss <後段時間> -frames:v 1顯示正確的場景- 響度約為 -16 LUFS
然後開啟 MP4 和 index.html 預覽。預覽會同步播放混音,並提供章節和時間軸拖曳功能。
清楚地報告已驗證的內容、你無法檢查的項目(音訊聽起來如何),以及哪些部分已被簡化。
工作規則
- 不要使用 glob 刪除。 不要在專案資料夾上執行帶有萬用字元的
rm或rm -rf。新輸出將放入新的資料夾,檔案會按名稱被覆蓋。 - 被中斷的命令可能已部分執行。 如果使用者中斷了一個多步驟的命令,請在繼續之前檢查磁碟上的變更,並告知他們任何部分效果。一組被部分替換的剪輯可能會留下一個看起來已完成的短影片。
- 不要根據偏好暗示自動切換。 如果使用者還在決定時說「我喜歡第二次錄音」,請在重新渲染前確認。
- 提供選項,但不建置: 例如 9:16 直立版本、修剪至 30 秒,或更多打磨。每項用一行提及。
疑難排解
'NoneType' object is not callable出現在PerthImplicitWatermarker:執行uv pip install --python $PY "setuptools<81"。Chatterbox 的水印庫需要pkg_resources。- 第一次執行 TTS 很慢:這是因為暖機和模型下載。後續執行會更快。
- 音樂太大或太小聲:
--music-db(預設 -12)。音效:--sfx-db(預設 1)。使用--audio-only快速疊代混音。 - 找不到 Chrome:設定
CHROME_PATH,或載入under-the-hood-setup技能。 - Chrome 的離線音訊在不同執行之間並非位元完全相同,因此不同渲染之間的音軌會略有差異。時間點是精確的,影格是像素級相同的。