Communitygithub.com

kylefritz/video-skill

為無法觀看影片的 AI 代理程式,從終端機製作、編輯、檢查及理解影片。當需要製作、編輯、檢查或渲染影片(如宣傳片、解說片、開場卡、動態圖像、照片幻燈片、旅遊或活動剪輯、GIF、社群短片,或現有素材的剪接),或者需要了解影片內容(「這段影片發生了什麼」、「找到……的時刻」、「轉錄這段影片」),或者處理看起來過曝、歪斜或不同步的手機影片時使用。同時也適用於 OpenFilm、其 Studio 編輯器、film.html 或包含 window.film 的頁面,以及響度、H.264 相容性、HDR 轉 SDR、GIF 和 WebP 匯出。

video-skill 是什麼?

kylefritz/video-skill 是一個專為無法觀看影片的 AI 代理程式設計的終端機技能,能讓代理程式以程式化方式製作、編輯、檢查與理解影片。它將所有影片處理步驟轉換為可閱讀的格式:影格、聯絡表單、時間戳和轉錄稿,使代理程式能像人類觀看影片一樣進行判斷。該技能支援 OpenFilm(一種基於 HTML 的作者格式)、素材探測與代理處理、響度分析、HDR 轉 SDR、GIF/WebP 匯出,以及常見的影片交付檢查(H.264、yuv420p、faststart、恆定影格率)。它是 macOS 上的指令列工具,依賴 ffmpeg、Python 與 OpenFilm 套件,透過 probe、proxy、look、check、share、frames 等指令提供一站式影片工作流程。關鍵亮點在於它能讓 AI 代理程式完全「讀懂」影片內容,而無需實際觀看。

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

在你喜歡的 AI 中提問

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

說明文件

video-skill 是做什麼的?

腳本位於此檔案旁 scripts/ 目錄中;以下以 $S 代表該目錄,但在每個指令中都需寫出絕對路徑,因為 shell 變數無法在 Bash 呼叫之間傳遞。

你無法觀看影片,所以每個步驟都將其轉換成你能閱讀的內容:你查看的影格和你檢查的數字。 製作一部影片的流程是:寫入 → 渲染影格 → 閱讀聯絡表 → 修正。理解素材的流程是:探測 → 代理 → 時間戳表 + 轉錄稿 → 判斷。交付則透過一個腳本來檢查編碼格式、影格率、faststart 和響度,讓「到處都能播放」成為事實。

首次在 Mac 上使用

自行執行 sh $S/setup.sh。它會檢查 mise 和 ffmpeg(需要的話會透過 Homebrew 安裝 ffmpeg),在首次使用時安裝固定版本的 OpenFilm 並執行 openfilm doctor。修正它印出的每一個 TODO,或向使用者清楚解釋。可以安全地重複執行。

製作影片:OpenFilm

OpenFilm(MIT 授權)是創作格式:一部影片是一個包含 film.html 的資料夾,該檔案將 HTML 頁面、素材、圖片和聲音剪接在一起,每個頁面會在要求的時刻 t 繪製任何內容。Studio 是其本機瀏覽器編輯器。

  1. 列印說明文件並完整閱讀(內容簡短且每個版本都會變更):$S/openfilm。遵循說明文件,當此文件與說明文件不一致時以此文件為準。
  2. $S/openfilm 是在此處執行 OpenFilm 的唯一方式:它會固定版本,在首次使用時透過 mise 安裝,並防止 Studio 彈出瀏覽器視窗。請勿使用 npx openfilm(會繞過固定版本)或 npx skills add openfilm/openfilm(這是與此技能衝突的上游技能)。
  3. FILM 必須是絕對路徑,例如 $HOME/Movies/OpenFilm/Projects/<film-name>。使用相對名稱則會放在當前資料夾,例如某人的 git 儲存庫中。影片絕不能放在儲存庫內。
步驟指令
建立或開啟$S/openfilm open FILM
檢查整部影片$S/openfilm -C FILM look
檢查某個時刻、片段、檔案… look 4.5、look 3-6、look assets/bed.wav
檢查快速進入場景… look 0-2 --count 24
渲染 MP4$S/openfilm -C FILM render
已連接哪些媒體服務$S/openfilm get
診斷安裝$S/openfilm doctor

look 和 render 可以在不開啟 Studio 的情況下執行,並會印出相對於 FILM 的路徑。Studio 的位址包含一個存取金鑰:只提供給與你合作的使用者(它是 127.0.0.1,使用 Chrome 或 Edge,無法從手機存取)。

在展示任何內容之前,請先閱讀每張 look 輸出的工作表,並修正你所看到的問題。它的檢查(同一個 t 繪製相同畫面、字型已載入、文字裁剪、響度)不會判斷品味或版面配置。關於入口動畫中文字被裁切的 ! 警告是正常的;但在靜止狀態下被裁切則是錯誤。然後以全尺寸查看幾個時刻(look 12.5):一個 300 像素的格子會隱藏小細節,包括人物在內。

透過製作一部影片學到的建構方式:

  • 每個鏡頭一個頁面;頁面共享的內容(如同一個 Ken Burns 動作、字型、顏色)放在它們匯入的模組中。每個值都只是 t 的函數:沒有計時器、沒有動畫迴圈、沒有狀態。
  • 頁面自行淡出(透過 t 控制不透明度);在同一個軌道上,鏡頭之間透過黑色淡出是最簡單的轉場。交叉淡入淡出需要後續鏡頭位於前一個鏡頭的上方軌道。
  • 照片上的文字需要背景陰影(例如底部漸層),否則會在複雜場景中消失。
  • 字型放在 FILM/fonts/ 中,使用 @font-face,透過 window.film.ready(document.fonts.ready)等待載入。對於照片,使用 ready: img.decode()。
  • 使用 #t=in,out 進行修剪,絕不剪輯新檔案;比影片還長的音效會使影片延長。

音效

$S/openfilm get 顯示已連接的服務;生成語音、音樂和音效需要使用者自己的提供商金鑰(Studio:OpenFilm 標誌 → 設定 → 提供者)。如果沒有金鑰,則使用 ffmpeg 製作音效,儲存在 FILM/assets/ 下,並將指令保留在 FILM/sound-notes.txt 中以便重新建構,同時說明哪個服務能做得更好。你無法聽到音效,因此透過數字來判斷:

  • -16 LUFS 整合值適用於最終混音(Podcast、大多數網路影片);串流平台通常標準化在 -14 左右。保持真峰值低於或等於 -1 dBTP。背景音墊在語音下方約 -22。
  • 測量:ffmpeg -i X -af ebur128=peak=true -f null -。使用 loudnorm=I=-16:TP=-1.5:LRA=7 標準化生成的音墊;對於最終母帶,請執行 loudnorm 兩次(先測量,然後將 measured_* 值回傳)以確保增益是線性的。
  • look 會列印混音的響度,而 footage.py check 會將未達標的渲染標記為失敗。

收到的素材:導入

手機影片通常與看起來的樣子不同。在查看或剪輯之前,請對任何素材執行以下操作:

uv run --no-project --with pillow python -I $S/footage.py probe CLIP.mov ...
uv run --no-project --with pillow python -I $S/footage.py proxy CLIP.mov <scratch>/clip.mp4

probe 會對以下每一項發出警告,而 proxy 則可在一次處理中修復所有問題(SDR BT.709、內嵌旋轉、固定 30 fps、偶數尺寸、H.264 yuv420p、AAC 48 kHz、faststart):

  • HDR(iPhone 預設錄製 HLG:color_transfer=arib-std-b67、BT.2020)。以 SDR 讀取時,看起來會過曝且顏色偏移:朱紅色變成橙色。proxy 會先嘗試使用 macOS 內建的 avconvert 進行色調映射,否則使用 ffmpeg 的 zscale(許多 Homebrew 版本中缺少此功能),再否則發出警告。
  • 旋轉:手機將直向影片以旋轉標記的方式儲存;某些工具會忽略此標記。
  • 可變影格率:標稱 24,平均 23.997。影格時間會漂移,音訊在剪接後會與畫面不同步。probe 會標記任何差異超過 0.001 fps 的情況。
  • 奇數尺寸:H.264 yuv420p 需要偶數的寬度和高度。

查看並從代理檔案進行剪輯;保留原始檔案以備需要維持全品質的情況使用。

理解素材

uv run --no-project --with pillow python -I $S/footage.py frames <scratch>/clip.mp4 <scratch>/sheets --every 4

這個指令會在每次場景變換時(--scene 0.3)以及至少每 --every 秒取一個影格,最多 --max 60 個,產出 5×6 格的工作表,每格標記為 0007 · 1:23.4,並附有 manifest.json 將每個 ID 對應到其時間。閱讀工作表並用 ID 和時間回答。這是實務指引,並非絕對規則:

  • 創作物:根據鏡頭長度進行均勻取樣。現有素材:場景變換加上每 2-5 秒至少一個影格。快速動作:在短片段中使用 --every 0.5。
  • 工作表長邊保持在 ~2,500 像素以下,並一次閱讀少量工作表;對於長時間的素材,將工作表分發給子代理程式,每個子代理程式為每個格子 ID 寫入一個 JSONL 判決,然後執行 python3 -I $S/check_verdicts.py manifest.json out/*.jsonl(缺失、重複或虛構的 ID 會導致失敗;如果一個工作表中所有格子都得到相同答案,則可能是草率略過)。
  • 談話性影片的大部分內容都在音訊中。 使用裝置端轉錄並帶入逐字時間戳:uvx parakeet-mlx AUDIO.wav --output-format json --output-dir <scratch>(先提取音訊:ffmpeg -i clip.mp4 -ar 16000 -ac 1 audio.wav)。根據時間將詞彙與影格對應。專有名詞可能會出錯(「鳥居」→「Torrey」),因此在引用之前請根據所見內容檢查名稱。

交付

uv run --no-project --with pillow python -I $S/footage.py check FILM/<name>.mp4 --duration 30
uv run --no-project --with pillow python -I $S/footage.py share FILM/<name>.mp4 <scratch>/<name>-share.mp4
uv run --no-project --with pillow python -I $S/footage.py gif FILM/<name>.mp4 <scratch>/loop.webp --start 2.5 --duration 6 --width 480
  • 在交付檔案之前,check 必須通過:H.264、yuv420p、偶數尺寸、恆定影格率、moov 在 mdat 之前(faststart:可邊下載邊播放)、持續時間、響度 ±1.5 LU、真峰值。
  • 當使用者要求檔案或無法使用這台 Mac 時進行渲染;在 MP4 本身上執行 look 作為最終檢查。share 會產生一個較小的複本(1280 寬、CRF 28:一個 30 秒的 1080p 渲染從 34 MB 降到 3.8 MB),用於網頁或聊天;原始影片的 MP4 保持不變。
  • 循環動畫:使用動畫 WebP 而非 GIF。 一個 5.6 秒的照片循環帶慢速縮放,GIF 為 6.7 MB,WebP 僅 1.6 MB:當每個像素都在移動時,GIF 無法重複使用像素。僅在目標無法顯示 WebP 時才使用 GIF;此時 footage.py gif X.gif 會使用生成的色盤(palettegen/paletteuse)。
  • 移除不應傳遞的資訊:iPhone 影片在其中繼資料中攜帶 GPS、手機型號和時間。proxy 和 share 會丟棄所有這些資訊(-map_metadata -1)。原始檔案或透過 AirDrop 或照片匯出產生的複本則會保留。使用 exiftool -GPSCoordinates FILE 檢查。

影片中的照片

使用 photo-skill 技能(github.com/kylefritz/photo-skill;如果未安裝,請提議將其複製到 ~/.claude/skills/photo-skill)來尋找照片(按描述搜尋圖庫,然後判斷聯絡表),並下載全解析度原始檔案:預覽圖對 1080p 來說太小了。將影片使用的照片複製到 FILM/assets/ 中,並重新儲存(移除 EXIF)。在包含某人照片的影片傳送到任何地方之前,請以全尺寸查看每個鏡頭:人臉偵測會遺漏人群,而 300 像素的格子會隱藏 1080p 影格中顯示的人物。

其他工具

OpenFilm 最適合代理程式,因為一部影片就是純 HTML,而 look 正好能回傳你需要看到的內容。截至 2026 年底的替代方案:

工具創作方式備註
HyperFrames(HeyGen、Apache-2.0)HTML/CSS + GSAP,由無頭 Chrome 渲染最接近的類似工具;check --json lint/版面/對比度閘道、快照、Claude Code 外掛
RemotionReact 組件成熟、官方的代理程式技能;原始碼可取得授權,超過一定規模的公司需要授權
Manim(MIT)Python 場景數學和圖解解說
MoviePy(MIT)/ 原生 ffmpegPython / filtergraphs簡單的剪接和疊加;ffmpeg 最適合做為 I/O 層

升級 OpenFilm

上游經常發布新版本。先閱讀發行說明並執行 npm view openfilm scripts(preinstall 或 postinstall 條目需要檢查),然後更改 scripts/openfilm 中的 OPENFILM_VERSION 並重新執行 setup.sh。之後執行 ls ~/Library/Caches/ms-playwright:OpenFilm 的首次執行會刪除沒有連結標記的 Playwright 瀏覽器;setup.sh 會報告它移除了哪些,而 npx playwright install chromium 在需要它的專案中會將其重新安裝。

常見錯誤

錯誤修正
npx openfilm …$S/openfilm …:npx 會繞過固定版本
在錯誤的資料夾中執行 look 或 render$S/openfilm -C FILM …
在沒有開啟其 PNG 的情況下信任 look 的檢查閱讀工作表;檢查通過並不表示排版沒問題
直接剪輯或查看 iPhone 素材先 probe,再 proxy:HDR、旋轉和 VFR 都會造成問題
將主要 MP4 傳送到聊天使用 share,然後 check 複本
為 README 或頁面製作 GIF使用 WebP,大小約為 1/4
升級後使用過時的 Studio停止舊的 studio/server/main.mjs 程序(pgrep -fl openfilm);一個 Studio 對應兩個程序

相關技能