程式碼製作 3D 影片(影片與 Shorts)
每一幀都是時間的純函數,以 HTML/CSS/three.js 撰寫。同一個網頁既是即時編輯器(即時播放,不存檔),也是渲染來源(Chromium 逐幀捕捉,ffmpeg 合成)。使用者是導演,你負責執行。直到使用者觀看過即時版本後才進行渲染。
工作流程包含七個步驟。請依序執行,且不可跳過步驟五。
| # | 步驟 | 產出結果 |
|---|---|---|
| 1 | 設定 | 從 template/ 複製專案資料夾,啟動伺服器 |
| 2 | 腳本 | script.md,接著鏡頭計畫:一句話 = 一個鏡頭 |
| 3 | 語音 | voiceover.mp3 + 單字時間戳記,或若語音稍後提供則使用預估時間 |
| 4 | 風格 | 外觀以數字寫入 STYLE.md,並建構到 3D 世界中 |
| 5 | 修正 | 即時編輯器審查,套用意見,重複錯誤加入 references/lessons.md |
| 6 | 渲染 | 分段渲染,與音訊合併 |
| 7 | 上傳 | 標題選項、描述、章節、縮圖提示 |
1. 設定
- 工具位於
~/.youtube-video-editor/venv(Playwright Chromium、imageio-ffmpeg、pillow、faster-whisper)。 若遺失,執行~/.claude/skills/youtube-video-editor/scripts/setup.sh。務必使用~/.youtube-video-editor/venv/bin/python -I呼叫。使用者的 Mac 上沒有系統級的 ffmpeg 或 node。 - 將
template/複製到使用者可見的資料夾內的<project>/(他們通常使用~/Downloads)。 16:9 影片 →index.html+scenes.js。直立 Short →short.html+scenes-short.js(舞台 1080×1920)。 - 啟動伺服器:從專案資料夾執行
python3 -m http.server 8766 --bind 127.0.0.1(使用nohup … &在背景執行), 然後在瀏覽器面板中開啟http://localhost:8766/index.html。file://頁面會顯示為靜態快照, 且preview_start搭配 launch.json 在此 Mac 上無法啟動伺服器,因此請從 Bash 啟動。
2. 腳本
- 腳本決定影片內容。以使用者的口吻撰寫:簡短的句子、白話、不要教科書語氣。 他們的觀眾是非技術背景的初學者(Low Code Studio)。每分鐘約 150 字;Short 約 60–110 字。
- 在動畫前規劃鏡頭:一句話 = 一個場景,並為每個場景寫一行說明攝影機所見。 修改計畫是免費的,修改動畫則不然。
- 若受其他影片啟發:保留結構與教學內容,但更換所有範例、視覺與台詞。絕不可重複使用 他們的畫面、措辭、縮圖或角色。
3. 語音
- 使用者自行錄製語音(這是品牌的一部分),之後再加入頭像。因此第一個版本沒有音訊:
每個場景的長度是根據其
vo字數估算(由 engine.js 中的WPS/PAD計算)。 - 當
voiceover.mp3存在時:轉換為 16 kHz 單聲道 wav,執行~/.claude/skills/youtube-video-editor/scripts/transcribe.py取得單字時間,設定每個場景的dur為 其第一個字與下一個場景第一個字之間的時間差,並將data-in值對齊關鍵單字。 場景內的時間會自動隨場景長度伸縮(撰寫節奏 → 實際節奏),因此大多數場景只需要設定dur。 渲染時傳入--audio voiceover.mp3。 - 在此 i3 Mac 上,當機器忙碌時 Whisper
small可能變慢。base、beam_size=1、無單字時間戳記 速度快約 5 倍,且足以作為參考;僅在最終同步時才使用small+ 單字時間戳記。
4. 風格:數字,而非形容詞
「電影感」沒有意義;每個場景會有不同的解讀。在專案中撰寫 STYLE.md,包含可檢查的規則,
然後一次性地將這些規則建構到世界中。從 references/style-rules.md 開始(內建 3D 外觀:攝影機
角度、鏡頭、燈光數值、色板、動態、字幕)。若使用者提供參考圖片,閱讀它們並將所見轉換為
同樣的數字。使用他們自己的參考,而非複製其他創作者影片。
2D 動態圖形耗費更少的 token 且比 3D 更穩定。在空間、比例或旅程重要的鏡頭(鉤子、「世界」鏡頭) 使用 3D,在提示、列表、比較與章節卡片使用 2D 卡片。一個好的搭配大約是每三到四個場景中有一個 3D 鏡頭。Short 可以全部使用 3D,因為它只有少數幾個鏡頭。
5. 修正:即時編輯器(絕不跳過)
- 為使用者開啟編輯器,然後停在那裡。他們明確要求:在完整渲染之前於即時編輯器中審查。 側邊面板顯示每個場景的語音旁白,讓他們調整長度(±0.5 秒)並寫下意見; 複製我的審查意見按鈕會將所有內容複製到剪貼簿,供他們貼回給你。
- 交給使用者之前,先檢查自己的工作:
render.py --sheet sheet.jpg會產生每個場景的一幀畫面。 檢視它(將高長條圖分割成 3 個裁切以便閱讀),修正錯誤,重複直到正確。常見的初稿錯誤 記錄在references/lessons.md中。開始建構前先閱讀該檔案。 - 當相同的意見出現在多個場景中時,修正影片並且將一行記錄加入
references/lessons.md,讓下一部影片一開始就解決這個問題。這就是本技能的核心價值。
6. 渲染
- 只有在使用者批准即時版本後才進行。
render.py --chunks out/chunks --chunk-len 60然後render.py --join out/chunks final.mp4 [--audio voiceover.mp3]。對於 Short 需加上--size 1080x1920和short.html?render網址。若某個場景錯誤 → 刪除該chunk_NNN.mp4並重新執行;只有它會被重新渲染。 - 在 i3 上的速度(實測):全螢幕 1080p 3D 場景約每秒 1 幀,因為無頭 WebGL
以軟體方式執行。一部 10 分鐘、30 fps 的影片是 18,000 幀,所以預計需要 3–5 小時,並在開始前告知使用者。
若使用者同意,可使用
--fps 24,使用nohup在背景執行,保持 Mac 清醒(request_keep_awake),並 最多同時執行兩個區塊處理程序(使用--start/--end將範圍分割到不同資料夾)。 - 無頭 Chromium 需要
--use-angle=swiftshader --enable-unsafe-swiftshader才能使用 WebGL(已包含在 render.py 中)。 - 無需重建即可重新剪輯:場景是一個陣列,因此重新排序或刪除場景就是一份編輯清單。如果開場 太慢,將最強的鏡頭移到索引 0。
7. 上傳
你已經知道腳本,因此撰寫 5 個標題選項(建議一個)、描述、根據場景開始時間的章節、
以及標籤。請遵循 ~/.claude/skills/youtube-video-editor/references/youtube-metadata.md。
縮圖是唯一適合使用影像模型的地方:渲染一張強而有力的靜止畫面(render.py --stills),
撰寫提示,讓使用者產生或合成它。縮圖上的每個宣稱都必須與影片內容相符。
場景格式(engine.js)
SCENES.push({
id: 'belt', chapter: '2 · 腳本', title: '盒子在皮帶上', // 在編輯器中顯示
vo: `你的盒子在皮帶上行進。`, // 口語台詞;在音訊存在前決定長度
dur: 4, // 可選:固定長度(秒)
cls: 'z', // 可選:plain | grad | paper | z | z1(放大)
html: `<div class="three abs" style="inset:0"></div>
<div class="h1" data-in="0.4" data-a="pop">你好</div>`,
tick: (t, root) => K.draw3d(root.querySelector('.three'), 1920, 1080, t, 'belt'),
});
- 宣告式:
data-in/data-out(秒)、data-a(up down left right pop fade drop zoom)、data-d、data-type(打字機效果)、data-count="0,2400000"、data-w="0,80"(寬度百分比)、data-draw(SVG 描邊)。 tick(t)用於任何客製需求。它必須只依賴t:不可使用Date.now()、不可使用Math.random()(改用E.rnd(i))、不可使用 CSS 動畫或過渡。否則渲染結果將不匹配預覽。- 工具庫:
K.chat()Claude 風格提示框、K.track()步驟追蹤器、K.chapter()滿版章節卡片、K.wave()+K.waveTick()、K.draw3d(holder, w, h, t, mode)用於一個 3D 視角、K.snap(canvas, t, mode)用於 在一個場景中顯示多個攝影機視角(共用一個 WebGL 渲染器;絕不為每個場景建立渲染器)。 - 3D 世界為
K.world()(在 kit.js 中):只建立一次,update(t, mode)移動物件並放置攝影機。 對於新的影片,在那裡替換物件和攝影機模式;保持模式不變。examples/workflow-video/是一個 使用此技能製作的完整 10 分鐘影片(45 個場景)。在撰寫新場景之前閱讀它以取得模式。
兩種視覺風格:玩具立體模型與故事世界
kit.js中的K.world()是簡單的平塗陰影立體模型(建構快速,適合解說與背景)。template/worlds.js是更豐富的故事視覺風格,使用者在稱立體模型「不夠真實」後偏好此風格: 平滑的玩具風格角色(person()帶有可動頭部、手臂、腿部,加上walk())、漸層天空穹頂、 ACES 電影色調映射、一個低角度暖色太陽加上暖色實用光源、用於燈具、蒸汽與光束的疊加發光精靈、 畫布紋理窗戶、用於深度的霧氣。其中包含三個完整的 6 秒世界(黎明茶攤、夜間送貨員、燈塔管理員);examples/story-samples/展示如何將它們放到頁面上。在kit.js之後載入worlds.js,並使用K.drawStory(holder, w, h, t, name)繪製。- 程式碼製作的 3D 無法達到照片級真實。若使用者要求「超寫實」,請明確告知並提供選擇: AI 影片(消耗點數,且影片不能再宣稱「全程式碼」)或故事視覺風格。然後提供 2–3 個簡短 範例片段供選擇,再以同一視覺風格建構整部影片。
- 每個故事鏡頭都要有一個角色在場景內從開始到結束做一件事(走進來、停下、揮手;舉起燈籠)、 一個名牌,以及一個移動光源。這就是讓人感到「一個故事」的要素。
Shorts 檢查清單
1080×1920,20–45 秒,一個想法。鉤子在 2 秒內可見且被口語說出,從動態開始。字幕 2–5 個字,
放在深色藥丸形背景上(明亮的 3D 天空上直白文字難以閱讀),位於安全區域內:上方 220 px
或下方 420 px 內不要放置重要內容。使用較緊湊的攝影機模式(belt、follow、hero),
因為廣角鏡頭在直立格式中會變得很小。以回報加上一行要求追蹤的句子結束;刪除任何結尾。
捆綁檔案
template/:index.html、short.html、engine.js、kit.js、worlds.js、style.css、render.py、starter scenes、lib/three.min.jsexamples/story-samples/:三個角色範例片段頁面examples/workflow-video/:完整的「我如何用 Claude Code 製作影片」建構(scenes-1/2/3.js + index.html); 將這些複製到範本檔案旁即可執行(其 0:21 牆上的縮圖未包含在內)references/style-rules.md:以數值呈現的 3D 內建外觀references/lessons.md:已付出代價的錯誤(開始建構前閱讀,每次審查後附加)