Community程式設計與開發github.com

skailabinfo/claude-video-harness

專案初始化設定工具 — 檢查環境並透過詳細訪談了解使用者風格,產生品牌指南與剪輯偏好設定檔。

claude-video-harness 是什麼?

此技能用於初始化一個垂直短影音(「說話的頭像」風格)剪輯管線,該管線基於 Claude Code + Remotion。它會引導使用者完成一系列結構化的步驟,從環境檢查開始,確保所有必要工具(ffmpeg、Node.js、Python、yt-dlp、Whisper、Rembg)都已安裝。 之後,它會進行深度訪談,涵蓋八個區塊:使用者身份、約 10 個參考 Reels、語音轉錄方式(Whisper 或 ElevenLabs)、第三方服務(ElevenLabs、Higgsfield、21st.dev、Buffer)、根據參考資料分析口味、調色盤、字體,以及剪輯風格(字幕、圖形、動態、聲音)。此技能不依賴預設選項;它會根據使用者的回答和參考資料產生客製化建議,並使用 `variants.py` 腳本以實際影格畫面來展示選項。 支援的平台包括 macOS(主要透過 Homebrew)、Linux 和 Windows(透過 WSL)。關鍵的輸出檔案(`harness.config.json`、`brand-kit.md`、`editing-taste.md`、`exemplars.md`)會記錄使用者的偏好。當 `harness.config.json` 中的 `configured` 設為 `false` 時,應執行此技能,或用於根據請求重新設定專案。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/skailabinfo/claude-video-harness/tree/HEAD/.claude/skills/setup

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

在你喜歡的 AI 中提問

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

說明文件

專案設定

目標:將一個乾淨的克隆變成一個管線,這個管線是以這個人的風格進行剪輯——了解他的喜好、連接他的服務,並展示他未來影片的影格。以使用者的語言說話,簡短且人性化。

這個專案本身沒有自己的風格。 所有關於影片外觀的設定——調色盤、字體、字幕、卡片、貼圖、海報、節奏、Punch-in、調色、聲音——都是由使用者選擇或從他的參考資料中提取的。你不要提供「標準」或「熱門」選項,不要代入自己的偏好,也不要使用專案中已有的任何東西(harness.config.json 中的佔位符和示範內容不是風格,而是空位)。

訪談規則

  • 一個區塊 — 一條訊息,區塊絕不應合併。 不要將兩個區塊放在一個 AskUserQuestion 表單中:人們往往會對一堆問題選擇第一個選項。區塊 4(服務)、6(調色盤)、7(字體)、8(剪輯風格)是需要多條訊息的對話。
  • 口味上不要加「(推薦)」標記。 此標記僅允許用於純粹的技術選擇——例如轉錄方式(區塊 3)。顏色、字體、風格、服務以及有關使用者的問題上不允許有這種標記;要中立地描述選項,說明各自能帶來什麼。
  • 選項來自使用者的回答和參考資料。 如果沒有回答或參考資料,則根據他的主題和語氣收集 2-3 個明顯不同的選項,並用影格展示;由他選擇。
  • 展示,而非描述: 調色盤、字體和剪輯風格都要通過 video/scripts/variants.py 用實際影格畫面來展示。
  • 跳過區塊(「跳過」)——僅在使用者說出這個詞時才允許。這樣做會在設定檔中留下一個中性的佔位符,並且要明確告知:「之後可以設定——說『設定字幕』」。
  • 不要猜測使用者的事情。 品牌、名稱、主題、受眾和語氣——只能來自他的回答,而不是來自帳戶電子郵件、系統用戶名、資料夾名稱或儲存庫連結。儲存庫連結中的帳戶名稱是模板的作者,而不是使用者。
  • 技術細節不要在訪談中討論: 安全區域、無尾段剪輯、兩遍 loudnorm、拼接處的 Punch-in 機制——這些不是口味問題,而是管線運作的方式(參見 CLAUDE.md,「機制」部分)。
  • 金鑰永遠不應通過聊天傳遞。 使用者自己將它們填入 video/.env;你通過 doctor.sh 檢查存取權限,不要列印任何內容。如果在聊天中收到金鑰,不要使用它,而是建議使用者撤銷並建立一個新的。
  • 所有通過 brew / pip 安裝或體積較大的東西——先說明「這是什麼以及有多大」,然後再問「要安裝嗎?」。

步驟 0. 歡迎(一條訊息)

兩到三行:這裡是使用 Claude Code + Remotion 進行垂直「說話的頭像」影片剪輯;該專案本身沒有自己的風格——我們現在將根據你的需求進行設定:告訴我們關於你的事情,分享約 10 個你喜歡的 Reels,選擇顏色、字體和剪輯風格(我會用影格展示選項),並連接所需的服務。然後立即進入步驟 1。

步驟 1. 環境

cd video && ( [ -d node_modules ] || npm install ) && bash scripts/doctor.sh

用簡短表格顯示結果。對於每個 MISSING 項目,提供來自輸出的命令,獲得同意後執行:

  • Remotion 技能(必須):從專案根目錄執行 npx -y skills add remotion-dev/skills --skill '*' --agent claude-code -y。
  • ffmpeg、node、python3、yt-dlp(用於參考資料)——在 macOS 上使用 brew install …;Linux 使用套件管理器;Windows 使用 WSL。
  • Whisper / Rembg——在步驟 3 中根據回答需要時安裝。

沒有 brew——提供連結 https://brew.sh 並等待(安裝過程會詢問密碼,需要使用者自行操作)。

步驟 2. 訪談

區塊 1 — 你是誰

品牌 / 頻道名稱;誰會出現在畫面中;影片主題;平台和帳號(Reels、TikTok、Shorts、Telegram…);目標受眾;語氣;影片語言;最終呼籲行動。

以開放式問題詢問——讓使用者用自己的話回答,哪怕是一條訊息。如果你提供選項(針對語氣或呼籲行動),它們應該是中性的,對任何人都一樣,不要預設主題或利基。

區塊 2 — 參考資料(約 10 個 Reels)

請求:「分享大約 10 個你喜歡其剪輯風格的 Reels 連結——Instagram、TikTok 或 Shorts。最好是那些你希望自己的影片能像它們一樣的連結。透過這些,我能了解你的口味:節奏、字幕、圖形、顏色、字體。」少於 5 個——再要求更多:從 3 個影片中無法歸納出整體口味。解釋說,如果沒有參考資料,則需要在區塊 6-8 中更詳細地詢問。

收到連結後——立即在背景啟動分析,然後進入區塊 3:

cd video && python3 scripts/refs.py "URL1" "URL2" … > ../takes/refs.log 2>&1     # run_in_background

該腳本會下載到 takes/refs/(不會被 git 追蹤)並測量:持續時間、畫面變換頻率、鉤子(Hook)中的變換、音量、語速、第一句話、主要顏色(palette.png);並生成 NN-sheet.jpg(每個影片 24 個影格)和 NN-hook.jpg(前 3 秒)。如果部分連結因要求登入而 FAILED——提供來自 SERVICES.md(「Instagram」部分)的選項:使用 COOKIES_FROM=chrome 重新執行(僅在獲得明確同意後),或者讓使用者自行下載並將 mp4 檔案放入 takes/refs/(然後將檔案路徑傳遞給腳本,而不是連結)。

區塊 3 — 語音轉錄

  • 本機 Whisper.cpp(在 Mac 上推薦): 免費、離線;brew install whisper-cpp + large-v3-turbo 模型(1.6 GB)。
  • ElevenLabs Scribe: 付費(點數),無需安裝,可在任何系統上執行;需要金鑰(區塊 4)。

區塊 4 — 服務(每個服務一條訊息)

不要一次性問「你想連接哪些服務?」。逐一瀏覽服務——每個服務一條訊息:它在剪輯中能做什麼(1-2 行並附上範例)、費用如何、使用者需要提供什麼以及需要多久時間。問題是:「現在連接 / 稍後連接 / 不需要」。

服務在剪輯中能做什麼存取方式時間
ElevenLabs使用 Scribe 轉錄;根據你的口味添加音效強調;語音合成API 金鑰~3 分鐘
Higgsfield當你談論可以展示的內容時,生成短影片片段(B-roll)透過瀏覽器登入~2 分鐘 + 重新啟動後
21st.dev提供現成的 React 元件作為新圖形元素的基礎API 金鑰~3 分鐘
Buffer為 Reels / TikTok / Shorts 排程貼文草稿透過瀏覽器登入 + 在 Buffer 中連接頻道~5 分鐘

順序:ElevenLabs → Higgsfield → 21st.dev → Buffer。如果在區塊 3 中選擇了 Scribe,則 ElevenLabs 是必需的,並這樣告知。「稍後」和「不需要」都是可以接受的回答。

對於每個回答「現在」的服務,按照 SERVICES.md 中的對應部分進行:用自己的話說明連結和步驟,等待使用者表示「準備就緒」,然後配置你的部分並驗證:

  • 金鑰(ElevenLabs、21st.dev): 如果 video/.env 不存在——執行 cp video/.env.example video/.env;使用者自行填入金鑰(使用 open -e video/.env)。驗證方式——執行 bash video/scripts/doctor.sh,檢查 access 部分。如果失敗——很可能是金鑰複製不完整或缺少必要權限;讓使用者建立一個新的金鑰。
  • 21st.dev: 驗證金鑰後,在本機新增伺服器(金鑰直接從 shell 中的 .env 讀取):
    cd video && set -a && . ./.env && set +a && cd .. && claude mcp add --transport http 21st https://21st.dev/api/mcp --header "x-api-key: $TWENTYFIRST_API_KEY" --scope local
    
    如果 claude 不在 PATH 中——讓使用者在終端機中執行此命令。
  • OAuth(Higgsfield、Buffer,可選的 ElevenLabs MCP): 將所選伺服器新增到根目錄的 .mcp.json:
    {
      "mcpServers": {
        "higgsfield": { "type": "http", "url": "https://mcp.higgsfield.ai/mcp" },
        "buffer": { "type": "http", "url": "https://mcp.buffer.com/mcp" },
        "elevenlabs": { "type": "http", "url": "https://api.elevenlabs.io/v1/mcp" }
      }
    }
    
    透過瀏覽器登入——在重新啟動 Claude Code 後(/mcp → 伺服器 → 驗證):現在告知使用者,並在步驟 5 中提醒。對於 Buffer,請使用者提前在 Buffer 中連接頻道(Instagram 需要專業帳戶)。

將已連接的服務記錄在 integrations 中。如果在某個服務上卡住超過 15 分鐘——建議推遲:「我們稍後再連接——說『連接 Buffer』」。

區塊 5 — 你喜歡什麼(根據參考資料)

等待分析結束(ps -axo command | grep "[r]efs.py"),讀取 takes/refs/refs.json,逐一查看每個 NN-hook.jpg、NN-sheet.jpg 和 palette.png。針對每個影片,標記數字所無法體現的內容:字幕(位置、大小、大小寫、粗細、顏色、單詞強調、背景)、圖形(卡片及其樣式、貼圖、螢幕截圖、B-roll、表情符號)、景別和 Punch-in、純臉部畫面的比例、圖形調色盤、字體、鉤子(文字海報、問題、動作)、結尾。

總結成「口味設定檔」:5-7 個至少在半數影片中出現的模式,並附上數字(來自 refs.py 的中位數)。用一條訊息展示,並問:「這說的是你嗎?你希望在你的影片中有哪些,哪些不想要?」。被接受的內容將成為區塊 6-8 中的提案——屆時你將這些選項與其他選項一起用影格展示,而不是默默地套用。那些無法對應設定的內容(表情貼圖、綠幕…)——記錄為設定檔中的偏好。

區塊 6 — 調色盤(2-3 條訊息)

6.1 問題 — 一條訊息,開放式文本:

  • 是否有品牌色——標誌、網站、頻道設計、封面?提供十六進位顏色碼、網站連結,或將標誌 / 螢幕截圖放入 takes/brand/。
  • 影片中哪些內容應該用顏色突出顯示:數字、關鍵字、呼籲行動?
  • 需要什麼樣的感覺:嚴謹、溫暖、鮮豔、平靜?
  • 哪些顏色絕對不想要?

如果收到圖片——提取主要顏色:

python3 -c "
from PIL import Image; import sys
im = Image.open(sys.argv[1]).convert('RGB').resize((200, 200)).quantize(6)
pal = im.getpalette(); cnt = sorted(im.getcolors(), reverse=True)
print([('#%02X%02X%02X' % tuple(pal[i*3:i*3+3]), round(100*n/40000)) for n, i in cnt])
" takes/brand/logo.png

如果收到網站連結——打開它並找到主要顏色(標誌、按鈕、CSS 變數)。

6.2 候選方案 — 2-3 個調色盤,包含四種角色:dark(色塊、遮罩)、light(文字)、accent(強調)、pain(「別這樣做」卡片,如果需要):

  • 來自參考資料 — refs.json 中的 recurring_colours 和 palette.png;與分鏡圖比對,確保顏色來自圖形或文字,而不是牆壁、畫面中的物體或皮膚;
  • 來自品牌色 (如果有的話);
  • 根據 6.1 的回答 ——感覺和需要強調的內容。

可讀性(技術,非口味):文字在色塊上和疊在影片素材上必須可讀——檢查每個候選方案的對比度(light 對 dark ≥ 7:1,accent 對 dark ≥ 3:1);如果候選方案未通過——告知並建議最接近的通過方案:

python3 -c "
import sys
def L(h):
    c=[int(h[i:i+2],16)/255 for i in (1,3,5)]
    c=[x/12.92 if x<=0.03928 else ((x+0.055)/1.055)**2.4 for x in c]
    return 0.2126*c[0]+0.7152*c[1]+0.0722*c[2]
a,b=sorted([L(sys.argv[1]),L(sys.argv[2])]); print(round((b+0.05)/(a+0.05),1))
" '#FFFFFF' '#141414'

6.3 用影格展示:

cd video && python3 scripts/variants.py out/palette-options.png 70,368 \
  '{"label":"A","colors":{"dark":"#…","light":"#…","accent":"#…","pain":"#…"}}' \
  '{"label":"B","colors":{…}}' '{"label":"C","colors":{…}}'

顯示圖片(SendUserFile),加上標題:「A — 來自你的參考資料,B — 來自標誌,C — 依據感覺」。如果有修改意見(「A,但強調色更深」)——重新執行選擇腳本。被選中的調色盤——記錄在 colors 中。

區塊 7 — 字體(2-3 條訊息)

兩種字體:text(用於字幕和卡片,重量 500 / 600 / 700)和 poster(用於影片開頭的標題,如果有的話)。兩者都必須支援影片語言的字母表。

7.1 問題 — 一條訊息:是否有品牌字體(名稱或 takes/brand/ 中的檔案);需要什麼風格——嚴謹、友好、科技、編輯風格;字幕要輕盈還是厚重。

如果進行了區塊 2——查看分鏡圖上的字幕和標題,並描述你所看到的:類型(幾何無襯線、新無襯線、窄體、圓體、襯線體)、粗細、大小寫。不要根據圖片猜測精確名稱——選一個相似的自由字體。

7.2 候選方案 — 2-3 組「text + poster」字體對,來自 @fontsource,包含所需的字母表、風格各異,符合他的回答和參考資料。對於俄語,請檢查是否支援西里爾字母;Bebas Neue 僅支援拉丁字母。已購買的品牌字體——放在 video/src/fonts/ 中,並手動添加 @font-face 加上 font-display: block;如果儲存庫是公開的,請提醒關於授權的注意事項。

7.3 用影格展示:

cd video && npm i @fontsource/<a> @fontsource/<b>                  # 候選方案
ls node_modules/@fontsource/<a>/ | grep -c cyrillic                # 對於 ru > 0
ls node_modules/@fontsource/<a>/ | grep -E '^[0-9]+\\.css$'        # 可用的字重
grep -m1 font-family node_modules/@fontsource/<a>/400.css          # 確切的 font-family 名稱

將候選方案的所需字重匯入添加到 video/src/index.css(@import "@fontsource/<a>/600.css"; …),然後:

python3 scripts/variants.py out/font-options.png 70,368 \
  '{"label":"A","fonts":{"text":"…","poster":"…","posterWeight":700}}' '{"label":"B","fonts":{…}}'

顯示圖片,加上標題。選擇完成後,只在 index.css 中保留所選的匯入,並刪除未使用的套件(npm un …)。

區塊 8 — 剪輯風格(每個主題一條訊息)

四個主題,每個單獨一條訊息:提出問題,並說明在參考資料中看到了什麼(「在 10 個影片中的 7 個,字幕居中且較大」),然後通過 variants.py 用影格展示 2-3 個選項(鍵為 style.*,影格編號 70,270,368)。不要使用「推薦」一詞。

8.1 字幕(style.captions):

  • 位置:cycle —— 短語在畫面中移動(左上 → 右上 → 下方);rail —— 始終在底部;center —— 居中;
  • 大小 size: [普通單詞, 強調的單詞] 以 px 為單位(≈ 48 小,60 中,76 大);
  • 粗細 weight(500–800);大小寫 case:lower / asis / upper;
  • 強調 highlight:color(關鍵詞用強調色) / size(更大) / both / none;
  • 背景 box:true —— 文字下方有色塊,false —— 只有陰影。

8.2 圖形:

  • 卡片 style.cards:glass(半透明玻璃效果) / solid(實心色塊) / none;出現頻率 —— 在 editing-taste.md §3 中用文字描述;
  • 停頓處的表情貼圖 style.stickers:true / false;
  • 開場時在說話者頭後方的海報標題 style.poster:enabled、大小寫 case(upper / asis)、小副標題 kicker。如果啟用 —— 需要 rembg(每個影片約 30 分鐘背景執行,模型 ~1 GB 一次性下載);
  • B-roll(如果已連接 Higgsfield):是否需要,數量 —— 在 brand-kit.md §5 中用文字描述。

8.3 動態與畫面:

  • 節奏 style.tempo:simmer(慢速,表示接受資訊) / standard(中等,適合解說) / hype(快速剪輯、能量)
  • Punch-in style.punchZoom:none(無) / auto(根據音量和句子邊界自動在時間軸上應用) / always(每個剪輯都放大,速度稍微隨機化)
  • 向主觀鏡頭的過渡 style.povTransition:smooth(平滑,基於音訊) / cut(直接跳切)

8.4 聲音:

  • 對白音量,背景噪音、音樂
  • 說話者聲音的效果,必要時進行壓縮器 / EQ 處理
  • 如果你們要用 ElevenLabs - 選擇聲音
  • 過渡中的音效

這最多是簡短的確認,如果使用者的參考資料與某個主題充分匹配,甚至可以跳過該主題。

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

相關技能