Communitygithub.com

vincesector/talking-head-pipeline

將原始講話錄影轉換為乾淨的預裁剪檔案。測量並修正嘴型與音訊的同步問題、逐字轉錄、找出結巴與重新開始、移除靜音、提出重拍建議,並在保留字詞邊界的前提下進行渲染與驗證。

talking-head-pipeline 是什麼?

這是一個專為AI代理(如Claude Code、Cursor、Codex)設計的技能,用於自動清理原始講話錄影。它能處理無線麥克風與錄製軟體造成的音訊延遲(透過SyncNet逐檔案測量嘴型同步偏移)、Whisper時間戳不準確(以強制對齊器重新計時)以及Whisper平滑重複語句導致漏掉結巴等常見問題。支援的平台包括macOS與Linux。工作流程分為八個階段:選取檔案(唯讀)、規劃模式(分析同步、轉錄、標記結巴與重拍)、以表格形式顯示計畫並等待人工批准、根據時間碼或詞語套用編輯、渲染(包含三段式後處理確保邊界乾淨)、QA驗證(檢查移除片段中的殘留語音、逐字轉錄中的重複、邊緣裁剪等)、交付成果並移交給/dynamic-edit、最後依指示清理。硬性規則包括:未經人類核准不得渲染、不得硬編同步偏移、從不修改原始檔案、以裁剪後的逐字轉錄而非一般Whisper轉錄進行檢查。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/vincesector/talking-head-pipeline/tree/HEAD/skills/autocut

在你喜歡的 AI 中提問

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

說明文件

/autocut

輸入原始錄影,輸出乾淨的預裁剪檔案。你執行所有指令;人類核准計畫並觀看結果。切勿把命令列交給他們去執行。

儲存庫根目錄(腳本位址):

THP_HOME=${THP_HOME:-$(cat ~/.config/talking-head-pipeline/root)}

適用範圍

情況管線
原始錄影;需要修正靜音、失誤與同步問題此管線
已剪輯好的人物頭像畫面,期望呈現動態感/dynamic-edit,使用本技能產生的 clean.mp4

此技能不新增特效、字幕或圖形。它產生的檔案是 /dynamic-edit 的輸入。串聯是常規流程:先 /autocut 再 /dynamic-edit。

為什麼這樣做有效(這樣解釋)

兩個事實導致簡單的自動剪輯器會「吞噬」字詞並偏移同步:

  1. 無線麥克風與錄製軟體提供的音訊可能提早或延遲,且每次錄製的偏移量都不同(在一台設備上測得 +240 毫秒)。因此,同步是根據嘴部動作(使用 SyncNet)逐檔案測量後再處理。絕不硬編碼。
  2. Whisper 的字詞時間戳大約每 12 個字中只有 2 個落在真正的字詞邊界上。 容忍錯誤數值的裁剪仍然會截斷字詞。因此,每個字詞都會透過強制對齊器重新計時,並且在渲染時,每個裁剪邊緣都會對齊波形本身。

而一個事實導致它們遺漏失誤:Whisper 會平滑掉重複。 「所以我們來談談,所以我們來談談發生的事」會變成一個乾淨的句子。第二次的逐字轉錄(CrisperWhisper)會保留每個假開頭、重複和填充詞;結巴和重新開始就是從這裡找到的。

工作流程

1. 找到檔案,絕不改動它

使用人類指定的檔案,或他們擷取資料夾中最新的錄影(問一次資料夾位置)。用一行文字確認檔名與長度。原始檔案在整個任務期間為唯讀;所有輸出都放到 <原始目錄>/<原始主檔名>_autocut/。

2. 規劃模式

python3 "$THP_HOME/scripts/autocut/autocut.py" "<raw.mp4>"

同步偵測是較慢的部分(3 到 10 分鐘,在忙碌的機器或僅限 CPU 的 Linux 上更久)。開始前要說明。規劃模式的其餘部分在模型快取後約需一分鐘;第一次執行每種語言時會下載模型(幾分鐘)。只有在偵測到的語言錯誤時才加入 --lang en|pt|it|es|fr|de|nl。當偏移量已知時,使用 --offset SECONDS 可跳過偵測;對螢幕錄影(無臉部)使用 --no-sync。

如果偵測失敗(無臉部、信心低),腳本會說明並以偏移量 0 繼續。不要自行編造數值。告訴人類無法測量,並詢問:在不做同步的情況下繼續,或使用他們提供的數值。

3. 以緊湊表格呈現計畫,然後 STOP

讀取工作目錄中的 plan.md 並呈現(切勿貼上原始檔案):

  來源    take-01.mp4   01:47.9
  同步      +240 毫秒(音訊提前),信心度 5.5,離散度 0 毫秒
  結果     預定 01:40.5,移除 7.3 秒,5 個裁剪點

  00:00.0-00:02.8   移除   靜音 3.0 秒          2.8 秒
  00:23.6-00:24.9   移除   靜音 2.0 秒          1.3 秒

  結巴(已套用):  "所以我們來談談,| 所以我們來談談"   保留第二次
  重新開始(建議): 01:12.4 "將會有一個損失在" x2 ...     套用間隔指令已列出
  重拍建議(未套用):
  1  01:45.9-01:47.0  "然後所以"  ->  保留 01:47.0-01:48.1 "然後所以"

在同一區塊標記:同步離散度超過 40 毫秒或信心度低於 3.5;對齊起始偏移 p90 超過 500 毫秒(轉錄稿不穩定);任何被標記為 Whisper 解碼器循環的重拍列。

重複與假開頭預設被移除。 這就是逐字掃描的目的。精準度仍然重於召回率:錯誤的裁剪會導致重拍,遺漏的結巴最多只是多一次裁剪。確信符合模式(立即重複、兩次拍攝間無標點符號的放棄)會被套用;較不明確的則列為 restart? 候選項。在上下文中閱讀每個候選項。否決任何蓄意的修辭重複(「低於 60、低於 70、低於 80」)。填充詞(嗯、呃)會被列出,但永不自動移除。保留最後一次拍攝;當兩次拍攝之間有停頓,該停頓標示第二次拍攝的開始位置。

問一個問題:按原樣核准,或指定要放回的內容。如果某個片語有歧義,請具體詢問;不要猜測。未經回答不得渲染。

4. 根據數字套用編輯,而非記憶

  • 接受重拍或重新開始時使用詞語,而非輸入時間戳:
    python3 "$THP_HOME/scripts/autocut/apply_spans.py" <workdir> --drop "[email protected]"   # 最接近 22 秒的片語
    python3 "$THP_HOME/scripts/autocut/apply_spans.py" <workdir> --span 71.20:74.85     # 使用 plan.md 中列出的指令
    
    閱讀它回顯的每一行上下文。
  • 在渲染前重新從磁碟讀取 plan.json;人類可能編輯過。編輯過的計畫會在裁剪後自動重新裁剪。
  • 編寫的停頓是有內容的:蓄意的停頓(「而答案是……[停頓] 沒有」)會以 keep_silences: [[s, e]](原始秒數)寫入 plan.json,這樣裁剪器就不會緊縮它。

5. 渲染

python3 "$THP_HOME/scripts/autocut/autocut.py" "<raw.mp4>" --render

渲染的動作,以便你能解釋失敗原因:

  • 09p 長片段(超過 3 分鐘):將超過 0.65 秒的停頓上限設為最後一個聲音後的 0.30 秒加上下一個聲音前的 0.20 秒。這裡的靜音是指每 5 毫秒幀低於 -55 dB。切勿提高此門檻:字尾會衰減到 -42 至 -55 dB,更高的門檻會吃掉尾子音。
  • 09a 將每個裁剪邊緣移出聲音運行區,並與被移除的聲音保持至少 50 毫秒的距離;修剪頭尾到第一個和最後一個真實字詞;在 0.4 秒或更長的間隙中移除括號噪音([UH]、[lipsmack])。
  • 09b 將任何持續有聲音的保留起點移回靜音區(恢復被截斷的開頭)。
  • 裁剪器會丟棄任何低於 1 秒且無聲音的片段(兩個跳接之間的「靜音細條」),並對保留的低於 1 秒片段印出 CHECK short piece with sound。逐一聆聽每個此類片段。

6. 驗證裁剪(非選項,按此順序)

  1. 先檢查 qa.md 的 ## Removed-span audit。 每個被移除的間隙都會檢查是否有殘留語音(能量 + 獨立轉錄)。FLAGGED 列表示裁剪不可交付:請調查(先看最大音量視窗 dB,再聽 qa/removed/spanNN.wav),修正 keep,然後重新渲染。單獨一個字詞片段且最大音量視窗 dB 很低,通常是喀噠聲或呼吸聲,而非語音;請相信能量數值而非轉錄文字。approved cut 列沒問題。
  2. 像編輯一樣從頭到尾閱讀 qa/verbatim_cut.txt。 這是 CrisperWhisper 對裁剪後檔案的逐字轉錄。尋找任何殘留的重複片語、片段或整句重拍。切勿使用一般的 Whisper 轉錄來檢查裁剪:它正好會隱藏這些。 停頓後連續說出的整句重拍只能以此方式發現。
  3. ## Restarts still in the cut 和 ## Edge clipping 在 qa.md 中:解決每個 FLAGGED 列(像 "928 ... 939" 這樣的數字序列可能是誤判;請閱讀它們)。
  4. 腳本無法執行的檢查:
    • 輸出長度 vs 預定長度:差異超過 0.6 秒有問題;
    • 以 5 fps 掃描每個連接點(從 timemap.json 取得前後 0.5 秒的幀):連接點不得落在手勢模糊或重複幀上;
    • 無內部停頓超過 1.0 秒;無低於 -45 dB 的片段;
    • 固定幀率:計數的幀數 / 串流持續時間必須與標稱 fps 完全相等(30.0000,而非 29.98)。錄製設備在負載下會掉幀,如果此值不正確,下游每個基於幀索引的工具都會發生漂移。

在不重新裁剪的情況下重新執行 QA:autocut.py --qa-only --workdir <dir>。

為人類開啟 clean.mp4(macOS 用 open,Linux 用 xdg-open)。

7. 報告與交接

報告已移除的內容(表格)、clean.mp4 的位置,以及一句話:這是預裁剪輸入;說「讓它變動態」以繼續使用 /dynamic-edit。下一階段使用的字幕來自逐字詞語,並對應到裁剪時間軸:

python3 "$THP_HOME/scripts/autocut/verbatim_cut_words.py" <workdir> -o words.json

8. 清理,僅當人類表示影片已完成時

工作目錄包含 synced.mp4(錄影的完整副本)和 tmp/ 渲染片段。在刪除前先詢問。plan.json、transcript.json、verbatim.json 和 qa.md 很小;保留它們。

嚴格規則

  • 計畫閘門是強制的。 沒有獲得人類同意不得渲染。
  • 絕不硬編碼同步偏移。 逐檔案測量,或使用人類提供的數值。
  • 原始檔案絕不被修改。
  • 使用裁剪後的逐字轉錄檢查裁剪,切勿使用一般的 Whisper 轉錄。
  • 絕不鎖定自動產生的邊緣。 _meta.pinned_edges 專供人類對照波形檢查過的邊緣;鎖定機器邊緣會跳過快照器的清除作業並吞噬字詞。
  • 靜音僅限低於 -55 dB。 在閘控麥克風上,-40 到 -55 dB 之間的東西不是靜音。
  • 無拼接的短於 1 秒且無語音的片段。
  • 當詞語或指令含糊時,問一個具體的問題。

注意事項

  • Whisper 會在結尾環境音上幻想出空段落,時間戳會超過檔案結尾。這是預期行為;重拍尋找器會過濾它們。在尾部兩秒內出現一千個「重拍」是解碼器循環,而非真正的重拍,plan.md 會這樣說明。
  • 同步偵測需要畫面中有臉部。僅螢幕錄影的片段:使用 --no-sync,並說明原因。
  • 許多麥克風錄製的音量偏小(約 -30 LUFS)。autocut 不做正常化。音量調整屬於最終母帶處理(scripts/master/sync_trim.sh --loudnorm);切勿暗中套用它。

完整的按階段參考文件:$THP_HOME/docs/AGENT_GUIDE.md。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能