Communitygithub.com

skailabinfo/claude-video-harness

從原始錄影到完成影片的完整剪輯流程:尋找重複片段與假開始、剪去空白、修正逐字稿、去背人物以製作縮圖、製作卡牌與貼紙的節奏表、產出審稿畫面、最終成片、封面圖與封存。在 prompts 中可用「剪接 takes/1.MOV」、「新影片」、「這是錄影」來啟動。

claude-video-harness 是什麼?

這個 AI 助手技能(Agent Skill)專為影片創作者與編輯者設計,將原始錄影(take)自動化處理為最終成品。它支援 Claude Code、Cursor 與 Codex 等 AI 編碼代理(coding agent)平台,透過一系列明確的腳本與命令,自動完成重複性剪輯工作。 技能的核心流程包括:使用 FFmpeg 分析錄影方向與畫面,以 Python 腳本偵測重複片段與假開始(false starts)並建議裁剪點,再根據用戶設定的剪輯節奏(tempo)與參數進行自動剪輯。接著會並行執行人物去背(matting)與逐字稿修正(JSON 格式的 caption 編輯),然後生成包含卡牌(cards)、貼紙(stickers)、B-roll 與音效的腳本(SCRIPT.md)並編寫 Remotion 代碼。最後渲染審稿靜止畫面、輸出最終影片(master)、製作封面圖,並將所有素材封存(archive)至 edits/ 資料夾。 此技能的獨特之處在於它高度尊重用戶的風格設定(如 brand-kit.md 與 editing-taste.md 所定義),只會在用戶明確允許的情況下才加入特效、B-roll 或音效,否則一律詢問。它也包含完善的錯誤檢測機制,例如在剪輯後檢查拼接點是否落在語音上、最後影片的音量是否符合 LUFS 標準等,確保輸出的品質穩定且一致。

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

在你喜歡的 AI 中提問

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

說明文件

新影片:從錄影到成品

開始之前:確保 harness.config.json 中的 configured: true(否則會執行 setup 技能),然後執行 bash video/scripts/doctor.sh 確認沒有 MISSING。 請先閱讀 brand-kit.md、editing-taste.md、exemplars.md 中的「口味設定檔」、anti-patterns.md 以及 delivery-specs.md。 影片風格只能來自用戶設定檔: 是否有海報、卡牌、貼紙、B-roll、音效、圖形多寡、節奏快慢。 設定檔中沒提到的部分,請詢問用戶,不要自行決定。 程式碼的起點是目前的 video/src/。

如果 video/public/footage.mp4 是從上一支影片留下來且尚未封存到 edits/ 中,請先封存(步驟 11),然後再開始。

1. 檢查錄影

ffprobe -v error -show_entries format=duration:stream=width,height,r_frame_rate:stream_side_data=rotation -of default=nw=1 takes/1.MOV

請以 rotation 為準判斷方向,不要只看 width(iPhone 會把垂直影片記錄為 1920x1080 並加上旋轉旗標)。 用以下指令查看 3-4 個畫面:

ffmpeg -ss N -i … -frames:v 1 out/peek-N.jpg

除非是用手持拍攝,否則不要用 vidstab 穩定畫面——它反而會引入晃動。只有當畫面明顯是在手持情況下拍攝時,才需要對原始素材進行穩定處理(使用 vidstabdetect=shakiness=6:accuracy=15 和 vidstabtransform=smoothing=25:optzoom=1:interpol=bicubic,並加上 -c:a copy;需要內建 libvidstab 的 ffmpeg),然後再後續處理。

2. 重複片段與假開始——在剪輯前先處理

cd video && python3 scripts/chunks.py ../takes/1.MOV

整段逐字稿會隱藏重複內容,但觀眾立刻就能察覺。 請找出:相鄰且包含相同片語的段落(重複片段——保留最後一個);長度僅 1-2 個詞、且被下一段重新開始的段落(假開始)。 向用戶展示你將剪掉的清單,附上時間碼,等待用戶同意。 裁切邊界應落在停頓處。

3. 剪輯

cp public/captions.json out/captions.backup.json 2>/dev/null   # cut.py 會覆蓋逐字稿
DROP="12.40-15.80" python3 scripts/cut.py ../takes/1.MOV

節奏取自設定檔中的 cut 參數(根據參考素材調整)。 腳本會輸出 DURATION、拼接畫面以及「拼接點落在語音上」的檢查結果。 如果拼接點太少,不符合用戶想要的節奏,請傳入低於設定檔的參數,例如 … 0.4 0.2(預設約 0.35 / 0.2);太多則調高。 完全沒有拼接點——若環境噪音很大,請用 QUIET=-46。 說話很快 / 節奏緩慢——請用 SPEED=1.1。 拼接點若落在語音上,請調整 DROP 或參數,不要置之不理。

4. 去背——請立即啟動(如果 style.poster.enabled 為 true)

TITLE_OUT 取自 cut.py 輸出中的第一個拼接點(海報會在該處出現),通常為 4-7 秒。 去背是最耗時的部分(CPU 上約 8 秒/幀,2 個工作者約 6 幀/分鐘),請在背景執行,然後一邊寫程式碼:

python3 scripts/matte.py <TITLE_OUT> 2 > out/matte.log 2>&1      # 在背景執行 (run_in_background)

去背進行時不要渲染靜止畫面,因為會拖慢速度。 等待完成的方式是透過 ps -axo command | grep "[m]atte.py",不要用 pgrep。 腳本會跳過已完成的幀——重新啟動時直接再次執行即可。

5. 逐字稿

打開 public/captions.json(w、s、e 以秒為單位,em):

  • 修正聽錯的部分:人名、品牌、術語、外來語;縮寫請按照正確寫法(如 AI、ROI);Whisper 常在尾端安靜處產生「謝謝觀看」或「Thank you.」——請刪除;
  • 根據意義來設定「em: 2」(如果 style.captions.highlight 是 size 或 both)和「"accent": 1」(如果是 color 或 both),且數量與用詞須與設定檔(brand-kit.md 第 2、4 節)一致。 如果設定檔未描述,請詢問用戶哪些詞需要標示。

6. 節奏表

自行或透過子代理 script-beats(若影片較長)來撰寫 video/SCRIPT.md:

  • 海報——僅當 style.poster.enabled 為 true:使用用戶的用詞和語氣,重音和 kicker 須符合設定檔;
  • 卡牌——若 style.cards 不為 none,密度依照 editing-taste.md 第 3 節(數字決定 count;步驟決定 num + head;列舉則用 head + lines 或帶圖示的 row);from 為該片語的第一個單詞 + 4 幀;
  • 貼紙 FLOATS——僅當 style.stickers 為 true:用一個單詞作為標籤,並使用簡潔的圖示(ART_NAMES);
  • 卡牌若標註 pain: true——僅當用戶明確要求「避免這樣做」時才使用。

在寫程式碼之前,先向用戶簡要展示節奏表(出現什麼、出現在哪裡)——這是用戶的影片,由用戶決定。

7. 程式碼

  • src/Composition.tsx:設定 DURATION、TITLE_OUT、KICKER、TITLE、BEATS、FLOATS;Captions from 若有海報則為第二個片語的開始,否則為 0。
  • src/ui/Footage.tsx:BEATS 表格必須嚴格按照 cut.py 輸出的拼接點,並且以最大力度顯示(特寫約 1.16-1.21 倍,一般約 1.06-1.09 倍)——style.motion.punch 會自行調整或關閉。特寫的位置依據 editing-taste.md 第 4 節;特寫後要拉回,否則特寫感會「卡住」;若有海報,則在第一個拼接點使用。
  • 只有當卡牌、貼紙、Photo / Clip / Tag 都無法表達時,才新增元件(此時使用 scene-builder)。
  • 如果已連結 Higgsfield 且設定檔要求 B-roll(brand-kit.md 第 5 節):透過 <Clip> 顯示(先裁切並靜音:ffmpeg -an -t <秒>),插入前請檢查生成畫面上的文字 / 臉 / 手。請先詢問用戶並告知價格。
  • 音效——僅當 style.sfx 為 true:缺少的音效(如 card、count、end)請透過子代理 audio-agent 根據設定檔描述生成。
  • npm run lint 必須乾淨。

8. 審稿畫面(去背完成後)

根據每個卡牌和貼紙,渲染一張完全組合好的靜止畫面、海報的中間時刻(最後一行文字位於頭髮上方)、幾句字幕、以及最後一個畫面:

npx remotion still MyComp out/key/f<N>.png --frame=<N> --scale=0.5 --timeout=120000

將這些畫面以每列 4 張的方式拼成一張圖,並加上編號標籤(使用 PIL;字型需支援西里爾字母,例如 /System/Library/Fonts/Supplemental/Arial Bold.ttf),然後向用戶顯示(SendUserFile)。 只有當用戶說「可以」之後,才能輸出最終影片。 審稿畫面只需幾分鐘,最終影片則需 10-20 分鐘。

在顯示之前自行檢查:關鍵文字不要落在畫面下方 15% / 上方 8% 以內;沒有任何元素重疊;貼紙與卡牌不交錯;最後一個畫面不空或不完整;一切都符合用戶設定檔,沒有多餘內容。

9. 最終影片

npm run master        # 在背景執行;請監控程序,不要只看檔案是否出現

腳本會自動檢查裁剪處、計算幀數,並輸出 out/preview.mp4。 請檢查音量:

ffmpeg -i out/final-master.mp4 -af ebur128 -f null - 2>&1 | grep -A3 Summary

音量應接近 audio.lufs 的目標值。 將預覽影片傳送給用戶。

最終影片後的修改(例如「把這句剪掉」)——請直接修改最終影片(使用 ffmpeg 的 trim+concat 以靜音處為界),不要重新裁剪原始錄影或重新渲染全部;請提前告知預計完成時間。 檢查接合處:剪掉前後各 6 秒並用 whisper 跑一遍——應該只有所需的兩句話。

10. 封面圖

如果設定檔未指定,請詢問用戶需要哪種封面:從影片中選取的畫面(Cover)、影片海報(PosterCover)或自訂。 選擇畫面時請與用戶共同決定:提供 3-4 張清晰且人物睜開眼睛的畫面(ffmpeg -ss <秒> -i takes/1.MOV -frames:v 1 -q:v 2 out/cover-N.jpg)。

  1. 將選定的畫面複製為 public/cover-bg.jpg。
  2. rembg i -m birefnet-portrait public/cover-bg.jpg out/cover-matte.png
  3. python3 scripts/cover-sticker.py public/cover-bg.jpg out/cover-matte.png public/cover-cutout.png 20
  4. 在 Root.tsx 中,設定 Cover 的 defaultProps.lines:使用用戶的用詞作為標題,accent / em 則依用戶喜好。字型大小會自動調整——請勿手動修改。
  5. npx remotion still Cover out/cover.png --timeout=120000——然後顯示結果。

替代方案:PosterCover——使用影片海報作為封面(畫面及其去背結果分別放在 poster-bg.jpg / poster-cutout.png)。

11. 封存

將以下檔案放入 edits/<N>/(位於根目錄,而非 video/ 下):Composition.tsx、Footage.tsx、captions.json、SCRIPT.md、cover.png、final-master.mp4、preview.mp4。 如果用戶想要,後續可執行 publish 技能。

Individual skills in this repo

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

相關技能