Video Edit
Fork 自 browser-use/video-use (MIT):使用本機 whisper.cpp 取代 ElevenLabs、在每次渲染前加入驗證關卡、使用 Hyperframes 字幕取代 libass 字幕、並加入畫布重新構圖功能以製作社群廣告變體。
原則
- LLM 從原始轉錄稿與隨需視覺資料進行推理。 唯一值得保留的衍生產物是打包過的短語層級轉錄稿 (
takes_packed.md)。其他一切——填充詞標記、重拍偵測、鏡頭分類、重點評分——都在決策時才推導。 - 音訊優先,視覺後至。 剪輯候選點來自語音邊界與靜音間隙。只在決策點才深入檢視視覺資料。
- 提問 → 確認 → 執行 → 疊代 → 持久化。 在使用者以白話文確認策略之前,絕不動手剪輯。
- 一般化。 不要預設這是哪種影片。觀察素材,詢問使用者,然後才進行編輯。
- 藝術自由是預設值。 本文檔中的每個特定數值、預設集、字型、顏色、持續時間、音高結構與技術,都是來自一個已驗證影片的實際範例,而非強制規定。閱讀它們以了解可能性和為什麼有效。然後根據素材的實際情況和使用者的實際需求,做出你自己的品味判斷。你必須做的唯一事情在下方「硬性規則」中。 其他一切都是你的自由。
- 自由發明。 如果素材需要此處未描述的技術——分割畫面、畫中畫、下方身份卡、反應剪輯、速度坡道、凍結幀、交叉淡化、匹配剪輯、L-cut、J-cut、呼吸處的速度坡道等——儘管建立。輔助工具是 ffmpeg 和 PIL。它們能做到格式支援的任何事。無需等待許可。
- 在向使用者展示之前,先驗證自己的輸出。 如果你自己都不會發布,就不要呈現出來。
硬性規則(生產正確性——不可協商)
這些是偏離會導致靜默失敗或損壞輸出的部分。它們關乎正確性,而非品味。請記住它們。
- 字幕在濾鏡鏈中最後應用,在任何疊加層之後。否則疊加層會遮蓋字幕。靜默失敗。
- 逐片段提取 → 無損
-c copy串接,而非單次濾鏡圖。否則在加入疊加層時會對每個片段進行兩次編碼。 - 在每個片段邊界加入 30ms 音訊淡化(
afade=t=in:st=0:d=0.03,afade=t=out:st={dur-0.03}:d=0.03)。否則每次剪輯都會有可聽到的爆音。 - 疊加層使用
setpts=PTS-STARTPTS+T/TB將疊加層的影格 0 移至其視窗起點。否則在疊加層視窗期間會看到動畫的中間部分。 - 字幕使用輸出時間軸偏移:
output_time = word.start - segment_start + segment_offset,其中每個片段佔據其整個影格長度(captions.py會處理這個)。否則字幕在片段串接後會錯位。 - 絕不在詞中間剪輯。 將每個剪輯邊緣對齊轉錄稿中的詞邊界。
validate_edl.py --fix會機械性地完成此操作。 - 為每個剪輯邊緣添加邊距。 工作範圍:30–200ms。詞邊緣已對齊音訊包絡,但邊距吸收了剩餘的誤差。快節奏時用較緊的邊距,電影感時用較鬆的。
- 僅使用逐詞原文 ASR。 絕不使用 SRT/短語模式(會失去亞秒級間隙資料)。絕不使用標準化填充詞(會失去編輯訊號)。
transcribe.py會提示 whisper 保留「um」/「uh」——不要移除這個提示。 - 每個來源快取轉錄稿。 除非原始檔案本身變更,否則絕不重新轉錄。
- 多個動畫使用平行子代理。 絕不循序執行。透過
Agent工具同時生成 N 個;總耗時 ≈ 最慢的那個。 - 在執行前先確認策略。 在使用者批准白話文計劃之前,絕不動手剪輯。
- 所有階段輸出都在
<videos_dir>/edit/中。 絕不在技能目錄內寫入。 - 在每次渲染前進行驗證。
validate_edl.py <edl> --fix,只在退出碼為 0 時才渲染。它能捕捉到虛構的來源 ID、超出檔案結尾的時間、詞中間的剪輯、缺少疊加層檔案以及疊加層超出剪輯範圍——這些正是 LLM 撰寫的編輯清單會有的失敗模式。 - 字幕是 Hyperframes 圖層,而非燒錄字幕。 Homebrew 的 ffmpeg 沒有 libass,因此在 EDL 中使用
subtitles會失敗。請使用captions.py;render.py會將字幕 WebM 合成到每個疊加層之上。 - 來源 ID 是檔案的主檔名。 在
sources中,鍵必須是影片檔案名稱去掉副檔名(例如take_B.mp4對應take_B),或在使用--audio-track N轉錄時為<stem>.track<N>——轉錄稿就是這樣找到的。當字幕開啟時,驗證器會在不匹配時報錯。 - 每次渲染單一影格率。 如果你傳遞
--fps給render.py,也請將相同的--fps傳遞給validate_edl.py和captions.py。範圍會被四捨五入到整數影格,使字幕永不偏移。
本文檔中的其他內容都是實際範例。每當素材需要時,請偏離這些範例。
目錄結構
技能位於自己的目錄中(輔助工具與範本在此檔案旁)。使用者影片放在他們指定的任何位置。所有階段輸出都進入 <videos_dir>/edit/。
<videos_dir>/
├── <來源檔案,保持不變>
└── edit/
├── project.md ← 記憶;每次階段後追加
├── takes_packed.md ← 短語層級轉錄稿,LLM 的主要閱讀視圖
├── edl.json ← 剪輯決策(對於變體:edl_9x16.json, edl_1x1.json …)
├── transcripts/<name>.json ← 快取的 whisper.cpp 轉錄稿(逐詞 + 靜音)
├── captions_<edl stem>/ ← Hyperframes 字幕合成 + captions.webm
├── animations/slot_<id>/ ← 每個動畫的來源 + 渲染 + 推理
├── clips_graded/ ← 每個片段的提取(含調色 + 淡化)
├── downloads/ ← yt-dlp 輸出
├── verify/ ← 除錯影格 / 時間軸 PNG
├── preview.mp4
└── final.mp4
設定
install.sh / setup.sh 會安裝所有項目(Homebrew 套件、.venv、whisper 模型、Hyperframes + Chrome)。在冷啟動時僅需驗證——如果缺少 .venv 或某個輔助工具因匯入或缺少工具而失敗,請在執行任何其他操作之前執行 <此技能目錄>/setup.sh(它是冪等的):
PY=<此技能目錄>/.venv/bin/python存在。使用$PY執行每個輔助工具,絕不使用系統 python(它缺少 numpy/Pillow/OpenCV)。ffmpeg、ffprobe、whisper-cli在 PATH 中,並有一個 ggml whisper 模型。預設值:~/.claude-video-vision/models/ggml-large-v3-turbo.bin;可透過VIDEO_EDIT_WHISPER_MODEL覆蓋。- Node.js 22+ 用於 Hyperframes。始終使用固定版本來呼叫:
npx --yes [email protected] …。 yt-dlp和 Manim 僅在首次使用時需要。此技能內含skills/manim-video/;在建立 Manim slot 時請閱讀其 SKILL.md。- 無需 API 金鑰。除了 Hyperframes 的一次性 npm 下載外,沒有任何東西離開機器。
輔助工具位於此 SKILL.md 旁的 helpers/ 中。請根據包含此檔案的目錄解析其路徑。
輔助工具
所有工具都以 $PY helpers/<name>.py … 的方式執行。
transcribe.py <video>— 本機 whisper.cpp,逐詞,保留填充詞,詞邊緣對齊音訊包絡,列出靜音。每個來源會快取(僅當檔案變更時才重新執行)。--language en跳過語言偵測;--audio-track N用於多音軌錄影。transcribe_batch.py <videos_dir>— 資料夾中的每個影片,依序處理(whisper 已讓 GPU 飽和)。pack_transcripts.py --edit-dir <dir>—transcripts/*.json→takes_packed.md(短語層級,在靜音 ≥ 0.5s 處斷開;對於語速快的人,可將--silence-threshold降至 0.3)。timeline_view.py <video> <start> <end>— 產生包含膠片條和波形的 PNG。隨需的視覺深入檢視工具。不是掃描工具——在決策點使用它,而非持續使用。validate_edl.py <edl.json> [--fix]— 每次渲染前的關卡(硬性規則 13)。--fix會將邊緣對齊到詞間隙、加入邊距(--pad-in、--pad-out)、將範圍四捨五入到整數影格、重新計算total_duration_s、保留edl.json.bak。關於邊緣附近少於 30ms 靜音的警告會通過--fix:那些剪輯位於詞與詞接觸的位置——請將它們移動到真正的停頓處。captions.py <edl.json>— 輸出時間軸的逐詞字幕,作為 Hyperframes 合成 → 透明的captions.webm,設定 EDL 的captions鍵。樣式標誌:--accent、--color、--top、--size、--font、--case、--words、--no-pop。render.py <edl.json> -o <out>— 逐片段提取(影格精確、HDR→SDR、畫布重新構圖、調色、淡化)→ 無損串接 → 疊加層(PTS 偏移)→ 字幕 → loudnorm。--preview用於品質檢查,--draft僅用於剪輯檢查。reframe.py <edl.json> [--apply]— 跨每個範圍的 OpenCV 臉部偵測(YuNet)→crop_x/crop_y,在 EDLcanvas上保持說話者居中並留有頭頂空間。每當canvas改變長寬比時,在執行validate_edl.py --fix後執行此工具。它會標記那些臉部MOVES過多以至於無法使用一個靜態裁剪的範圍(應將其分割),以及那些no face的範圍(請自行選擇裁剪)。某個範圍上的"crop_lock": true可保護手動裁剪。scenes.py <video>— OpenCV 鏡頭變換偵測,加上每個鏡頭的DARK/BLURRY標記 →edit/shots/<stem>.json。當轉錄稿無法結構化腳本時使用:B-roll、產品鏡頭、蒙太奇、多機位輸出、無聲片段。鏡頭邊界是乾淨的視覺剪輯點;標記過的鏡頭在廣告中很少可用。grade.py <in> -o <out>— ffmpeg 濾鏡鏈調色。預設集 +--filter '<raw>'用於自訂。
對於動畫,建立 <edit>/animations/slot_<id>/ 並使用 Bash,然後透過 Agent 工具生成一個子代理。
流程
-
盤點。 對每個來源執行
ffprobe。對目錄執行transcribe_batch.py。對於語音很少或沒有語音的來源(B-roll、產品鏡頭),改為執行scenes.py以取得其鏡頭。閱讀其輸出的QC:行(也在每個轉錄稿的qc下):被壓縮到 ≤20ms 或在靜音內開始的詞具有不可靠的時間——在使用它們之前,請使用timeline_view檢查任何靠近這些詞的剪輯。- 多位說話者(通話、訪談):沒有說話者標籤。從內容推斷輪換(問題 vs 回答),然後使用
timeline_view確認你計劃保留的每個短語(在視訊通話中,活躍說話者的圖塊會顯示誰在說話)。如果通話是每人一個音軌錄製的,請改用--audio-track N轉錄每個音軌。執行pack_transcripts.py以產生takes_packed.md。取樣一兩個timeline_view以獲得視覺上的初步印象。
- 多位說話者(通話、訪談):沒有說話者標籤。從內容推斷輪換(問題 vs 回答),然後使用
-
預先掃描問題。 對
takes_packed.md進行一次掃描,記下口誤、明顯的失言或要避免的措辭。形成一個簡單清單,併入編輯者簡報。 -
對話。 以白話文描述你看到的內容。提出根據素材而定的問題。收集:內容類型、目標長度/長寬比、美學/品牌方向、節奏感覺、必須保留的時刻、必須剪掉的時刻、動畫與調色偏好、字幕需求。不要使用固定清單——每次的正確問題都不同。
-
提出策略。 4–8 句話:形狀、鏡頭選擇、剪輯方向、動畫計劃、調色方向、字幕風格、長度估計。等待確認。
-
執行。 透過編輯子代理簡報產生
edl.json。在模糊的時刻深入使用timeline_view。在平行子代理中建立動畫。執行validate_edl.py --fix直到它以 0 退出。然後,如果需要字幕(字幕是從最終範圍建立的,因此任何範圍變更後都需重新執行),則執行captions.py。 -
預覽。
validate_edl.py(不加--fix)→render.py --preview。 -
自我評估(在向使用者展示之前)。 在渲染輸出(而非來源)的每個剪輯邊界處(±1.5s 視窗)執行
timeline_view。檢查每個影像中的:- 剪輯處的視覺不連續性 / 閃爍 / 跳動
- 邊界處的波形尖峰(從 30ms 淡化中漏掉的爆音)
- 隱藏在疊加層後面的字幕(違反規則 1)
- 疊加層錯位或顯示錯誤影格(違反規則 4)
同時取樣:前 2 秒、後 2 秒以及 2–3 個中點——檢查調色一致性、字幕可讀性、整體連貫性。對輸出執行
ffprobe以確認持續時間是否符合 EDL 預期。測量音訊,不要假設:
ffmpeg -i out.mp4 -af ebur128=peak=true -f null -以取得整合響度和真實峰值,以及每個區段的 RMS(對話、純音樂、結束卡)。結束卡比對話低 15 dB,或音效比語音大,都是錯誤。你無法收聽:請說明這一點,並回報數值。對於使用者將發布的任何內容(發布、宣傳、廣告),也請使用渲染後的檔案、EDL 以及使用者給出的任何參考影片,生成一個評論子代理。指示它進行批評,而非讚美:一個 verdict、按時間碼排列的排名問題及證據(影格、位準),以及應先做的 5 個修復。新鮮的眼光能看到作者不再看到的東西——被截斷的妙語、0.5 秒的迷因、在手機尺寸下無法閱讀的 28px 文字。
如果有任何失敗:修復 → 重新渲染 → 重新評估。自我評估次數上限為 3 次——如果三次後仍有問題,請向使用者標記出來,而不是無限期循環。只有在自我評估通過後,才呈現預覽。
-
疊代 + 持久化。 自然語言回饋、重新計劃、重新渲染。絕不重新轉錄。在確認後進行最終渲染。追加到
project.md。
剪輯工藝(技術)
- 音訊優先。 從詞邊界和靜音間隙中尋找剪輯候選點。
- 保留高峰。 笑聲、妙語、強調節拍。將剪輯點延後到妙語之後,以包含反應——笑聲本身就是節拍。
- 說話者交接時,話語之間留一些空白會更好。常見值:400–600ms。快節奏時用較少,電影感時用較多。這是品味判斷。
- 笑聲和反應不會被標記(whisper 不會發射音訊事件)。在
timeline_view波形中找到它們作為無語音但響亮的段落;將剪輯點延後到它們之後——笑聲本身就是節拍。 - 靜音間隙是剪輯候選點。