Communitygithub.com

beachyphotoandfilm-arch/video-skills

將原始說話頭影片轉換為 DaVinci Resolve 中的組裝粗剪。從素材碟拉取片段、本地轉錄、移除失敗鏡頭、重啟、旁白與空白音,然後建立一個包含兩個紙本編輯時間軸的新 Resolve 專案,準備好進行精修。

video-skills 是什麼?

此技能自動化從原始攝影機檔案到 DaVinci Resolve 粗剪的工作流程。它透過 ffmpeg 和本地 Whisper 轉錄處理說話頭影片,識別並移除失敗的鏡頭、重啟、旁白、長時間沉默以及句子內的重啟。最終產出兩個時間軸:一個僅基於判斷的粗剪(v1),以及另一個同時收緊暫停的版本(v2),通常能將原始長度減少約 25%,且接近人類編輯的精確度。技能還支援選用的「特寫」功能,可根據腳本標記添加靜態構圖變化,以及在剪輯鎖定後可選的照片覆疊層。整個過程完全在本地進行,利用 DaVinci Resolve 的 Python API 透過 Resolve MCP 伺服器,無需雲端服務或手動檔案移動。它會保留一段詳細的切割清單以供使用者審查,並在應用之前要求確認,以確保編輯的決定保持透明且可由人類覆寫。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beachyphotoandfilm-arch/video-skills/tree/HEAD/skills/paper-edit

在你喜歡的 AI 中提問

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

說明文件

紙本編輯

原始攝影機檔案輸入,Resolve 中組裝的粗剪輸出。在其首次實際測試影片中:原始 14:17,輸出 10:16,對比創作者自己的手動編輯為 10:32。

分工方式: Claude 執行粗略剪輯,創作者進行精修。不要試圖交付最終剪輯,也不要過於保守,以免他們必須重做顯而易見的部分。

設定:填寫這些

佔位符說明範例
<FOOTAGE_DRIVE>原始素材存放位置,每個影片一個資料夾/Volumes/MyWorkDrive
<LUT_PATH>可選 LUT,相對於 Resolve 的 LUT 資料夾MyLuts/SLog3-to-709.cube
WHISPER_MODEL (環境變數)whisper.cpp 模型檔案預設 ~/.cache/whisper-models/ggml-small.en.bin
RESOLVE_APP (環境變數,可選)非標準路徑的 Resolve 應用程式路徑預設 /Applications/DaVinci Resolve/DaVinci Resolve.app

需求:ffmpeg、ffprobe、whisper-cli (whisper.cpp)、Python 3、DaVinci Resolve 以及一個暴露 execute_resolve_code 的 Resolve MCP 伺服器。

執行

工作目錄:使用工作階段暫存區,例如 <scratchpad>/paperedit。技能目錄如下為 .claude/skills/paper-edit。

1. 尋找素材

素材位於 <FOOTAGE_DRIVE>,每個影片一個資料夾,通常命名較寬鬆。

find "<FOOTAGE_DRIVE>" -maxdepth 4 -iname "*<關鍵字>*" -not -path "*/.*"

如果有多個相符項目,請與使用者確認資料夾。不要複製檔案;Resolve 會連結到素材碟上的檔案。

2. 轉錄每個片段

bash <skill>/scripts/transcribe.sh "<FOOTAGE_DRIVE>/<資料夾>" "<work>"

寫入 <clip>.json (詞級)、<clip>.wav 和 clips.ndjson (包含時長)。對於 15 分鐘的素材,約需 90 秒。會跳過已完成的片段,因此重新執行是安全的。

3. 自己閱讀轉錄稿

python3 <skill>/scripts/sentences.py "<work>"

全部閱讀。 這是無法腳本化的部分。曾經嘗試過重複短語檢測器但失敗得很慘:它想要刪除 737 秒中的 428 秒,因為老師會故意重複短語(「這是有效的,這是無效的」)。

4. 撰寫剪切清單

<work>/cuts.json,每個移除項目一個物件,時間以從該片段開始的秒數表示:

[{"clip":"C0002","start":32.58,"end":39.76,"why":"結巴:'我意識到有時甚至...'"}]

剪切這些:

  • 旁白和對鏡頭說話:「說真的,那還不錯」、「這台相機快沒電了」、「這大概會是七分鐘的影片」
  • 虛假開始,保留最後一次嘗試。說話者經常重複一個句子兩次,第二次更好。
  • 行動呼籲的失敗鏡頭。通常結尾有 3-4 個;保留最後一個。
  • 段落間的長時間沉默、括號內的噪音([BLANK_AUDIO]、(鍵盤敲擊聲)、(移動聲))
  • 思緒中斷並重建的句子(「我以前不做這個的原因是因為我害怕,而且...」)
  • 句子內部的短暫重啟,以逗號和重述子句標記:「我所要求的回報只是一個簡單的評論,而這個是,而且添加評論部分...」從放棄的子句剪切到重啟處。這些通常 1-2 秒,很容易被閱讀過去。
  • Whisper 詞時間偏移約 0.5 秒。 在重複相同詞語的虛假開始上(「我喜歡進來提供,我喜歡開始」),在第二個「我喜歡」的開始處結束剪切,而不是第一次嘗試的結尾,否則一個多餘的詞會保留下來。
  • 在保留詞的 to 偏移處開始剪切,絕不在其 from 處。 在一次測試中,剪切從 40.30 開始,而保留詞的範圍是 40.19-40.92,因此鉤子的最後一個詞被切掉了,必須手動拖回來。使用 from|to 列印每個剪切前一個詞的偏移量。
  • 在長時間的 [BLANK_AUDIO] 之後,時間計算不可靠。 Whisper 在 30 秒的靜音後壓縮了第一個鉤子鏡頭的詞語,而剪切在影片的第一秒就留下了一個詞片段。當一個鏡頭在空白音之後開始時,檢查音頻電平(ffmpeg astats)以找到語音真正開始的位置,而不是信任詞偏移量。

保留:

  • 用於教學節奏的有意重複
  • 仍然教導某些東西的離題,除非使用者另有說明
  • 任何你不確定的內容。在你的摘要中標記它,而不是剪切它。

5. 建立片段

python3 <skill>/scripts/segments.py "<work>"

產生 segments-v1.json(僅判斷剪切)、segments-v2.json(也將超過 0.50 秒的暫停修剪至 0.22 秒)和 cutlist.txt。可透過環境變數調整:MIN_GAP、KEEP_PAUSE、NOISE_DB。

它也會丟棄無語音短脈衝:v2 中低於 1 秒且沒有說話級別音頻的片段。它們是滑鼠點擊和筆記型電腦上的瞥視,保留為修剪暫停之間的孤島。可調整參數:BLIP_MAX、SPEECH_DB。

在向使用者展示之前,閱讀 cutlist.txt 中的每一行 join:。 它會列印句子在每個剪切處的讀取方式。如果相同的短語出現在 | 的兩側,則剪切太短。

兩個版本都很重要。 僅使用判斷剪切時,回饋是「整個過程中有很大的暫停,特別是在開頭。」暫停修剪是將 11:32 降至 10:16 的原因。不要將 KEEP_PAUSE 降至約 0.20 秒以下;它開始聽起來很倉促。

6. 在建立前顯示剪切清單

貼上摘要:原始長度、v1、v2、剪切數量,以及帶有說明的顯著剪切。使用者可以否決他們不想要的。

7. 在 Resolve 中建立

需要 偏好設定 > 系統 > 一般 > 外部腳本使用:本地(設定一次,會記住)。不要要求使用者開啟 Resolve。首先執行此操作;如果 Resolve 已關閉,它會啟動 Resolve 並等待 API 回應:

bash <skill>/scripts/ensure_resolve.sh

如果 Resolve 正在執行但超時,表示腳本功能已關閉;這是唯一需要要求使用者修正的事情。

寫入 <work>/params.json:

{"project":"<影片名稱> - YYYY-MM-DD","work":"<work>",
 "files":["<FOOTAGE_DRIVE>/<資料夾>/C0001.MP4","..."],
 "fps":23.976,"width":1920,"height":1080}

然後一次 execute_resolve_code 呼叫:

PARAMS = "<work>/params.json"
exec(open("<skill>/scripts/resolve_build.py").read())

多個影片:一次建立一個,絕不平行進行工具呼叫。 Resolve 只有一個當前專案,因此同時兩個建立會衝突。曾經有兩個建立同時執行,結果一個 v2 是空的,儘管腳本報告每個項目都已添加。每次建立後,自行檢查每個時間軸的項目數量。

將專案命名為 <影片> - YYYY-MM-DD,使得同名專案永遠不會混淆。它會建立一個新專案,匯入片段,並建立 Paper Edit v1 和 Paper Edit v2 (tight)。不會觸及任何現有內容。這是 execute_resolve_code 的授權使用;append_to_timeline 無法接受輸入/輸出點,因此沒有替代工具。在同一個工作階段中,首次向使用者顯示程式碼。

如果無法連線到 Resolve 的後備方案(雲端/排程執行,或 ensure_resolve.sh 失敗):撰寫一個包含 asset-clip 元素的 FCPXML,每個片段一個,包含 start 和 duration(以 frames*1001/24000s 表示),然後讓使用者匯入它。結果相同,多按一下。

8. 交接

告訴使用者兩個時間軸都存在,應該先瀏覽哪一個(v2),以及 v1 是如果 v2 感覺被剪輯得太過的備用方案。然後詢問剪輯是否鎖定,因為疊加層是在這之後進行(如果你有的話,請參閱 video-overlays)。

9. 特寫(可選的第三時間軸)

靜態構圖變化使說話頭影片更易觀看。Resolve 的 API 沒有關鍵影格存取權限,因此無法腳本化緩慢推近;靜態的每個片段構圖(「時不時讓其中一個片段稍微放大一點」)是你能做的事情。

將每個更改與轉錄稿連結,絕不根據計時器。 基於計時器的版本感覺很隨機。在重點台詞或新主題開始的地方進行特寫,使其有意義。

寫入 <work>/framing.json:

[{"clip":"C0002","at":361.40,"framing":"med","why":"提示 3"},
 {"clip":"C0002","at":371.80,"framing":"close","why":"'這是重要的部分'"}]

at 是來自 sentences.py 的句子開始時間。然後執行 python3 <skill>/scripts/punchins.py "<work>" 並在 params.json 中設定 "punchins": true。它會在標記落在片段內任何位置時分割該片段,在句子開始附近最安靜的點進行分割,因為說話頭經常在沒有暫停的情況下長時間說話,否則變化會延遲出現。

如果使用者在 Resolve 中手動修剪了 v2,他們的時間軸就是剪輯版本。 讀取其項目(GetLeftOffset/GetDuration,影格數 x 1.001/24 = 秒)到 segments-locked.json 中,使用 SEGMENTS=segments-locked.json 執行,並僅將 v3 添加到現有專案,使用 "timelines": ["v3"]。目標是每約 20-40 秒進行一次更改:每個新主題使用寬景,教學時使用中景,重點台詞使用特寫。建構器會在每次更改處放置一個命名原因的藍色標記,以便邏輯可視。

構圖:wide 1.00、med 1.11(傾斜 -12)、close 1.21(傾斜 -24)。

如果使用者在修剪 v2 時對其進行了調色,v3 是從頭開始僅使用 LUT 建立的,因此在建立 v3 後立即將 v2 的調色複製到 v3 上:

src = v2.GetItemListInTrack("video", 1)[5]          # 任何已調色的 v2 項目
src.CopyGrades(v3.GetItemListInTrack("video", 1))    # 跨時間軸有效;縮放/傾斜會保留

使用 GetNodeGraph().GetToolsInNode(1) 驗證每個 v3 項目。不要使用圖庫路徑(GrabStill + ExportStills 到 .drx):透過 API 匯出會回傳 False。如果使用了 GrabStill,請刪除該靜止幀,以便圖庫保持乾淨。

讀取鎖定的 v2:GetLeftOffset() 和 GetDuration() 提供來源影格。第一個片段會告訴你鉤子是否被修剪。比較鎖定的片段與 segments-v2.json,並記錄更改了什麼,以便校準下一次編輯。

10. 調色

在 params.json 中設定 "lut": "<LUT_PATH>",將其應用於節點 1 上的每個片段。如果相機拍攝日誌設定檔(例如 S-Log3),未調色的素材看起來平坦且灰暗,因此設定 LUT 是值得的。API 無法添加第二個節點;對於多節點調色,手動調色一個片段,然後使用 CopyGrades 推送到其他片段。

11. 在對話上方放置照片(可選)

當講者談論他們擁有靜止照片的內容時,將它們放在v3 的 V2 軌道上,並使用白色背景。

  • 卡片,不是幻燈片。 在純白色上渲染 1920x1080 PNG:三張肖像並排(縮放到 h840,50px 間距)、兩張肖像(h880,60px 間距)或一張橫向(h900)。根據正在說的內容對照片進行分組。
  • 將每張卡片的時間設定為鎖定轉錄稿中的一個句子開始,並在下一句切換卡片。每張卡片約 2-5 秒。僅在描述照片時才停留在照片上。
  • 將它們作為精確長度的 ProRes .mov 匯入,而不是靜止幀。 靜止幀以固定的 2 秒進入 Resolve 並互相重疊。編號的名稱(card1.png、card2.png)會作為單個影像序列匯入,因此請使用單詞名稱。使用 ffmpeg -loop 1 -framerate 24000/1001 -i x.png -frames:v N -c:v prores_ks -profile:v 3 渲染。
  • 對於 .mov,AppendToTimeline 需要 endFrame = 影格數量(不是數量-1),否則每張卡片都會短一個影格,且講者在卡片之間閃現。傳遞 "mediaType": 1 以便不帶入音頻。
  • 將軌道命名為「<主題> 照片」,將卡片放在它們自己的媒體池資料夾中,並且永遠不要對它們套用 LUT(它們已經調色完成)。
  • 在放置之前,向使用者顯示卡片的連絡表。

值得記住的事實

  • 從真實編輯中校準: 在 v2 之後,創作者通常會從約 10 分鐘的剪輯中手動移除 10-20 秒。其中大部分是片段邊緣的影格級收緊,再加上重述的台詞,即一個觀點在幾秒內被說出,然後又以更好的方式再說一次。當一個句子重述前一個句子時,剪掉第一個版本。這與有意的教學重複不同,後者是在跨章節重複一個短語,而不是連續重複。當一個觀點在相距很遠的地方被提出兩次時,將較弱的鏡頭標記為可能的剪切。
  • 通常的擔憂是過度剪切,導致必須添加回東西,因此只在有證據時收緊,絕不根據直覺。
  • 範例來源格式:4K 23.976 MP4,帶 48kHz 音頻;交付時間軸 1920x1080 23.976,從 01:00:00:00 開始。根據你的素材調整 params.json 中的 fps/width/height。
  • 23.976 的時間碼每秒計數 24 影格:frames = round(seconds / 1.001 * 24)。
  • AppendToTimeline 將 endFrame 視為獨佔:傳遞你想要的最後一個影格之後的影格。一個「包含,減 1」的規則會從每個片段中減少一個影格(在 10 分鐘的時間軸上約 4 秒,任何 1 影格的片段都會消失)。
  • 有些講者幾乎不使用填充詞;在圍繞填充詞移除進行建置之前請先檢查。
  • 大約 20% 的原始說話頭影片是可以移除的,其中約四分之三是判斷(鏡頭和重啟),四分之一是空白音。
  • Whisper 模型:ggml-small.en.bin 足夠準確;它確實會聽錯一些詞,這對於剪切點來說無關緊要,但如果你引用講者,這就很重要了。

相關

  • video-overlays:動態圖形,在剪輯鎖定後執行(如果已安裝)
  • video-reels:來自同一素材的豎版剪輯(如果已安裝)
  • video-thumbnails:縮圖和標題(如果已安裝)
  • lapel-sync:當音頻由單獨的領夾麥克風/錄音機錄製時,首先執行此項

Individual skills in this repo

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

beachyphotoandfilm-arch/video-skills

Sync camera footage to a separate lapel or field-recorder track (e.g. Tascam DR-10L and similar) and lay it up in DaVinci Resolve. Stitches the recorder's split files, finds each clip's exact place in the audio by matching words then waveforms, cuts one lapel slice per clip so every later skill works unchanged, checks for clipping, and builds a synced timeline in a new Resolve project. Trigger on "sync the lapel", "sync my audio", "line up the recorder", "I used a lav", or any shoot with a separate audio folder (live talks, events, workshops). Run it before paper-edit or video-reels.

beachyphotoandfilm-arch/video-skills

Design a unique Instagram cover for each reel in your house style. Reads what the reel is about, writes a short hook headline, picks one of your own photos from a tagged photo library, lays it out like your existing covers, and proofs it in grid view at phone size. Renders locally, never with AI image generation. Can be called by a scheduling skill before reels are scheduled. Trigger on "make covers", "reel covers", "cover photo for this reel", "design the IG covers".

beachyphotoandfilm-arch/video-skills

Render finished reels out of DaVinci Resolve, write captions in the creator's voice, attach a custom Instagram cover from reel-covers, and schedule them to Instagram, TikTok and YouTube Shorts through Metricool. Handles the Drive upload hop, collision checks against the existing calendar, and cleanup. Trigger on "schedule the reels", "post these", "put these on the calendar", or after reels are approved.

beachyphotoandfilm-arch/video-skills

Build animated brand overlays (motion graphics) for a talking-head video, timed to the speaker's exact words, plus a DaVinci Resolve import file. House style is in-scene type (text beside and behind the speaker's head) plus diagrams. Transcribes the rough cut locally, picks the moments, renders transparent .mov clips, and writes an FCPXML that drops every clip onto the timeline already in position. Trigger on "make animations for this video", "add overlays/motion graphics", "animate this", "b-roll graphics for my YouTube video", or when the user shares a rough cut and asks for graphics.

beachyphotoandfilm-arch/video-skills

Cut vertical Instagram reels out of a long-form talking-head video, hook first. Picks the strongest standalone moments from the transcript, opens each reel on its punchiest line, builds vertical timelines in DaVinci Resolve framed on the speaker's face with the LUT applied, and finishes them: a hook (a held text card, or a word-by-word "build" hook with punch-in) and burned-look captions on V3; this-or-that reels get product graphics and a comment-keyword CTA card. You trim and render, nothing to import. Trigger on "make reels", "clip this for Instagram", "cut some verticals", or after a YouTube video is cut.

beachyphotoandfilm-arch/video-skills

Design YouTube thumbnails and titles for a talking-head video. Pulls graded full-res frames out of the raw footage, renders brand-styled variants in two proven layouts, and proofs them at phone size where the click actually gets decided. Trigger on "make thumbnails", "thumbnail for this video", "title and thumbnail", or after a video is cut.

beachyphotoandfilm-arch/video-skills

Run the whole YouTube video pipeline end to end, one stage at a time, stopping for the creator's approval at every gate. Paper edit, punch-ins, reels, reel covers, scheduling the reels, overlays, thumbnail and title, then scheduling the long-form video, all through Metricool. Keeps state per video so you can stop anywhere and pick up later. Trigger on "/youtube", "let's do the whole video", "run the video pipeline", "continue the <name> video", or when handed raw footage for a YouTube video.

相關技能