Communitygithub.com

影片剪輯

將未經編輯的長影片,透過內容感知方式,轉換為精簡、可觀看的第一版剪輯。由人類(你)決定保留哪些內容,腳本負責處理精確的邊界對齊、無聲時間回收、記憶體安全渲染及自我檢查。

影片剪輯 是什麼?

這個技能專注於將原始、未經編輯的長影片(YouTube URL 或本地檔案)製作成緊湊的「初剪」。核心運作方式是:人類先做出編輯決策(決定保留哪些片段),然後由一系列自動化腳本執行機械性的精確任務,例如將剪輯邊界對齊到句子結尾、移除停頓與填充詞、以及調整說話速度。它支援 Windows 和 Linux 平台,並使用 `yt-dlp` 下載影片、`ffmpeg`/`ffprobe` 進行影音處理、以及 `faster-whisper` 進行語音轉文字。技能會產出多個中間檔案(如轉錄稿、分析報告、編輯計畫)與最終的剪輯影片和報告。一個關鍵特點是「記憶體安全渲染」,它使用多個獨立搜尋的輸入片段並透過 `concat` 濾鏡合併,避免一次性解碼整個影片導致記憶體不足。此外,技能內建嚴格的「自我檢查」流程,包含重新轉錄、檢測黑畫面、影音同步和無聲時間等項目,確保剪輯品質後才會宣告完成。它也支援自動變速功能,可在不改變內容的情況下,將說話速度調整至舒適範圍。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/WhiteTowerAI/cut-as-code/tree/main/skills/video-cut

在你喜歡的 AI 中提問

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

說明文件

影片剪輯 是做什麼的?

將一段未經編輯的長影片,轉換為精簡、可觀看的初剪——具決策力、內容感知,且經過自我驗證。由人類(你,模型)做出編輯決策:決定保留什麼;而附帶的腳本則負責執行機械性的精確任務(邊界對齊、無聲時間回收、記憶體安全渲染、自我檢查)。

使用時機

  • 需要將原始/未編輯的影片(YouTube URL 或本地檔案)剪輯得更緊湊。
  • 要求是「減半」、「剪掉無聊的部分」、「製作初剪/粗剪」。
  • 不適用於:逐字填充詞的微手術、多機位 B-roll 組合、色彩/音訊修飾——這些屬於後續的 P1/P2 精修階段。此技能是 P0:驗證診斷結果並產出紮實的剪輯。

相依性

/video-understand 是必要的前置技能。請先執行它,並使用其驗證過的媒體、轉錄稿、分析和時間軸,而不是在此技能中重新建立。開始前,請確認它是否已安裝。如果未安裝,請警告使用者缺少此必要條件,並在處理媒體前停止。

啟動任何包含以下工具的環境(不要假設特定的 conda 環境名稱):

  • yt-dlp(下載),ffmpeg/ffprobe(剪輯/渲染/偵測)需在 PATH 中
  • Python 需安裝 faster-whisper(CPU 即可:device=cpu, compute_type=int8) 先檢查:yt-dlp --version,ffmpeg -version,python -c "import faster_whisper"。

專案協定工作流程

使用以下持久的專案檔案:

work/cut/edit-plan.json          # 僅有人工編寫的保留/丟棄決策
work/timeline.json               # 產生的精確範圍 + 來源/節目對應
review/01-cut/cut-summary.md
review/01-cut/timeline-map.png
review/01-cut/boundary-review.mp4
review/01-cut/full-proxy.mp4  # 可選:完整節目的節奏審查

每個標準決策都有一個穩定的 id、action(keep 或 drop)、start_s、end_s、reason 以及語義/轉錄稿的 evidence_refs。保留決策需按時間順序排列;V1 不支援重新排序或重複的來源片段。

重複使用共享的證據層,而不是重新轉錄或診斷:

python skills/video-understand/scripts/transcribe.py work/cache/audio16k.wav work/understand/transcript
python skills/video-understand/scripts/analyze.py work/understand/transcript.json work/understand/analysis.json

現有的精確腳本接受標準計畫。擴展單詞安全邊界,可選擇分配線性變速,然後產生共享時間軸:

python skills/video-cut/scripts/build_edit.py work/cut/edit-plan.json work/understand/transcript.json work/cache/edit-final.json
python skills/video-cut/scripts/assign_speed.py work/cache/edit-final.json work/understand/transcript.json
python skills/video-understand/scripts/build_timeline.py work/cache/edit-final.json work/timeline.json --fps-num SOURCE_FPS_NUM --fps-den SOURCE_FPS_DEN

使用 work/understand/media.json 中的確切有理數 FPS;切勿將 30000/1001 四捨五入為 30/1。審查 timeline-map.png 和簡短的 boundary-review.mp4。僅在需要審查整個節目節奏時才產生 full-proxy.mp4。將結果寫入 cut-summary.md,並將操作檢查報告指向該檔案。

記錄時間軸貢獻及其所需的來源輸入,更新操作整數 revision,並將 based_on 設定為所使用的確切理解修訂版:

"render": {
  "kind": "timeline-transform",
  "input": "../input/original-video.mp4",
  "plan": "timeline.json"
}

共享的交付渲染器會在通過所有修訂檢查後對有效序列進行編碼。

獨立相容性工作流程

以下舊版檔案和指令在遷移期間仍受支援。build_edit.py 接受 edit_coarse.json 和標準的 decisions[];cut_render.py 接受 edit_final.json 和 timeline.json;此技能的 transcribe.py 是 ../video-understand/scripts/transcribe.py 的相容性包裝器。

將所有中間檔案保留在 work/ 下,交付到專案根目錄:

work/source.mp4            # 下載的原始檔案
work/audio16k.wav          # 給 whisper 的 16k 單聲道音訊
work/transcript.json/.srt  # 逐字時間戳
work/analysis.json         # 診斷(無聲/填充詞/連續說話)
work/edit_coarse.json      # *** 你的編輯決策(手寫)***
work/edit_final.json       # 擴展後的緊湊渲染片段(自動產生;包含每段速度)
work/selfcheck/            # 剪輯重新轉錄 + 幀檢查
first_cut.mp4              # 交付成果
first_cut_report.md        # 編輯 + 自我檢查報告

流程(6 個步驟)

1. 下載

最高可達品質 + 音訊。預設的播放器客戶端經常失敗(無法取得 / DRM / 需要登入)。可靠的備援方案是 android 客戶端:

yt-dlp --extractor-args "youtube:player_client=android" \
       -o work/source.mp4 "<URL>"

如果無需登入只能取得混合的 360p(格式 18),請接受它並記錄此限制 — HD DASH 經常受 DRM/登入限制。然後提取音訊:

ffmpeg -y -i work/source.mp4 -ac 1 -ar 16000 work/audio16k.wav

2. 轉錄(逐字級別)

python scripts/transcribe.py work/audio16k.wav work/transcript [base.en]

產生 work/transcript.json(段落 + 每個單詞的開始/結束時間)和 .srt。使用 faster-whisper,CPU/int8,啟用 VAD,word_timestamps=True。 非英語: 傳遞多語言模型 + --lang,例如 python scripts/transcribe.py work/audio16k.wav work/transcript medium --lang zh (.en 模型僅適用於英語)。先在一個簡短樣本上驗證語言。 注意: Whisper 會移除大部分發聲的「嗯/啊」——它們無法透過轉錄稿測量,因此填充詞檢測必須將下面的詞彙搜尋與無聲間隔分析相結合,不能僅依賴轉錄稿文字。

3. 診斷(「觀看」+「閱讀」)

python scripts/analyze.py work/transcript.json work/analysis.json

呈現:開頭/結尾的無聲時間、單詞間 ≥0.8 秒的停頓(附帶它們跟隨的單詞)、填充詞計數、WPM、說話比率、近似重複段落、>40 秒的獨白段落(可能是冗長的部分)。

要觀看畫面,每約 2 秒取樣一個幀製作成縮圖索引,並自行閱讀;確認場景結構 / 尋找黑畫面或垃圾幀:

ffmpeg -y -i work/source.mp4 -vf "fps=1/2,scale=240:-1,tile=10x10" -frames:v 1 work/contact.png
ffmpeg -i work/source.mp4 -vf "blackdetect=d=0.1:pic_th=0.98" -an -f null -

對於單一的靜態說話頭部鏡頭,不會有場景切換——請預期此情況,並注意後續的跳躍剪輯是正常的,並非故障。

4. 決定剪輯 — 手動撰寫 edit_coarse.json

這是編輯的核心。閱讀轉錄稿 + 分析,然後手寫一個粗略的計畫,包含保留區塊和丟棄區段,這些區塊和區段應無間隙無重疊地覆蓋整個時間軸,每個都有 in、out 和一行 reason。將緩慢的前言壓縮成幾個高價值的片段;保留實質內容為大區塊;丟棄明確的離題/冗長內容。保持時間順序;標準 V1 時間軸拒絕重新排序。目標是將執行時間大致減半。

  • 格式規範 + 真實範例:reference/edit_coarse.schema.md。
  • 將每個區塊邊界對齊到句子/子句結尾——切勿在句子中間或口吃處開始/停止。使用:
    python scripts/inspect_bounds.py work/edit_coarse.json work/transcript.json
    
    它接受舊版的 keep[] 和標準的 decisions[] 計畫,並列印每個邊界附近的單詞,以便您可以將其調整到乾淨的邊緣。

5. 擴展 → 自動變速 → 渲染

將粗略區塊轉換為緊湊、無無聲時間的渲染片段,標準化說話速度,然後渲染:

python scripts/build_edit.py   work/edit_coarse.json work/transcript.json work/edit_final.json 1.5
python scripts/assign_speed.py work/edit_final.json   work/transcript.json   # 添加每段速度
python scripts/cut_render.py    work/edit_final.json   work/source.mp4 first_cut.mp4
  • build_edit.py 在內部停頓大於 SPLIT_GAP(第 4 個引數,例如 1.5 秒)處分割每個區塊,並將每個邊界修剪到無聲時間內(前 LEAD 0.10 秒 / 後 TRAIL 0.30 秒),這樣就不會裁剪到任何單詞,同時回收了無聲時間。較低的 SPLIT_GAP = 更緊湊但更斷續;對於講話節奏緩慢、深思熟慮的講者,建議使用 ~1.5,而不是 0.6(避免過多的微剪輯)。
  • assign_speed.py(自動變速)— 按 decision_ref 分組渲染片段,測量每個手寫保留決策的說話速度,並將一個共享的 speed 因子以及每個片段產生的 out_dur 寫回 edit_final.json。已經在舒適範圍內的速度保持為 1.0;超出範圍的速度僅移動到最近的死區邊界。相鄰的決策區塊速度差異不超過 0.08 倍,以避免「起伏感」。它僅改變速度——絕不改變保留的內容。在渲染前閱讀列印的表格:
    • 指標:words/min(英語)— 對於 CJK(zh/ja/ko)會自動切換為 chars/min。
    • 預設值是首次運行的起點,並非經過驗證的常數:死區 145–185 WPM,速度限制在 1.0–1.3。這僅是加速:慢速的決策區塊可以被加快,而自然快速的講話則保持 1.0。短的決策區塊(<3.5 秒 / <6 個單詞)噪音太大無法測量,會繼承全域因子。
    • 速率是在回收無聲時間後測量的,因此它比總體 WPM 更高,更接近發音速率。列印表格的審查是關鍵的:在渲染前仔細檢查並根據講者調整 deadband,不要盲目信任預設值。
    • 參數(k=v):mode=segment|global|off(預設 segment;global=整個影片使用一個因子,off=停用),deadband=lo,hi,min_speed=/max_speed=,min_seg=/min_words=,lang=auto|en|cjk。要完全跳過此功能,只需不執行此步驟即可 — cut_render.py 會將缺失的 speed 視為 1.0。
  • cut_render.py 使用 N 個獨立的搜尋輸入 + concat 濾鏡,單次重新編碼。這是強制的:從一個解碼後的輸入修剪 N 次會使 ffmpeg 緩衝整個解碼後的串流(對於長影片來說是數十 GB)。請參閱 reference/pitfalls.md。 當片段有 speed 時,它會重新設定每個輸入的時間(setpts 影片 / atempo 音訊)並在 concat 前標準化每個輸入的 fps/timebase/sample-rate,以保持影音同步;沒有速度時則回退到確切的原始圖形。
  • 最終比較: video-edit-compare 讀取標準時間軸加上實際的最終交付檔案。它將最終像素投射回來源時間,將變速片段拉伸到其來源持續時間,並以黑色顯示丟棄的範圍。

6. 自我檢查 — 在通過此檢查之前不要宣佈完成

# 協定精確度回歸檢查(從儲存庫根目錄執行)
python skills/video-cut/scripts/check_project_protocol.py
# 重新轉錄完成的剪輯
ffmpeg -y -i first_cut.mp4 -ac 1 -ar 16000 work/selfcheck/cut_audio16k.wav
python scripts/transcribe.py work/selfcheck/cut_audio16k.wav work/selfcheck/cut_transcript
# 內容 + 填充詞 + 邊界檢查
python scripts/verify_cut.py work/edit_final.json work/transcript.json work/selfcheck/cut_transcript.json
# 幀 / 黑畫面 / 接合點檢查(接合時間使用速度調整後的 out_dur,因此保持準確)
python scripts/selfcheck_frames.py work/edit_final.json first_cut.mp4 work/selfcheck
# A/V 同步 + 無殘留無聲時間
ffprobe -v error -select_streams v:0 -show_entries stream=duration -of csv=p=0 first_cut.mp4
ffprobe -v error -select_streams a:0 -show_entries stream=duration -of csv=p=0 first_cut.mp4
ffmpeg -i first_cut.mp4 -af silencedetect=noise=-32dB:d=1.5 -f null -

通過門檻:

檢查項目通過條件
黑畫面無
接合點幀乾淨 — 僅有自然的頭部跳動,無黑/凍結/撕裂畫面
A/V 同步影片與音訊持續時間差異在約 1 幀(≈30ms)內;總和 ≈ 啟用變速時的 final_duration_s_after_speed
≥1.5 秒的無聲時間0(說話比率應明顯上升)
遺漏/重複片段無 — 所有關鍵內容都存在(difflib ~0.90 是可接受的;較低的比率通常是含糊說話導致二次轉錄的噪音,而非內容遺失 — 在歸咎於剪輯前,請透過關鍵字存在與否來驗證)
被切斷的半句話無 — 邊界落在無聲時間 / 句子結尾

誠實的填充詞說明: 段落級別的剪輯不會達到「幾乎沒有填充詞」。每分鐘的密度甚至可能上升,因為保留的內容是對話式的。請誠實報告此情況;逐字級別的填充詞移除屬於 P1/P2(並且會使單一鏡頭的說話頭部影片明顯斷續)。

最後

撰寫 first_cut_report.md:來源摘要、剪掉了什麼及原因、自我檢查表格,以及任何誠實的說明(360p 來源的品質上限、填充詞密度等)。如果應用了變速,請揭露:多少片段被重新計時以及速度範圍(來自 assign_speed.py 的表格 / speed_params),以便讀者知道剪輯並非 1:1 即時速度。另請注意,verify_cut.py 的每分鐘填充詞數在加速後會略高(相同的單詞,更短的分鐘)——這是一個報告假象,並非增加了填充詞。

關鍵原則(得來不易的原則)

  • 你決定內容;腳本決定幀。 手寫 edit_coarse.json;讓 build_edit.py 處理精確度,assign_speed.py 處理速度。
  • 速度影響節奏,絕不影響內容。 自動變速為來自同一個 decision_ref 的所有渲染片段設定相同的速度,僅將超出範圍的速度移動到最近的死區邊界,將相鄰決策的 delta 限制在 0.08 倍,並將輸出限制在 1.0–1.3。atempo 保留音調。審查表格;使用 mode=off 或跳過此步驟以停用。
  • 絕不裁剪任何單詞。 邊界始終落在無聲時間內。
  • 僅使用記憶體安全渲染(N 個搜尋輸入 + concat)。切勿對一個輸入進行多次修剪。
  • 果斷決策。 做出合理的判斷並繼續;不要過度詢問。
  • 自我檢查不可妥協。 在宣佈完成前,務必重新轉錄 + 檢查幀。
  • 請參閱 reference/pitfalls.md 獲取完整的陷阱與解決方案清單。

Individual skills in this repo

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

相關技能