Communitygithub.com

eternityspring/reelbench-skills

將拉片數據與原始影片合成一條**可直接觀看的影片**:一邊是畫面,一邊是該鏡頭的分鏡資訊(鏡號、起止、時長、景別、類別、運鏡、畫面描述、台詞),**鏡頭切換時資訊同步切換**,鏡頭表自動滾動並高亮當前鏡頭。版面僅依原始影片的寬高比決定:**橫版/方版 → 畫面上、資訊下;豎版 → 畫面左、資訊右**,畫面始終原始縮放,不裁切、不拉伸。鏡頭表**隨播放滾動**:切點處滾動一段將當前鏡頭帶到錨點後停止,高亮條同步滑動。實作上僅截取三張圖(底板 + 展開長圖 ×2),滾動與高亮由 ffmpeg 按時間裁切視窗,**佈局全在 scripts/panel.css 中,修改它即可調整版面**,無需修改腳本。使用 video-shots 產出的 shots.json(如有 frames/ 則將關鍵幀作為縮圖)。零 npm 依賴,使用 ffmpeg 合成、無頭瀏覽器渲染面板。當使用者要求匯出影片、合成影片、分鏡影片、帶分鏡資訊的影片、解說版影片、video with shot info、annotated shot video 時使用。

reelbench-skills 是什麼?

此技能「reelbench-skills」用於將拉片資料(shots.json)與原始影片合成為一條帶有分鏡資訊的影片。它會依據原始影片的寬高比自動選擇佈局:橫版或方版將畫面置上、資訊置下;豎版則畫面在左、資訊在右。畫面始終保持原始縮放,不裁切或拉伸。技能的核心特色在於僅截取三張靜態圖片(底板及兩張展開的長圖),並利用 ffmpeg 根據時間點裁切視窗來實現滾動與高亮效果,而非逐幀渲染。這使得即使影片有 53 個鏡頭,截圖次數也從 53 次降至 3 次。鏡頭表在切點處滾動並自動將當前鏡頭帶到錨點後保持靜止,高亮條同步滑動。所有版面樣式皆定義在 scripts/panel.css 中,修改該檔案即可調整佈局,無需更動腳本。技能支援 Node.js 環境,無需 npm 依賴,並使用 ffmpeg 進行合成,以及無頭瀏覽器(如 Chrome、Chromium、Edge)渲染面板。它適用於 Claude Code、Cursor、Codex 等 AI 代理平台,幫助開發者快速產出帶註釋的影片,適合用於影片分析、教學或展示場景。

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

在你喜歡的 AI 中提問

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

說明文件

video-sync

把 shots.json + 原片 合成一條影片:畫面一邊,當前鏡頭的分鏡資訊另一邊, 鏡頭切了資訊跟著切,鏡頭表自動滾動並高亮。

版式只看寬高比,不看別的:

原片版式合成方式
橫版(寬 > 高)、方版畫面在上,資訊在下vstack
豎版(高 > 寬)畫面在左,資訊在右hstack

兩個方向都保證畫面原樣縮放、不裁不拉,面板補足剩下的地方。

只截三張圖,動的部分交給 ffmpeg。 面板上會變的只有兩樣:滾到哪、哪一行亮。 所以量一次行位置、截一張底板、截兩張把鏡頭表鋪開的長圖(一張壓暗、一張全亮), 滾動=從暗底長圖裁一個視窗,高亮=從亮條長圖裁一行蓋上去,位置由 sendcmd 在每個切點下發一條小表達式驅動。53 鏡的片子截圖從 53 次降到 3 次(12 秒)。

當前鏡頭釘在第二行:第 1、2 鏡不滾(高亮往下挪一行),第 3 鏡起每切一次往上滾一行。 動在切點,靜在鏡頭裡——切點處滾 --ease(預設 0.45)秒到位就停住, 16 秒的長鏡頭裡讓列表一直爬,觀眾要盯著它晃 16 秒。

行高由內容決定,描述寫得長行就高;高亮條按行高分層(crop 的高度執行時改不動)。

{baseDir} = 本檔案所在目錄。腳本 {baseDir}/scripts/video-sync.mjs,零依賴,node 直接跑。

邊界(不做的事):不做拉片(那是 video-shots 的活,本 skill 吃它的 shots.json)、 不剪輯不轉場不配樂、不燒字幕到畫面上、不做逐幀渲染(動效由 ffmpeg 按時間裁窗做出來)。


Step 0 — 先有拉片資料

要一份 shots.json(video-shots 的產出)和對應的原片。有 frames/(每鏡關鍵幀) 更好——鏡頭表裡會用起手幀當縮圖,沒有就留空格。

shots.json 必須和這條片子對得上:meta.durationSeconds 與原片不符就別合, 先回去把拉片做對。

Step 1 — 先看幾何,再動影片

node {baseDir}/scripts/video-sync.mjs plan shots.json --video <片>

只算不合成,幾秒出結果:版式、畫面區、面板區、輸出尺寸。先確認這三個數字合理再往下走—— 合成一條 3 分鐘的片子要一兩分鐘,算錯了再重來不值。

不滿意就調:--panel <比例>(橫版是面板高÷畫面高,預設 0.8;豎版是面板寬÷畫面寬,預設 1.6)、 --width / --height(畫面區的上限,預設 1920 / 1080)。

原片太小就放大畫面區:面板是跟著畫面區算的,640×360 的片子面板只有 640×288, 四列擠在一起讀不了。--scale 2 把畫面區放到 1280×720、面板放到 1280×576,寬高比不動。 預設是 1(只縮不放)。plan / panels / compose / export 都要帶上同一個 --scale。

Step 2 — 渲染面板

node {baseDir}/scripts/video-sync.mjs panels shots.json --video <片> \
  --frames frames --lang zh|en [--out panels] [--chrome <路徑>]

產出 static.png(底板)、list-dim.png / list-lit.png(整張鏡頭表鋪開的長圖, 一暗一亮)、layout.json(每行的位置,合成時按它算滾動),外加一張 panels/panel.html—— 用瀏覽器打開它就能預覽面板,#S07 換鏡頭看效果(預覽裡的滾動動效和導出一致)。

改佈局就改 {baseDir}/scripts/panel.css,改完重跑 panels 就是新版面, 不用碰腳本、不用重新想截圖邏輯。樣式約定見 {baseDir}/references/panel-style.md。

Step 3 — 合成

node {baseDir}/scripts/video-sync.mjs compose shots.json --video <片> \
  [--panels panels] [-o out.mp4] [--crf 20] [--ease 0.45]

音軌照搬原片(無聲片自動不接音軌)。合成完 stderr 會報輸出尺寸、時長、版式,核對一眼。

兩步也可以一條龍:

node {baseDir}/scripts/video-sync.mjs export shots.json --video <片> -o out.mp4 --frames frames

Step 4 — 抽幀驗收 ⛔ 不能跳

不要只看合成沒報錯就交。 至少抽三幀看看資訊對不對得上畫面:

for t in 5 30 60; do ffmpeg -v error -y -ss $t -i out.mp4 -frames:v 1 -q:v 3 /tmp/check-$t.jpg; done

看三件事:這一幀的畫面屬於哪一鏡、面板上的鏡號是不是同一個、高亮行有沒有跟著走。 對不上通常是 shots.json 和原片不是同一條,或者 --video 指錯了。

彙報一句話說清:輸出路徑、尺寸、時長、版式、多少鏡、面板哪幾張沒渲出來(如果有)。


邊界

  • 滾動只發生在切點:滾 --ease 秒到位就停住,鏡頭裡面板是靜止的。 真要做「全程勻速爬」也行(改 motionPlan 的分段),但長鏡頭會一直晃眼睛
  • 需要一個無頭瀏覽器(Chrome / Chromium / Edge)。這是「佈局能隨便改」的代價: 換成 ffmpeg 的 drawtext 畫面板,中文換行、縮圖、高亮全得自己實現,改個版式要改濾鏡圖
  • 詞表(景別 / 類別 / 運鏡 / 轉場)在本 skill 裡自帶一份,不跨目錄 import—— skill 要能整個拷走。video-shots 那邊加了新詞,這邊也要加,不然顯示成枚舉鍵
  • 渲染面板固定三張截圖,和鏡頭數無關:53 鏡約 12 秒。合成按片長走,203 秒的片子約 75 秒

自測

node {baseDir}/scripts/selftest.mjs

122 項斷言,不碰 ffmpeg、不開瀏覽器:幾何(橫/方/豎、偶數邊長、上下限、旋鈕)、 面板頁面的資料契約(詞表下發、節奏角色、縮圖有沒有才給、轉義)、 動畫命令(每條都必須短——表達式長了 ffmpeg 直接配置失敗)、ffmpeg 參數。 改完腳本先跑這個。

Individual skills in this repo

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

eternityspring/reelbench-skills

把一条视频重建成「只有画面和声音」的干净文件——**源片的元数据一概不搬**: GPS、设备型号、账号 ID、创建时间、章节、GoPro 的遥测轨,全部留在原地。 走的是白名单而不是黑名单:不列要删什么,只说带什么过去(画面一条流、声音一条流), 隐私保证来自结构,不来自枚举。 难点不在容器 tag,在**看不见的那几层**:x264 把完整编码参数写成 SEI 塞在码流里、 AAC 把版本号写进 DSE、avc1 的 compressorname 里还有一份——`ffprobe` 一个都看不见。 五个藏身处逐一堵死,每一处都有实测。 默认 `--mode copy`:**画面逐字节照搬**(cmp 验证过),只重编音频,53 秒的片子 1.3 秒跑完; `--mode encode` 完整重编码,多杀掉码流域的东西。 验收不靠声称:把源片所有元数据字符串当「针」,在输出文件里做**字节级扫描**, 扎到一根就红。12 道门全部由脚本确定性检查。 零依赖、零 API key,只要 node 和 ffmpeg。 Use when asked to 清元数据、去元数据、抹掉视频信息、视频隐私、去水印信息、 strip video metadata、remove exif from video、scrub video。

eternityspring/reelbench-skills

拉片:把一条成片拆成逐镜头的分析表——每个镜头的时长、景别、类别、运镜、画面。 分工刻在骨子里:**能量的都由代码量**(切点来自 ffmpeg 场景检测,时长是切点相减, 运动量是逐帧差分的中位数),模型只判断它真正该判断的那几件事(景别 / 类别 / 运镜 / 画面 / 节奏), 然后每一条判断都被代码当场对账——**声称推拉摇移却实测几乎不动,门直接拦**。 看片走联系表(每镜起手帧 + 收尾帧各拼一张大图,一屏二十几个镜头,a/b 对照就是运镜), 不是一张张翻。检测漏刀多刀用 recut 补刀并刀,自动重编号重算时长,手改边界过不了门。 产出 shots.json + Markdown 镜头表 + **单页交互式拉片报告**:内嵌播放器(播放时同步高亮镜头、 点镜头跳转)、镜头节奏带、可搜索可筛选可排序的镜头表(列表 / 卡片两种视图、首尾关键帧并排、 点图开大图)、景别类别运镜分布、出场人物、质量门、导出 JSON。单文件零依赖,离线双击能开。 15 道质量门全部由脚本确定性检查。 零依赖、零 API key,只要 node 和 ffmpeg。 Use when asked to 拉片、拆镜头、分析视频镜头、镜头时长、景别、运镜、镜头表、 video shot breakdown、shot list from video。

相關技能