Community程式設計與開發github.com

VirtualPirate/create-product-demo-video-skill

Claude Code 技能:在你的網頁應用程式中錄製真實使用者流程的產品展示影片 — 從實際 UI 轉錄,並使用 Playwright 和 ffmpeg 錄製成 mp4/gif。

create-product-demo-video-skill 是什麼?

這個技能讓 AI 代理(如 Claude Code)能夠自動為網頁應用程式建立產品展示影片。它會根據使用者描述的流程,分析應用程式的真實路由和 UI 元件,然後逐幀重現每個螢幕畫面,確保完全忠於原始設計。技能依賴 Playwright 進行瀏覽器自動化,ffmpeg 進行影片編碼,並支援多種字幕樣式(pill、lower-third、rail、coach)和可選的背景音樂。最終輸出一個包含所有互動過程的 mp4 或 gif 檔案,存放於 `demo/vN/` 目錄下,並附帶詳細的 README 文件說明場景對應的路由和資源映射。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/VirtualPirate/create-product-demo-video-skill/tree/main/skills/create-product-demo-video

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

建立使用者所描述流程的展示影片。輸出結果會放置在一個新的 demo/vN/ 資料夾中。

最重要的規則:每個畫面都必須是真實 UI 的轉錄,而不是憑空想像。 一個憑空發明版面、文案或元件的展示影片,比沒有展示更糟糕——它會讓觀看者學到一個不存在的產品。在為任何畫面撰寫標記之前,請先閱讀每個畫面的原始碼。

輸入

/create-product-demo-video <應該發生什麼> — 一個流程描述。如果描述很模糊(例如「展示產品」),請選擇最狹義、最終能產生可見價值的完整流程,用一句話說明你選擇了哪個流程,然後開始建構。不要因為提問而停頓。

步驟

  1. 將流程映射到路由。 將提示轉換為使用者實際會經過的、有序的實際路由列表。首先找到路由器——一個 routes/ 目錄、一個 app/ 樹、一個 <Routes> 區塊、或一個路由清單 — 並僅列出確實存在的路徑。如果流程需要一個必須先建立才能存在於後續畫面的實體(例如,在建立專案之前無法顯示專案範圍的報表),請包含該建立畫面或選擇一個不需要它的範圍——不要默默地跳過一個必要的步驟。

  2. 讀取每個畫面的原始碼。 對於每個路由:路由檔案、它渲染的元件、應用程式的共享佈局元件(殼層、頁面標頭、空狀態),以及它的設計系統基礎元件(components/ui/ 或它們所在的位置)。也要讀取任何產生展示中顯示的字串的東西——預覽輔助函式、衍生名稱、後端渲染/模板服務。逐字複製字串;不要改寫產品文案。

  3. 建立 Scaffold。 mkdir -p demo/vN(使用下一個未使用的 N — 切勿覆蓋現有的 vN),然後複製 assets/skeleton.html → demo/vN/index.html 和 assets/record.mjs → demo/vN/record.mjs。assets/ 位於此 SKILL.md 旁邊,也就是技能安裝的位置 — 可能是外掛快取目錄、~/.claude/skills/ 或專案的 .claude/skills/。請從技能自己的目錄解析它,絕不要從正在被展示的儲存庫解析。骨架包含一個預留位置的殼層、一個記號比例尺和播放引擎。 對於有配樂的展示,也要複製從 assets/music/ 中選擇的曲目 → demo/vN/music.mp3 — 請參閱音樂。將其複製進來(而不是引用技能資料夾)是為了讓 vN/ 日後可以重新錄製,這也是 record.mjs 每個版本都要複製的原因。

  4. 將骨架調整成符合此產品。 所有標記為 REPLACE: 的都是預留位置,在編寫任何場景之前都必須替換,因為每個畫面都會繼承它們:

    在 index.html 中替換為
    PRODUCT應用程式的名稱、其網址列顯示的主機名稱,以及其真實的 logo svg
    NAV從真實導覽列抄錄的側邊欄 — 相同的區段、順序和標籤
    TOPBAR真實的頂部工具列;刪除應用程式沒有的控制項
    :root tokens來自應用程式樣式表的 :root 區塊,以確保顏色/圓角/字型相符
    ICONS來自應用程式實際使用圖示集的 path 資料
    刪除流程中不會用到的選擇性 CSS 區塊(第三方畫面、傳遞面板)。
  5. 編寫場景。 每個畫面一個 <section class="scene" data-scene="N">,按順序排列。重用骨架的 CSS class(.pagehead、.card、.btn、.seg、.opt、.chip、.scopeid、.statusbadge、.empty、.input、.pillbar、.toast)— 它們的形狀類似於 Tailwind/shadcn 風格系統的輸出,因此請根據實際元件的 class 逐一檢查並調整,而不是直接假設。僅在骨架缺少某個元件時才添加新的 CSS,並從該元件的實際 class 中衍生。

  6. 編寫 play()。 標題卡片 → 畫面 → 結尾。使用字幕來命名每個步驟,並在腳本頂部設定 CAPTIONS — 包括樣式,以及 steps = 執行中 say() 呼叫的次數。互動需透過指標輔助函式進行,以便觀看者能夠追蹤正在點擊的內容。

  7. 錄製。 node demo/vN/record.mjs → demo/vN/out/product-demo.mp4。加上 --gif 可產生 900px 的 gif 檔案。demo/vN/music.* 檔案會被自動偵測使用;--music <path> 指定其他位置的檔案,--music-db <n> 調整音量水準,--no-music 則強制靜音。

  8. 透過檢視來驗證。 提取影格並讀取圖片 — 這是非做不可的步驟,因為這樣才能發現版面錯誤:

    for t in 5 12 20 28 36 44; do ffmpeg -y -loglevel error -ss $t \
      -i demo/vN/out/product-demo.mp4 -frames:v 1 /tmp/f$t.png; done
    

    檢查:沒有過大的圖示、沒有被折疊裁剪的內容、指標確實落在它宣稱要點擊的元件上、文字沒有被壓縮成一行。修正並重新錄製,直到乾淨為止。

    影格無法顯示音訊。 在配樂展示中,也要檢查串流和淡入淡出 — volumedetect 會在 info 層級記錄,因此 -v error 會吞掉它的輸出:

    ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,duration \
      -of default=nw=1 demo/vN/out/product-demo.mp4
    for w in "-ss 0 -t 0.25" "-ss 12 -t 0.5" "-sseof -0.25"; do \
      ffmpeg -hide_banner -nostats $w -i demo/vN/out/product-demo.mp4 \
        -af volumedetect -f null - 2>&1 | grep mean_volume; done
    

    預期會有一個 aac 串流,其長度與影片長度相差在 ~0.05s 內,max_volume 低於 0 dB,並且開頭和結尾的平均音量遠低於中間部分——這是由淡入淡出證明它已執行的跡象。

  9. 編寫 demo/vN/README.md — 包含場景表與路由、原始碼檔案對應、時長、錄製此版本時所使用的 CAPTIONS 樣式和音樂曲目,以及流程刻意跳過的內容。更新 demo/README.md 以列出新版本。

回報路徑、時長和大小,然後開啟 mp4 檔案以便使用者觀看 — macOS 上使用 open,Linux 上使用 xdg-open,Windows 上使用 start。

引擎 API

可在 play() 內部使用:

呼叫效果
scene(n)淡入淡出至場景 n,從 URLS 更新網址列
tap(sel, ms)移動指標到元件並點擊它(漣漪效果 + 按下)
moveTo(sel, ms) / click(sel)當你需要在兩者之間改變狀態時的兩個拆分動作
hideCursor() / place(x, y, 0)進入場景時重置指標位置
say(text, opts?) / hush()字幕淡入/淡出。{ at: sel } 會將 coach 字幕錨定到該元件;{ step: n } 強制指定索引
type(el, text, ms)逐字輸入文字到一個 <span> 中
wait(ms)維持目前畫面
reveal(el)由 moveTo 自動呼叫 — 平滑滾動 .main 區域,使摺疊線以下的目標可見

在結尾設定 window.__demoDone = true(骨架已內建此功能)— 錄製器會等待此變數。

字幕設計

const CAPTIONS = { style: 'pill', steps: 6 } 與 URLS 一起位於引擎頂部。四種樣式都內建在骨架中;無論選擇哪一種,say() 的呼叫方式都相同。請根據影片選擇:

style這是什麼何時選擇它
pill (預設)墨水膠囊,底部置中任何簡短且面向行銷的內容。遮擋最少,每個字幕約 10 個單詞。
lower-third左對齊區塊,帶有步驟索引和進度條較長的流程,希望觀看者能感受到序列感;在 gif 中最清晰易讀。
rail視窗下方 68px 的長條,帶有章節點文件和支援剪輯,確保不覆蓋任何內容。會佔用應用程式高度—請見下方說明。
coach提示框錨定到播放中的元件,其餘部分變暗跟著操作的逐步教學。每個字幕都需要 { at: sel };沒有的會退回使用 pill 樣式。

steps 驅動索引、進度條和 rail 的點—計算 say() 的呼叫次數並設定它,否則播放結束時會顯示 05 / 06。不確定要選哪個樣式?在瀏覽器中打開 index.html 並切換 CAPTIONS.style—頁面會按 R 鍵重播,因此無需錄製即可比較所有四種樣式。

音樂

可選,並且預設為關閉,除非有曲目存在。背景音樂在編碼時混入—Playwright 完全不會捕捉音訊,因此它完全不影響展示頁面或引擎。

node demo/vN/record.mjs                      # 使用 demo/vN/music.*(如果存在),否則靜音
node demo/vN/record.mjs --music ~/beds/x.mp3  # 明確指定的路徑優先於同目錄下的檔案
node demo/vN/record.mjs --music-db -4        # 更安靜的背景音樂
node demo/vN/record.mjs --no-music           # 即使有同目錄的曲目也保持靜音
  • 捆綁的曲目位於 assets/music/ 中,每個檔案對應其 LICENSES.md 中的一行。沒有曲目會在沒有可驗證的 CC0/CC-BY 授權條款的情況下發布—未經授權的 mp3 是每個安裝此技能的人的問題,而不只是你的問題。不確定?將它留在儲存庫外,並傳遞 --music <path>。
  • 音量是標準化的,而不是設定的。 每首曲目都會被驅動至 −18 LUFS,並帶有 −1.5 dB 的真實峰值限制,因此不同版本之間互換背景音樂時,音量會自動匹配,無需手動調整。--music-db 會偏移該目標值;它不會在之上增加增益。
  • 淡入淡出是自動的 — 入場 1.5 秒,退場 2.5 秒,退場時間根據實際影片時長計算。
  • 選擇比影片長的曲目。 任何更短的曲目都會被循環播放,並且接縫處會很明顯;錄製器在必要時會發出警告。60 秒以上通常足以應付一般的 40–60 秒展示。
  • 沒有人聲,沒有突然的節奏變化。 觀看者同時在閱讀字幕和 UI 文案。
  • 音訊僅會加入 mp4 檔案。 webm 是原始的無聲捕捉,而 gif 根本沒有音軌—僅音樂的變更在 --gif 輸出中是看不見的。

慣例

  • 舞台是一個固定的 1280×800 模擬瀏覽器;其中 44px 是瀏覽器 chrome,為應用程式留下 1280×756 的空間。骨架附帶了一個 48

相關技能