复制安装命令
用 Codex 或 Claude 安装复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它先审查 Skill 页面再帮你安装。
复制前请先查看来源、License 和安全提示。
视频侧的 Claude Code / Codex skill。
用 Codex 或 Claude 安装复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它先审查 Skill 页面再帮你安装。
复制前请先查看来源、License 和安全提示。
来源文件:README.md
视频侧的 Claude Code / Codex skill。
| skill | 干什么 |
|---|---|
| video-shots | 拉片:把一条成片拆成逐镜头的分析表——时长、景别、类别、运镜、画面、节奏。切点与时长由 ffmpeg 量,模型只判断该判断的那几件事,15 道质量门逐条对账 |
| video-sync | 合成带分镜信息的视频:画面一边、分镜信息一边,镜头切了信息跟着切、镜头表自动滚动高亮。横版上下叠、竖版左右并,布局改一份 CSS 就行 |
| video-scrub | 清元数据:把片子重建成只有画面和声音的干净文件,GPS、设备、账号 ID、遥测轨一概不搬。难的是 ffprobe 看不见的三层——SEI、AAC 的 DSE、compressorname。默认画面逐字节照搬,12 道门字节级验收 |
我建了一个付费AI视频交流群,聊 AI 视频的工作流、工具和实操。
有兴趣的加我:微信 hao_dev,添加时备注 github。
git clone https://github.com/eternityspring/reelbench-skills.git
cd reelbench-skills
./scripts/install.sh
软链到 ~/.claude/skills/ 和/或 ~/.codex/skills/(哪个装了就装到哪),git pull 之后立刻生效。
./scripts/install.sh --claude # 只装到 Claude Code
./scripts/install.sh --codex # 只装到 codex
./scripts/install.sh video-shots # 只装某一个 skill
./scripts/install.sh --uninstall # 取消软链
依赖只有 node >= 18 和 ffmpeg / ffprobe(macOS:brew install node ffmpeg)。
零 npm 依赖、零 API key,用当前会话额度。
不想软链就直接拷:cp -r skills/video-shots ~/.claude/skills/——skill 自包含,拷走就能用。
demo-report/ 是拿 demo-video.mp4(202.9 秒的 AI 短片《啥是AI》)真跑出来的完整产物:
53 镜、平均镜长 3.83 秒、每分钟 15.7 切、15 道质量门全绿。
demo-report-en/ 是同一套流程跑一段 287.4 秒的英文片段(--lang en,报告全英文):
46 镜、平均镜长 6.25 秒、最长的一镜 46.92 秒——场景检测在那一段里一刀都没落,
因为它真的是一条不切的长镜头。
报告是单文件交互页:内嵌播放器(播放时同步高亮镜头、点镜头跳转)、镜头节奏带、 可搜索可筛选可排序的镜头表(列表 / 卡片两种视图、首尾关键帧并排、点图开大图)、 统计分布、出场人物、质量检查。零外部依赖,离线双击能开。
demo-report/
├── shots-report.html ← 克隆下来双击就能开
├── shots.json ← 53 镜的拉片主数据
├── shots.md ← Markdown 镜头表
├── track.json ← 逐帧差分的运动曲线(机器证据)
└── frames/ ← 每镜首尾两张关键帧,共 106 张
demo-scrub/ 是 video-scrub 的产出——四段文字,没有视频,因为它的成品和源片
肉眼完全一样,那正是设计目标。值得看的是那份对账,尤其
half.txt:用网上教的标准做法清完,ffprobe 一片干净,
而码流里 x264 写在 SEI 的编码参数串还有 4 处、AAC 的 DSE 里还有 8 处——
任何 ffprobe 命令都看不见它们。
video-sync 的产出在最后面——直接看视频。
287.4 秒的英文片段 + 46 镜分镜信息,1280×1296(原片 640×360,--scale 2 放大)。
镜头切了信息跟着切,列表往上滚、高亮跟着滑:
播放器没出来就直接下载:demo-sync/demo-en-sync.mp4
name: video-scrub
version: 1.0.0
description: |
把一条视频重建成「只有画面和声音」的干净文件——**源片的元数据一概不搬**:
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。
allowed-tools:
- Read
- Write
- Edit
- Bash
- Glob
triggers:
- video-scrub
- 清元数据
- 去元数据
- 元数据
- 视频隐私
- 抹掉信息
- strip metadata
- scrub video
metadata:
license: Apache-2.0
requires:
bins:
- node # >= 18,只用标准库,无 npm 依赖
- ffmpeg # 重封装/重编码、码流过滤
- ffprobe # 探测 tag、流、章节、side data
runtimes:
- claude-code
- codex把一条视频重建成干净文件:画面和声音带过去,元数据一个字节都不带。
{baseDir} = 本文件所在目录。脚本 {baseDir}/scripts/video-scrub.mjs,零依赖,node 直接跑。
清元数据有两种思路,差别是死活:
| 怎么做 | 问题 | |
|---|---|---|
| 黑名单 | 列出要删的字段逐个删(exiftool 那种) | 删不完你不知道的东西——厂商私有的 udta、GoPro 的遥测轨、码流里的 SEI,漏一个就漏了 |
| 白名单 | 不说删什么,只说带什么过去:画面一条流、声音一条流,别的一律不要 | —— |
走白名单,源片的元数据没有任何通道能进来。它不是「被删掉了」,是从来没被搬运。
但 ffmpeg 默认会背叛这个结构两次,必须摁住:
-map_metadata -1gpmd 遥测轨一起带走 → -map 0:v:0 -map 0:a:0?第 2 条是 GoPro / DJI 这类源片的唯一防线:它们的 GPS 不在 tag 里,在一条独立的定时元数据轨上。 清 tag 清不掉,只有「只挑两条流」挡得住。
摁住上面两条,tag 层就干净了,ffprobe 一片安静。但文件里还躺着三处身份串:
| 藏在哪 | 内容 | ffprobe 看得见 |
|---|---|---|
| H.264 的 SEI | x264 完整参数串 cabac=1 ref=3 … crf=23.0 | ✗ |
| AAC 码流的 DSE | Lavc62.28.102 | ✗ |
| avc1 的 compressorname | Lavc libx264 | ✗ |
五个藏身处和各自的堵法见 {baseDir}/references/residue-map.md——每一条都有实测记录,
包括几个「看着该管用其实没用」的坑(-flags:v +bitexact 和 -x264-params info=0 都拦不住 SEI)。
| 模式 | 画面 | 音频 | 速度 | 多杀掉什么 |
|---|---|---|---|---|
copy(默认) | 逐字节照搬 | 重编 | 53 秒的片子 1.3 秒 | —— |
encode | 重编码 | 重编 | 慢得多 | 码流域水印、脆弱隐写 |
音频两种模式都重编——AAC 的版本号写在 DSE 里,那是码流内部,-c:a copy 抹不掉它。
重编一遍很便宜,换来音轨干净。画面则在 copy 模式下真的一个比特都没动(cmp 验证过,
除了被摘掉的 SEI)。
关于水印:encode 比 copy 多杀的是码流域水印和脆弱隐写,这两类在实际素材里少见。
真正要命的鲁棒像素水印(SynthID、影视取证水印)设计目标就是扛住重编码,两种模式都杀不掉。
所以选模式按画质和速度选,别指望重编码能洗掉水印。
擦白之后往回写的那一层:
| profile | 写什么 |
|---|---|
obs(默认) | OBS Studio 的长相。OBS 本来就是用 ffmpeg 封装的,所以这档不是伪造,是保持同类工具的正常外观 |
quicktime | macOS QuickTime 录屏:Core Media Video / Core Media Audio |
screencapture | ScreenCaptureKit 录屏 |
bare | 什么都不写。隐私强度最高——不留任何可被证伪的声明 |
有一件事做不到,写在这里省得再试:容器的 encoder 字段由 muxer 自己占着,
-metadata encoder=Lavf60.16.100 盖不过去,置空也清不掉(实测)。只有
-fflags +bitexact 能让它整个消失。所以 obs 档不伪造版本号,它就让 ffmpeg 写自己的真版本号。
node {baseDir}/scripts/video-scrub.mjs inspect <video>
一屏列全:容器 tag、每条流的 tag 与 side data、章节,以及码流里那几处 ffprobe 看不见的身份串。
末尾会告诉你验收时要拿几根针去扫,以及 SEI 这刀动不动。
先看这一屏再动手。 尤其注意两件事:
data / timecode 流——有就说明源片可能带遥测轨(GoPro、DJI)node {baseDir}/scripts/video-scrub.mjs scrub <video> -o out.mp4
默认 --mode copy --profile obs。常用参数:
--mode encode # 完整重编码
--profile bare # 什么都不写,隐私强度最高
--crf 18 # 只在 encode 模式有意义
--date 2026-01-01T00:00:00Z # 指定创建时间,不给就用当前时间
node {baseDir}/scripts/video-scrub.mjs verify <源> <输出>
或者一条龙(日常就用这个):
node {baseDir}/scripts/video-scrub.mjs run <video> -o out.mp4
验收的核心是一句话:前面全是「我调了正确的参数」,属于声称;这一步是「我扫了,真没了」,属于证明。
做法是把源片所有元数据字符串抓出来当「针」——tag 的键和值、handler 名、章节标题—— 在输出文件里做字节级扫描,扎到一根就红。
两条实现上的讲究:
VideoHandler 满世界都是,信息量为零;Lavf58.45.100 钉死了一个版本,
是指纹。分界线是「能不能把范围缩小到某个人、某台设备、某次导出」。| 门 | 拦什么 |
|---|---|
| 字节级残留 | 源片的元数据串扎中了输出 |
| tag 层残留 | 输出的 tag 值来自源片 |
| 位置信息 | 任何 GPS / location 字段 |
| 设备与软件标识 | make / model / software / artist / comment 之类 |
| 源片时间戳 | 输出的 creation_time 等于源片的 |
| 旋转矩阵 | encode 模式下旋转没烘进画面(copy 模式跳过——删了画面就是歪的) |
| 流构成 | 混进了 data / timecode / 附件流 |
| 章节 | 章节跟过来了 |
| 码流身份串 | SEI / DSE / compressorname 里还有编码器名字 |
| profile 相符 | 剩下的 tag 和声明的 profile 对不上 |
| 时长 | 输出被偷偷截断 |
| 可解码 | 产出了打不开的坏文件 |
ffmpeg 只给得起 NAL 级的粒度——filter_units 按 NAL 类型删,
h264_metadata 也没有「只删某个 SEI payload」的选项。所以 remove_types=6 是
全部 SEI 一起删。而 SEI 里除了 x264 那串垃圾,还住着:
所以脚本的策略是:只在真查到身份串时才动刀,HDR 源片一律不动(会明说没动,
以及为什么)。这个判断由 seiPlan() 做,不需要你操心,但你该知道它在那儿。
不去除水印(鲁棒像素水印重编码也杀不掉,别指望)、不改画面内容(不裁剪不缩放不旋转)、 不伪造设备型号和 GPS(profile 只写工具类信息,不编造拍摄设备和位置)、 不做批量目录扫描(一次一条片子)、不处理非 mp4/mov 之外的容器。
node {baseDir}/scripts/selftest.mjs
117 项断言,不碰 ffmpeg、不碰真文件。12 道门每道都有击穿用例——证明它真的会拦。 改完脚本先跑这个。
评论 (0)
暂无评论,成为第一个评论者吧!