錄製示範影片(免費、腳本化)
透過腳本控制瀏覽器來製作真實應用程式的無聲產品示範影片,然後渲染成mp4。 完全免費且在地端執行:Playwright 驅動應用程式,ffmpeg 製作影片。無需付費SaaS、無需旁白、 無需人工點擊。同樣的腳本也可作為UX冒煙測試(smoke test),當UI變更時只需重新渲染即可更新影片——這正是 它能夠永續產出大量功能示範影片的關鍵。
使用時機
- 用戶想要一個或多個功能示範/導覽影片,但不想付費購買工具。
- 遇到「每次新功能都要有人手動螢幕錄製」的重複性問題。
- 需要快速以視覺方式證明某項功能在真實UI中能端到端正常運作。
不適用於:需要大量動畫和配音的行銷影片(請使用專業剪輯軟體),或需要真人即時反應的內容。
結構
建立登入會話 → 使用Playwright驅動應用程式(錄製.webm) → ffmpeg → .mp4
三個檔案會放入目標儲存庫的 demo/ 目錄下(從 resources/ 複製):
record.mjs— 引擎。包含一個CONFIG區塊(依儲存庫而異)和一個FLOWS對應表(每個影片一個條目)。polish.sh— 將.webm轉換為.mp4,裁剪登入前導部分,可選燒錄字幕。run.sh— 單一指令:將開發伺服器指向staging、錄製、後製、清理。README.md— 每個儲存庫的使用說明。
要製作新影片:複製一個FLOWS條目,修改其中的 url 和 steps。就這麼簡單。
設定檢查清單(每個儲存庫只需執行一次)
- 安裝工具(一次性):
npm install -D @playwright/test && npx playwright install chromium。需要ffmpeg(使用Homebrew安裝)。若要使用燒錄字幕功能,則需要一個包含libfreetype的ffmpeg版本;否則字幕會自動跳過,其他功能不受影響。 - 探索儲存庫的特定資訊,並填入
record.mjs中的CONFIG區塊:- 開發指令 — 應用程式在本機執行的方式(通常是
npm run dev,有時會在子目錄中,例如congrats/)。 - Supabase客戶端模組路徑 — 通常是
src/integrations/supabase/client.ts。錄製器會在頁面中導入它來進行登入(請參閱陷阱1)。 - 要用哪個資料庫錄製 — 使用 staging,絕對不能是生產環境(避免真實用戶的PII)。找到它的URL、匿名/發布金鑰、服務金鑰以及直接DB URL。在此組織中,它們位於audition儲存庫的
.env.local檔案中(VETTED_SUPABASE_*用於VettedAI的staging環境,STAGING_CONGRATS_SUPABASE_*用於Congrats的staging環境)。 - 登入用的電子郵件 — 一個擁有可展示資料的合成/測試帳號。在建立會話前務必詢問用戶要用哪個帳號(專案規則:未經許可不得測試真實用戶資料)。
- 路由 — 你要錄製的流程的深層連結路徑。
- 開發指令 — 應用程式在本機執行的方式(通常是
- 將本機開發伺服器指向staging環境(請參閱陷阱2)。
- 編寫一個流程,執行
bash demo/run.sh <flow>,然後透過提取幀來驗證(陷阱8)。
陷阱(這些是實戰經驗——請在除錯前先閱讀)
1. 透過應用程式自己的客戶端登入,而不是偽造localStorage
Supabase-js在瀏覽器中以非預設的金鑰/封包格式寫入其會話;手動注入
localStorage['sb-<ref>-auth-token'] = JSON.stringify(session) 看起來正確,但客戶端不會讀取它 →
應用程式會跳轉到 /login。正確做法是:在伺服器端建立會話(使用 generateLink 搭配 verifyOtp 會產生
access_token 和 refresh_token,無需密碼),然後在頁面中 import 應用程式的Supabase客戶端
並呼叫 supabase.auth.setSession({access_token, refresh_token})。這樣會寫入正確的儲存空間,而且
會話在導航過程中仍然有效。這是最重要的一步。
2. --mode staging 可能被靜默忽略 → 應使用 .env.development.local
vite-react-ssg dev(以及某些設定)會忽略 --mode 參數的環境檔案載入,因此 .env.staging 永遠不會被載入,
應用程式會持續指向生產環境(你會看到請求發送到生產環境的Supabase主機)。Vite 始終會在開發模式下自動載入
.env.development.local,且其優先級高於 .env 和 .env.local。因此 run.sh 會在開始錄製時將staging設定
複製到 .env.development.local,然後在退出時刪除它(否則未來每次執行 npm run dev 都會靜默地使用staging
設定——這是一個嚴重的陷阱)。普通的 vite 儲存庫可能會遵守 --mode 參數;請透過觀察應用程式呼叫哪個Supabase主機來測試。
3. Staging的資料庫結構可能落後於前端 → 進行有針對性的漸進式修正
Staging分支可能缺少前端需要查詢的新欄位 → 資料查詢會回傳400錯誤(column X does not exist),
畫面會呈現空白。不要重播遷移腳本。比較畫面讀取的少數幾個表格的欄位差異(透過 information_schema.columns
比對staging和生產環境),然後只應用缺少的欄位,並以漸進式、可為空的方式執行 ALTER TABLE ... ADD COLUMN IF NOT EXISTS。
取得用戶的同意——因為這會變更staging資料庫。
4. 種子資料的尺度可能不符合預期
合成種子資料的分數/數值可能與UI格式化器預期的範圍不符(例如,資料庫儲存的分數範圍是0-100,但UI使用
value/5*100 進行計算 → 顯示「1392%」)。請檢查格式化器預期的範圍與生產環境的真實數值;必要時重新調整種子資料的
尺度(先詢問——因為這會變更資料)。
5. Playwright錄製的影片不會顯示滑鼠游標
透過 addInitScript 注入一個假的游標覆蓋層(在滑鼠移動時顯示一個小點,在滑鼠按下時變大)。
範本中已經包含了這個功能。在點擊前請先將滑鼠移動到正確的座標位置,這樣游標才會追蹤。
6. ffmpeg 可能缺少 drawtext
沒有libfreetype的ffmpeg版本在進行燒錄字幕時會報錯。polish.sh 會檢測 drawtext 是否存在,
如果缺少則會跳過字幕——不要因為字幕失敗而阻止mp4的產生。
7. 自動裁剪登入/啟動的前導部分
錄製畫面會包含登入和應用程式啟動的過程(空白秒數)。record.mjs 會測量前導時間並寫入一個
.trim 側檔;polish.sh 會根據該時間進行裁剪(使用 ffmpeg -ss)。
8. 透過擷取幀來驗證,不要只看「它錄製了」
使用 ffmpeg -ss <t> -i out.mp4 -frames:v 1 frame.png 在幾個時間點擷取幀,然後實際查看。
最初的幾次執行可能會停留在 /login 頁面、骨架畫面或錯誤的分頁——擷取幀是發現這些問題的方法。
9. 資料與驗證安全
在 staging 環境中使用合成資料(例如 seed_…@test.vetted.com)進行錄製,絕不要使用真實客戶的專案
(PII)。務必詢問用戶要以哪個帳號登入。建立驗證會話是一項真實操作——請先確認。
編寫流程
在 record.mjs 中,FLOWS 是一個對應表,包含 { label, url, steps(page, ui) }。ui 輔助函式涵蓋了大多數需求:
ui.settle(what, [words])— 等待內容載入(networkidle + 一個能證明畫面已載入的關鍵字)ui.scrollThrough(fraction, steps)— 平滑向下滾動再返回ui.clickFirstCandidate()/ 通用版本ui.clickFirst(selectors)— 盡力點擊,絕不硬性失敗ui.beat(ms)— 刻意暫停,讓影片看起來流暢
流程應保持選擇器輕量化且盡力而為(使用try/catch包裹點擊),這樣當某個選擇器無法匹配時,只會退化為「仍然是一個不錯的滾動展示」,而不會直接崩潰。節奏要寬裕(800–1800毫秒的暫停時間);一個好的無聲示範影片長度約為15–35秒。
輸出與交付
mp4檔案會放入 demo/output/ 目錄(已在gitignore中排除)。使用 open demo/output/<flow>.mp4 來播放
(Markdown的相對連結在IDE中無法播放——它會直接在編輯器中開啟檔案)。請分享路徑或使用 open 指令為用戶播放。
傳播此技能(本技能位於skill-master中)
此技能的正式版本位於 submodules/skill-master/.agent/skills/recording-demo-videos/,並以符號連結的方式
同步到各個儲存庫的 .agent/skills/ 目錄中。編輯完後,請先提交並推送子模組的變更,然後再更新父儲存庫的指標,
接著執行 /distribute-skill 來將此技能同步到其他兄弟儲存庫(推送前請先詢問用戶)。請參閱
skill-master-submodule-sync 規則。