錄製自動化演示影片 (Playwright)
模式 (先決定)
接收的參數: $ARGUMENTS
| 參數 | 模式 | 範本 |
|---|---|---|
包含 audio (或請求要求語音 / 旁白 / 口述旁白) | 旁白模式 — TTS 語音 + 字幕 | record-demo-narrated-template.mjs + narrate.py |
| 空白 / 其他任何內容 | 無聲模式 — 僅字幕 (預設) | record-demo-template.mjs |
旁白模式:語言 en (預設) 或 pt (巴西葡萄牙語);引擎 auto (預設:英文 → kokoro 離線;葡萄牙語 → edge,離線時回退至 kokoro),或強制使用 kokoro / edge。例如:audio、audio pt、audio pt kokoro、audio en edge。另請遵循下方的旁白模式。
根據所選語言(除非指定 pt 或使用者以葡萄牙語書寫,否則預設為 en)編寫字幕和旁白。
概述
演示影片是程式碼,而非手動捕捉:一個 Playwright 腳本驅動瀏覽器進行原生錄製,疊加字幕和視覺亮點。每當產品變更時即可重新錄製 (npm run demo:record),且具有可控的節奏和故事情節。
核心原則:影片是一份簡報,而非端到端測試。 每個場景旨在證明一個觀點——且只有在您逐幀驗證生成的影片後,工作才算完成。
使用時機 / 不使用時機
- ✅ 為投資人、客戶、利害關係人、新進人員製作的 Web 產品 POC/演示
- ✅ 記錄持續演進的端到端流程 (可重新錄製)
- ✅ 搭配語音:旁白模式 (本地/離線 TTS) — 請見上方說明
- ❌ 自動化測試 (請使用 Playwright Test) · ❌ 非網頁應用程式 · ❌ 捕捉應用程式本身的聲音 (Playwright 不錄製瀏覽器音訊)
流程
- 首先確保確定性狀態。 影片執行真實操作 (登入、點擊、資料庫寫入)。在錄製前,確保具備冪等的種子/示範資料和專用帳號。以生產模式執行伺服器 (
build && start) 或在開發模式下預先暖機路由——惰性編譯會在影片中顯示為白畫面。 - 先編寫腳本,再開始編碼。 一個四幕簡報架構:願景 (開場) → 運作方式 (差異化之處、內部機制) → 終端使用者體驗 → 證明/結果 (呼應願景作結)。每個場景 = 1 個論點 + 1 個字幕 (強而有力的標題 + 解釋性副文本)。目標:總長 60–120 秒,每個關鍵畫面停留 3–5 秒。
- 改編範本 — 內建輔助功能,可處理字幕、亮點、登入、節奏控制和轉換。使用專案的品牌顏色顯示字幕。
- 錄製,並將選擇器失敗視為腳本有問題 (修正它,而非繞過它)。
- 驗證影片 — 強制執行。 檢查時長和場景:
只有在檢查畫面後才能交付。如果某個場景失敗,請重新錄製。ffprobe -v error -show_entries format=duration -of csv=p=0 demo.mp4 # 為每個場景擷取一個畫面並檢查每個畫面 (字幕正確?畫面正確?有無破損?) ffmpeg -y -ss <t> -i demo.mp4 -frames:v 1 -vf scale=800:-1 frame_<t>.png - 交付
.mp4(可在 PowerPoint/Slack/WhatsApp 中使用) 以及.webm。保留一個 npm 腳本 (demo:record) 並將輸出檔案加入.gitignore(因為這些檔案是可以重新生成的)。
旁白模式 (audio)
流程與上述相同,但有以下差異:
- 先決條件:
uv和ffmpeg須在 PATH 環境變數中 (uv --version、ffmpeg -version)。將narrate.py複製到與錄製腳本相同的資料夾中。首次執行會下載 Kokoro 模型 (~120 MB,快取在~/.cache/recording-demo-videos中)。 - 節奏由音訊決定。
SCRIPT中的每個場景都有caption(畫面) +say(語音,1–2 句話,帶有語氣)。await narrate(page, "id")會顯示字幕、播放語音並等待其結束——在語音場景中請勿使用固定的pause()。在互動期間進行旁白:narrate(page, id, { wait: false });下一個narrate()會等待前一個語音播放完畢(不會重疊)。 - 語言/語音透過環境變數設定:
DEMO_LANG=en|pt、DEMO_TTS=auto|kokoro|edge、DEMO_VOICE=<voice>(Kokoro:af_heart、am_michael、bf_emma、pf_dora、pm_alex;edge:en-US-AvaMultilingualNeural、pt-BR-FranciscaNeural……)。kokoro= 離線、Apache-2.0 授權、英文預設;其葡萄牙語明顯較不自然。edge= 葡萄牙語預設、語音品質最佳,但需透過非官方的 Microsoft 端點線上使用——適合內部演示;商業使用請優先選擇kokoro或官方 TTS。 - 同步是自動的: 範本以一個洋紅色閃爍開始 (
syncMarker),測量實際影片開始延遲並修剪掉閃爍畫面。請將syncMarker保留為第一個動作;如果日誌顯示「Sync marker not found」,則語音將會不同步——請檢查syncMarker是否為第一個動作,且在前一秒內沒有任何東西遮住畫面,然後重新錄製。 - 輸出:
demo.mp4(旁白版——交付物)、demo.srt、timeline.json、demo.raw.webm(原始、無聲)、audio/(快取:重新錄製時只會重新合成已變更的行)。 - 額外驗證 (強制執行): 除了檢查畫面外,請確認語音落在正確的位置:
ffprobe -v error -show_entries stream=codec_type,duration -of csv=p=0 demo.mp4 # 必須同時包含影片和音訊 ffmpeg -i demo.mp4 -af silencedetect=n=-45dB:d=0.6 -f null - 2>&1 | grep silence_end # 每個 silence_end 應約等於 timeline.json 中某個場景的 atVideo (±0.2 秒);在該時間點擷取畫面並檢查字幕
常見陷阱 (經驗教訓)
| 陷阱 | 解決方式 |
|---|---|
| 影片檔名隨機 | 在關閉 page 之前擷取 page.video();在 context.close() 之後使用 await video.path();重新命名 |
| 導航後字幕消失 | 每次 goto 後重新注入字幕 (caption() 輔助函式),或使用 addInitScript + sessionStorage |
| 影片對人類來說太快 | slowMo: 100–150 + 每個場景明確暫停 3–5 秒 + 可見打字使用 pressSequentially({ delay: 40–60 }) |
| mp4 無法在 PowerPoint/播放器中開啟 | ffmpeg -c:v libx264 -pix_fmt yuv420p |
| 影片較小/被裁切 | recordVideo.size 必須等於 viewport |
| 影片中出現白畫面/待處理畫面 | 動作後使用 waitUntil: "networkidle" + waitForURL;在開發模式下預先暖機路由 |
| 觀看者不知道該看哪裡 | 在點擊前對元素使用琥珀色高亮 (box-shadow),或注入假游標 |
| 重新錄製導致資料重複 | 使用冪等動作,或可容忍重複執行的種子資料 (帶後綴的 slug、upsert) |
| 切換使用者身分時登入狀態洩漏 | 在切換使用者之間使用 context.clearCookies() |
| (旁白模式) 語音與畫面不同步 | Playwright 的影片會在頁面載入後 0.2–1.5 秒才開始 (每次執行/版本可能不同) —— 請使用範本的 syncMarker,切勿使用固定偏移量 |
| (旁白模式) 語音被切斷或場景倉促 | 對語音場景使用固定的 pause() —— 請改用 narrate(),它會等待語音播放完畢 |
| (旁白模式) 縮寫/品牌名稱發音錯誤 | 在 say 中採用音標拼寫 (例如「S Q L」或「sequel」);字幕保持正確 |
常見錯誤
- 跳過畫面驗證(「執行沒有錯誤」≠「影片沒問題」)—— 一定要檢查。
- 字幕描述 UI(「登入畫面」)而非敘述論點(「團隊登入——精細的角色控制」)。
- 沒有書面腳本就開始錄製:結果是一個冗長且沒有故事的螢幕錄影。
- 將真實憑證寫死在程式中——請使用示範/測試帳號,若需敏感資料則透過環境變數注入。