Community程式設計與開發github.com

piyush140104/screen-record-skills

Claude Code 技能:製作腳本化瀏覽器逐步操作影片,搭配 ElevenLabs 語音旁白、背景音樂、點擊音效與內嵌字幕。

screen-record-skills 是什麼?

這項技能讓 AI 代理能夠根據使用者腳本,自動生成具有旁白、背景音樂、滑鼠點擊音效及內嵌字幕的瀏覽器操作流程影片。它透過 Node.js 引擎整合 ElevenLabs 文字轉語音 (TTS)、ffmpeg 音訊處理,以及無頭 Chromium 瀏覽器的影片錄製,最終輸出 H.264 編碼的 MP4 與 WebM 影片檔,同時提供 SRT 與 ASS 字幕檔。使用者需提供 ElevenLabs API 金鑰,技能預設使用 Liam 等免費語音;若需 Charlotte、Rachel 等付費語音,則需 ElevenLabs 的付費方案。此技能非常適合製作 LinkedIn、Twitter 或產品銷售簡報用的產品展示影片。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add piyush140104/screen-record-skills

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

在你喜歡的 AI 中提問

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

說明文件

/screen-record — 腳本化瀏覽器逐步操作影片

使用時機

使用者想要一個網站在執行某項操作的精美影片 — 通常用於 LinkedIn、Twitter、銷售簡報、投資人更新或入門文件。他們描述螢幕上應該出現什麼、游標應該怎麼做、以及旁白大致要說什麼。你負責編寫腳本;引擎會處理游標動畫、透過 ElevenLabs 進行文字轉語音 (TTS)、背景音樂、點擊音效以及字幕內嵌。

請不要使用此技能來處理:已經在進行的真實螢幕錄影(請使用 macOS 截圖或 QuickTime)、GIF(請使用 GIF 工具)、或需要真人配音的影片(你仍然可以編寫腳本,然後請他們重新錄製)。

運作方式

引擎位於 engine.mjs。它匯出 runDemo(config) 函數,其功能如下:

  1. 透過 ElevenLabs 為每個提示 (cue) 生成一個 TTS 音檔。
  2. 使用 ffmpeg 生成柔和的背景音樂音軌與一個 UI 點擊音效。
  3. 以 1920×1080 解析度啟動無頭 Chromium,並錄製影片。
  4. 執行你的 scenes(helpers) 函數來驅動瀏覽器。
  5. 混合音訊(旁白大聲 + 音樂小聲 + 點擊聲輕柔)並燒錄 ASS 格式的字幕。
  6. 回傳最終 .mp4、.webm、.srt、.ass 檔案的路徑。

工作流程

步驟 1 — 閱讀使用者的請求

明確下列資訊:要錄製的 URL、流程(游標應該做什麼)、語氣(正式/隨意)、長度目標。如果有任何遺漏,請提出一個明確的問題,而不是猜測。

步驟 2 — 檢查 API 金鑰

依照此順序尋找 ELEVENLABS_API_KEY:

  1. $CLAUDE_PLUGIN_ROOT/.env.local(或技能資料夾本身的 .env.local)
  2. 當前專案的 .env.local
  3. process.env

如果找不到,請告訴使用者:

我需要一個 ElevenLabs API 金鑰。請到 https://elevenlabs.io/app/settings/api-keys 免費申請(每月 10,000 字元,大約可製作 15 個示範)。您可以在對話中貼上金鑰,我會將其儲存到技能的 .env.local,或者您也可以自行新增。

如果金鑰存在,但引擎拋出 ApiKeyDeadError(HTTP 401/402/403),請告訴使用者:

您的 ElevenLabs 金鑰被拒絕了(可能已撤銷、過期或額度用盡)。請到 https://elevenlabs.io/app/settings/api-keys 輪換金鑰,然後更新 .env.local。在您完成之前,我不會重試。

請勿默默重試,除非使用者明確要求,否則不要回退到 macOS 的 say 指令。

步驟 3 — 選擇語音

預設是 Liam (TX3LPaxmHKxFdv7VOQHJ) — 充滿活力的美國男性,現代感。比 George(英國)和 Sarah(美國女性)更輕快。其他免費語音可在 engine.mjs 中的 FREE_TIER_VOICES 下找到。如果使用者說「使用 X 語音」,請在目錄中找到它。如果他們說「低沉/厚重/輕柔/溫暖/女聲」,請據此選擇。

資料庫語音(如 Charlotte、Rachel、Adam 等)需要付費的 ElevenLabs 訂閱。如果使用者要求使用此類語音但他們使用的是免費方案,你會收到 HTTP 402 錯誤 — 此時請回退到最接近的免費語音並告知使用者。

步驟 4 — 探查目標頁面(僅在需要時)

如果你不了解頁面結構,請使用 Playwright 或 curl 檢查 DOM 以尋找選取器。不要猜測 — 選取器很重要,模糊的匹配會導致錄製超時。

對於具有動態內容的 SPA,請優先使用 aria-label、角色 (role) 或文字選取器,而不是 class 名稱。使用 page.locator(s).first() 語義(引擎的輔助函數已經這麼做了)。

步驟 5 — 撰寫場景檔案

在 /tmp/screen-record-<名稱>.mjs 建立一個檔案(不要污染使用者的儲存庫),該檔案匯入引擎並呼叫 runDemo。範本:

import { runDemo } from '/Users/<你的使用者名稱>/Desktop/Projects/skill/screen-record-skills/engine.mjs';
// 或者,如果是透過符號連結安裝:
// import { runDemo } from '/Users/<你的使用者名稱>/.claude/skills/screen-record/engine.mjs';

await runDemo({
  baseUrl: 'http://localhost:3000',
  outputDir: './output/onboarding-demo',
  outputName: 'onboarding',

  splash: {
    label: '造訪我們於',
    url:   'www.yourapp.com',
    footer: 'YourApp — 入門流程',
  },

  cues: [
    { id: 'intro',   text: '歡迎使用 YourApp。讓我帶您四處看看。' },
    { id: 'signup',  text: '點擊「註冊」來建立帳戶。' },
    { id: 'form',    text: '輸入您的電子郵件和密碼。' },
    { id: 'done',    text: '就這樣 — 您已經進來了。' },
  ],

  // 可選:模擬後端,使示範結果可預測。
  routes: [
    { match: /\/api\/signup$/, fulfill: { status: 200, body: { ok: true } } },
  ],

  // 可選:預先設定一個已驗證的使用者,讓示範跳過登入。
  // initialAuth: { id: 'u1', email: '[email protected]', name: 'Demo User' },

  scenes: async ({ page, baseUrl, sleep, speak, awaitCue,
                   clickAt, typeInto, moveCursorTo, hideSplash, typeSplashUrl,
                   configSwitch, showSwitch, hideSwitch, setAuth }) => {

    // 場景 0:URL 啟動畫面(引擎已離線導航至 baseUrl)。
    speak('intro');
    await typeSplashUrl('www.yourapp.com');
    await awaitCue('intro');
    await hideSplash();
    await sleep(750); // 配合啟動畫面淡出時間

    // 場景 1:點擊註冊
    speak('signup');
    await clickAt('button:has-text("Sign Up")');
    await awaitCue('signup');

    // 場景 2:填寫表單
    speak('form');
    await typeInto('input[type="email"]', '[email protected]');
    await typeInto('input[type="password"]', 'CorrectHorseBattery');
    await awaitCue('form');

    // 場景 3:提交
    speak('done');
    await clickAt('button[type="submit"]');
    await sleep(1000);
    await awaitCue('done');
  },
});

步驟 6 — 執行

cd /Users/<你的使用者名稱>/Desktop/Projects/skill/screen-record-skills
# 僅第一次需要:
npm install --silent
# 每次執行:
node /tmp/screen-record-<名稱>.mjs

每次執行時間約等於最終影片長度加上約 10 秒的額外開銷。

步驟 7 — 回報結果

告訴使用者:

  • 最終 .mp4 檔案的路徑(適用於 LinkedIn,1920×1080,H.264 + AAC)
  • .srt 檔案的路徑(LinkedIn 會自動將其導入作為隱藏式字幕)
  • 在 macOS 上提供使用 afplay <路徑> 播放的選項

輔助函數參考(你的場景可以呼叫的函數)

輔助函數功能說明
page原始的 Playwright Page 物件,如有需要可使用
baseUrl設定的基礎 URL
sleep(ms)await sleep(800)
moveCursorTo(x, y, durationMs?)平滑移動到指定座標
moveToSelector(selector, durationMs?, offset?)平滑移動到元素中心
clickAt(selector, durationMs?)移動 + 脈衝 + 點擊(記錄點擊時間用於音效)
typeInto(selector, text, perChar?)點擊 + 清空 + 逐字元輸入文字
recordClick()手動記錄一個點擊時間戳記(用於音效)
speak(cueId)標記提示開始。結束時間為 start + audioDuration + 0.35s
awaitCue(cueId)暫停直到該提示的旁白播放完畢
typeSplashUrl(text, perChar?)在啟動畫面 URL 欄位中進行動畫打字效果
hideSplash()淡出啟動畫面(之後務必 sleep 約 750ms)
configSwitch({ fromInitial, fromLabel, toInitial, toLabel, title, sub })設定帳號切換卡的內容
showSwitch() / hideSwitch()切換帳號切換覆蓋層的顯示/隱藏
setAuth(user)將 localStorage[authStorageKey] 設定為新使用者(與 showSwitch 搭配用於帳號交換示範)

節奏基本原則

  • 每個提示 (cue) 一句話。保持在 12 個詞以內。
  • 對於 UI 操作,在動作之前呼叫 speak(cue),這樣旁白會在游標移動時播放。
  • 對於打字密集的場景,打字時間會長於旁白時間 — 使用 sleep 而非 awaitCue 來控制節奏。
  • 影片總長度通常為 sum(audioDurations) + sum(sleeps)。對於 LinkedIn,目標設定在 30–75 秒。

容易出問題的常見選取器

  • 單獨使用 text=Foo 可能會匹配到多個元素。請使用 page.locator(...).first()(引擎已經這麼做了),或使用 button:has-text("Foo") 將範圍限定在特定標籤。
  • Tailwind 的 class 名稱很脆弱。請優先使用 aria-label、角色 (role)、語義化標籤加文字。
  • 模態框/對話框:在點擊內部元素之前,請等待 [role="dialog"] 或模態框的標題文字出現。

應避免事項

  • 不要將實際的旁白文字寫入場景檔案中 — 將旁白保留在 cues[].text 中,以便字幕和音訊保持同步。
  • 不要將游標樣式寫入頁面的 CSS 中 — 引擎會注入它。
  • 不要在場景中間使用 await page.screenshot() — 你可能會捕捉到處於奇怪位置的游標;如有需要,請事後使用 extractFrames。
  • 不要提交 .env.local(它已列在 .gitignore 中)。

技能說明結束。

相關技能