Communitygithub.com

展示與解說

當使用者想要建立一個有品牌標示的旁白演示影片,介紹任何網站時使用。負責網站探索、腳本草稿撰寫(讓使用者以通俗語言審閱)、透過 Open AI 進行文字轉語音旁白、Playwright 錄製、音訊/視訊混流、速度調整、品牌疊加,以及(第二階段)開場/結尾/字幕。最終產出高品質的 mp4 檔案。觸發詞如「製作一個關於……的影片」等。

展示與解說 是什麼?

此技能會將任何網站、一個標誌與一些使用意圖,自動轉化為一段約 5 分鐘、有旁白且具有品牌風格的示範影片。它引導使用者依序完成:需求訪談以收集網站 URL、意圖、目標受眾與品牌資產;透過 Playwright(無須驗證時)或儲存狀態檔案(用於 OAuth 場景)探索網站頁面;產生一份包含 15 至 30 個分鏡的腳本,每個分鏡包含一項動作與對應的旁白;然後使用 Open AI 的 TTS 引擎生成旁白音訊,並以調整後的速度(例如 1.2 倍速)錄製瀏覽器互動過程。最後,它會將音訊與視訊混合,加上品牌疊加,並輸出一個可隨時發布的 mp4 檔案。此技能支援 Claude Code CLI 與 Cowork 兩種環境,並會自動偵測以使用適當的工具(例如 Playwright MCP、Chrome MCP 或無頭瀏覽器探索)。在 Claude Code CLI 中,它會在本機執行指令;在 Cowork 中,則會使用 MCP 工具來處理較長的操作。此技能嚴格要求使用者提供明確的意圖與至少一個標誌,才能開始製作影片,確保輸出的品質。

相容平台✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/carveragents/show-n-tell/tree/main/skills/show-n-tell

在你喜歡的 AI 中提問

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

說明文件

展示與解說 是做什麼的?

你負責協調一個完整的流程,將任何網站、一個標誌以及一些使用意圖,轉化為一段 5 分鐘、有旁白且具有品牌風格的示範影片。scripts/ 目錄中的腳本只是單純的管道;你才是指揮者。

此資料夾中的參考文件:docs/SCHEMAS.md(YAML 與動作文法)、docs/GOTCHAS.md(已知問題與解決方法)、docs/CONTEXT.md(「什麼是好的輸出」)、examples/halyard-spme/(完整的標準範例)。請在需要時閱讀這些文件 — 不要預先載入它們。

何時使用此技能

  • 使用者想要一個網站的旁白示範影片(包含線上、本機開發或靜態網站)。
  • 使用者至少有一些意圖指引(「展示 X、Y、Z」/「示範儀表板流程」)。
  • 使用者有標誌或文字商標可以使用。

如果使用者沒有提供意圖筆記或標誌,請拒絕繼續進行。 使用預設品牌的通用示範影片是不好的示範。請要求使用者提供指引,而不是默默地產出品質不佳的影片。

環境偵測(開始前請先閱讀)

在執行任何操作之前,請先判斷 Claude 正在哪個環境中執行:

  • Cowork:mcp__cowork__list_artifacts 和 mcp__computer-use__screenshot 在 Claude 的工具清單中可用。
  • Claude Code CLI:這些工具不存在。

這點很重要,因為許多階段在不同環境中會有不同的行為。快速參考:

階段Claude Code CLICowork
工作目錄(階段 5)~/demo-videos/<縮寫名稱>/request_cowork_directory 輸出路徑
公開網站探索(階段 2b)Playwright MCP 工具Chrome MCP 工具或無頭模式的 explore_page.py
驗證擷取 OAuth(階段 2a)透過 Bash 執行 capture_auth.py使用者在本機執行 capture_auth.py
長時間指令(階段 7–9)同步執行nohup + 輪詢(45 秒 Bash 逾時)
交接(階段 11)回報 mp4 路徑mp4 路徑 + computer:// 連結

階段 1 — 訪談(收集輸入)

一次只問一兩個問題,不要全部同時問。必問項目:

  1. 目標 URL — 確認可以連線。
  2. 示範意圖筆記 — 要講述什麼故事?哪些功能很重要?
  3. 觀眾與語氣 — 內部/外部/投資者;說明性/銷售性/技術性/休閒性。
  4. 目標長度 — 預設 5 分鐘。
  5. 標誌 — URL 或路徑。如果只有純文字可用,請標示此限制但接受。
  6. 品牌顏色 — 主要顏色(墨水色)+ 強調色。如果未指定,使用 PIL 從標誌推斷。
  7. 需要驗證? — 網站是否需要登入?
    • 不需要 → 繼續進行。
    • 需要,表單式(網站有自己控制的電子郵件/密碼欄位)→ 在 demo_config.yaml 中使用 session.pre_session。收集憑證環境變數名稱(不是實際值)以及登入 URL/選擇器。告訴使用者他們必須在執行前將實際憑證放在 <工作目錄>/.env 中,絕對不要在聊天中提供。請參閱 examples/login-flow/。
    • 需要,OAuth / SSO / 魔法連結 / 通行金鑰(Google、Microsoft、Okta 等)→ 使用 session.storage_state。使用者不需要執行任何指令。由你為他們在階段 2a 中啟動 helpers/capture_auth.py,並且他們只需要在開啟的瀏覽器視窗中互動式地登入。擷取到的 auth.json 隨後將同時用於階段 2b 的探索和階段 8 的錄製。請參閱 examples/oauth-storage-state/。

階段 2a — 驗證擷取(僅限 OAuth)

如果階段 1 的問題 7 確定為「無需驗證」或「表單式」,則完全跳過此階段。對於 OAuth / SSO / 魔法連結 / 通行金鑰,請在現在、網站探索之前就擷取已驗證的會話 — 階段 2b 需要它來檢視已驗證的頁面。

mkdir -p ~/demo-videos/<demo-縮寫名稱>/
uv run helpers/capture_auth.py <登入或起始 URL> \
  --out ~/demo-videos/<demo-縮寫名稱>/auth.json \
  --viewport <recording.viewport 來自 demo_config.yaml;預設 1440x900>

透過 Bash 工具執行此指令,設定 timeout: 600000(10 分鐘 — 最大值)。此腳本會開啟一個有頭 Chromium 視窗。用通俗的語言告訴使用者:

「我正在為你開啟一個瀏覽器視窗進行登入。完成登入(Google、Microsoft 等,處理雙重驗證),導航到你希望錄製開始的頁面,然後關閉瀏覽器視窗。我會儲存會話並自動繼續。」

此腳本會以原子操作方式寫入 auth.json,權限設為 0600。如果使用者花費超過 10 分鐘(雖然罕見,但如果在另一個房間使用手機進行雙重驗證則可能發生),Bash 逾時會觸發 — 只需重新執行相同的指令。

--viewport 必須與 demo_config.yaml 中的 recording.viewport 相符。某些網站會指紋識別視窗大小;不符可能會在錄製時間或探索時間使擷取的會話失效。

如果 Playwright 的 Chromium 尚未安裝(剛複製技能),腳本會顯示可操作的錯誤。執行一次 uv run --with playwright playwright install chromium。

如果在 Claude Code CLI 中執行: 按上述方法透過 Bash 執行 capture_auth.py。

如果在 Cowork 中執行: Claude 會直接使用 computer-use 和 Chrome 工具處理 — 使用者只需要在瀏覽器開啟時登入。步驟如下:

  1. 確保已知工作目錄路徑。 如果階段 5 尚未執行,請立即呼叫 mcp__cowork__request_cowork_directory 以取得輸出路徑,並將 <工作目錄> 設定為 <輸出路徑>/<demo-縮寫名稱>/。

  2. 在使用者的桌面上開啟 Chrome:

    mcp__computer-use__open_application  →  "Google Chrome"  (或 "Chrome")
    
  3. 導航到登入 URL。 如果已連線,優先使用 Chrome MCP:

    • Chrome 擴充功能可用:mcp__Claude_in_Chrome__navigate 到 <登入或起始 URL>
    • Chrome 擴充功能未連線:使用 mcp__computer-use__* 工具點擊網址列並輸入 URL
  4. 告訴使用者登入 — 用通俗的語言說:

    「Chrome 已在登入頁面開啟。請登入(處理任何雙重驗證、SSO 等),然後導航到應該開始錄製的頁面。完成後請告訴我。」

  5. 等待並觀察。 每約 15 秒使用 mcp__computer-use__screenshot 輪詢。當 URL 不再是登入/驗證頁面,且看到儀表板或應用程式頁面時繼續。

  6. 透過 JavaScript 擷取會話狀態。 使用 mcp__Claude_in_Chrome__javascript_tool 執行此片段:

    (() => {
      const cookies = document.cookie.split(';').map(c => {
        const [name, ...rest] = c.trim().split('=');
        return { name: name.trim(), value: rest.join('='), domain: location.hostname,
                 path: '/', expires: -1, httpOnly: false, secure: location.protocol === 'https:',
                 sameSite: 'Lax' };
      }).filter(c => c.name);
      const ls = {};
      for (let i = 0; i < localStorage.length; i++) {
        const k = localStorage.key(i);
        ls[k] = localStorage.getItem(k);
      }
      const ss = {};
      for (let i = 0; i < sessionStorage.length; i++) {
        const k = sessionStorage.key(i);
        ss[k] = sessionStorage.getItem(k);
      }
      return JSON.stringify({
        cookies,
        origins: [{ origin: location.origin,
                    localStorage: Object.entries(ls).map(([n,v]) => ({name:n,value:v})),
                    sessionStorage: Object.entries(ss).map(([n,v]) => ({name:n,value:v})) }]
      }, null, 2);
    })()
    
  7. 使用 Write 工具將結果寫入 <工作目錄>/auth.json。這是有效的 Playwright storage_state 格式 — helpers/explore_page.py 和 record_demo.py 都透過 browser.new_context(storage_state=…) 使用它。

  8. HttpOnly Cookie 注意事項。 JavaScript 無法讀取 HttpOnly cookie — 它們對 document.cookie 來說是故意不可見的。如果網站的會話 Token 僅為 HttpOnly(在較舊的 Rails/Django 會話 cookie 中常見),則擷取的狀態將會缺少它。告訴使用者:

    「注意:標記為 HttpOnly 的會話 cookie 無法從 JavaScript 存取,因此我可能沒有擷取到所有驗證 Token。錄製時會嘗試使用已擷取的內容 — 如果階段 8 期間遇到登入牆,我們可以回退到在本機使用 capture_auth.py。」 然後繼續 — 許多現代網站(Google、Microsoft、Okta)會在非 HttpOnly cookie 或 localStorage 中保留足夠的狀態,讓 Playwright 可以運作。

階段 2b — 網站探索

如果階段 2a 已執行(auth.json 存在),請使用 helpers/explore_page.py 來檢視已驗證的頁面 — Playwright MCP 無法載入 storage_state,只會看到登入牆。對於無需驗證的示範,Playwright MCP 就很好用且更具互動性;請像以前一樣使用它。

對於需要驗證的頁面:

mkdir -p ~/demo-videos/<demo-縮寫名稱>/_explore/
uv run helpers/explore_page.py https://target.example.com/dashboard \
  --storage-state ~/demo-videos/<demo-縮寫名稱>/auth.json \
  --out-dir ~/demo-videos/<demo-縮寫名稱>/_explore/

這會為每個頁面在 _explore/ 目錄中寫入三個檔案:<縮寫名稱>.png(螢幕截圖)、<縮寫名稱>.dom.html(用於選擇器選取的 DOM)、<縮寫名稱>.meta.json(包含 {url_requested、final_url、title、status})。使用 Read 工具讀取 PNG 以查看頁面;對 DOM 進行 grep 以尋找選擇器。如果 meta.json 中的 final_url 指向一個登入頁面,表示會話已過期 — 請重新執行階段 2a。

對於公開頁面(任何示範的登陸頁面、行銷頁面;無需驗證示範的所有內容)— 像以前一樣使用 Playwright MCP 工具(mcp__plugin_playwright_playwright__*):

  • 使用 browser_navigate 導航到目標 URL,然後導航到使用者意圖提到的 2–5 個頁面。
  • 使用 browser_snapshot 或 browser_take_screenshot 查看每個頁面的版面。
  • 使用 browser_evaluate 讀取 DOM 以取得穩定的選擇器(盡可能偏好語意化選擇器而非 nth-of-type)。

如果在 Claude Code CLI 中執行: 按上述方法使用 mcp__plugin_playwright_playwright__* 工具。

如果在 Cowork 中執行: 首先確保 Chromium 可用:

uv run --with playwright playwright install chromium

然後選擇最佳可用方法:

  • 如果 mcp__Claude_in_Chrome__navigate 可用(Chrome 擴充功能已連線),使用 mcp__Claude_in_Chrome__navigate + mcp__Claude_in_Chrome__read_page 來互動式探索網站。
  • 否則回退到無頭探索:
    mkdir -p <工作目錄>/_explore/
    uv run helpers/explore_page.py <url> --out-dir <工作目錄>/_explore/
    
    (公開頁面不需要 --storage-state — 此參數現在是選填的。)

針對每個重要頁面記錄:

  • 值得示範的時刻(捲動到功能、點擊以查看詳細資訊、懸停工具提示)。
  • 需要的網站適應調整:固定標頭技巧?PDF 深層連結?模態框阻塞?驗證牆?
  • 看起來脆弱且可能需要 wait_for_selector 防禦機制的選擇器。

不要窮舉爬取。每個頁面 2–5 個動作就足夠了。

階段 3 — 草稿 storyboard.yaml

產生 15–30 個分鏡。每個分鏡 = 一個攝影機動作 + 1–3 句旁白。請參閱 docs/SCHEMAS.md 的動作文法(階段 A 子集:goto、goto_and_scroll、scroll_into_view、scroll_y、hover、click)。

5 分鐘影片在 1.2 倍速下的目標:

  • 加速後總時長:約 5:00
  • 原始總執行時間:約 6:00
  • 每個分鏡平均:約 12 秒,其中約 9–10 秒是旁白

撰寫旁白時的硬性規則:

  1. 每個事實性陳述必須在此分鏡的畫面上可見。 不要編造數字(例如「代理程式標記了 199 個變更」)。如果你在螢幕截圖上沒看到,就不要說。
  2. 需要逐字母閱讀的縮寫必須以連字號書寫: S-P-M-E、K-Y-B、A-P-I。TTS 提示會強制執行此慣例。
  3. 長度要與視覺內容相符: 捲動分鏡 8–18 秒,點擊分鏡 6–12 秒。
  4. 語氣要與 branding.yaml 的 voice.tone 欄位相符。

在腦中將分鏡分組為段落(概述 / 功能 A / 功能 B / 結尾),但在 YAML 中寫成平面列表 — 不要有章節標記。

階段 4 — 以通俗英語審閱

使用者不會直接編輯 YAML。 你將草稿以編號列表的形式呈現,並接受自然語言的回饋。請使用此確切格式:

這是我草擬的示範流程。預計時長:5:08(1.2 倍加速後)。
告訴我您想更改什麼。

概述(60 秒)
1. 抵達首頁(10 秒)—「歡迎使用 Acme Cloud,一個專為小型團隊打造的無伺服器平台...」
2. 捲動到功能區(15 秒)—「三個核心功能為平台提供動力...」
3. 捲動到輸出區(8 秒)—「這十個政策領域...」

功能 1 — 儀表板(45 秒)
4. 導航到儀表板(8 秒)—「點擊進入儀表板...」
5. 懸停在即時活動饋送(12 秒)—「每個專案都顯示即時活動饋送...」
...

結尾(20 秒)
27. 回到首頁統計資料(12 秒)—「團隊選擇 Acme 的三個原因...」
28. 結尾(8 秒)

然後:「有什麼要新增、刪除或重新排序的嗎?旁白語氣需要調整嗎?有什麼要跳過的嗎?」

將自然語言的回饋轉換為 YAML 編輯:

  • 「跳過分鏡 7」→ 從 YAML 中移除
  • 「將分鏡 3 加長」→ 用更多畫面上的細節擴充旁白(如果加長很多,則拆分為兩個分鏡)
  • 「在某處提到定價」→ 找出正確的分鏡並加入一句話(確認定價確實在此分鏡的畫面上可見)
  • 「語氣太正式」→ 用更輕鬆的措辭重寫旁白
  • 「顯示團隊頁面而不是關於頁面」→ 交換 URL 並調整旁白

重新呈現更新後的流程。反覆迭代,直到使用者明確批准。

在 TTS 之前進行執行時間漂移檢查: 將所有分鏡的 len(beat.narration) / 16(以 140wpm 的速度,字元/秒)相加。如果 估計值 * (1 / 速度倍數) 與目標相差超過 30 秒,請提出:「目前加速後的時長約為 6:20,與您 5 分鐘的目標不符。需要我修剪嗎?」

階段 5 — 工作目錄設定

mkdir -p ~/demo-videos/<demo-縮寫名稱>/_assets
cp <標誌路徑>             ~/demo-videos/<demo-縮寫名稱>/_assets/<logo>.png
# 從您的草稿寫入 storyboard.yaml、branding.yaml、demo_config.yaml

如果在 Claude Code CLI 中執行: 按上述方法使用 ~/demo-videos/<demo-縮寫名稱>/。

如果在 Cowork 中執行: 呼叫 mcp__cowork__request_cowork_directory 以取得使用者的輸出路徑。將工作目錄設定為 <輸出路徑>/<demo-縮寫名稱>/。在階段 6–11 的所有後續檔案寫入中,均使用此路徑 — 現在就儲存它並在整個會話期間保持一致。在此路徑下建立 _assets/ 子目錄,而不是在 ~/demo-videos/ 下。

如果使用者磁碟上沒有標誌檔案,只有 URL,請使用 curl 下載並將其放在 _assets/ 中。

相關技能