Communitygithub.com

video-skill

在终端中制作、编辑、检查与理解视频,专为无法观看视频的AI代理设计。适用于制作启动、演示、解说、标题卡、动态图形、照片幻灯片、旅行或活动集锦、GIF、社交短片等视频任务,或分析现有视频内容。

video-skill 是什么?

video-skill 是一个针对 AI 代理(如 Claude Code、Codex)的终端视频技能,旨在让无法直接观看视频的 AI 能够全面处理视频任务。它通过将视频转换为 AI 可读的形式(如帧格联系表、时间戳、元数据)实现“制作、编辑、检查与理解”功能。该技能集成了 OpenFilm(基于 HTML 的视频创作框架,每个镜头对应一个页面,通过时间函数驱动动画,并提供本地编辑器 Studio),用于制作电影;通过 `footage.py` 工具处理手机直出的 HDR、旋转、可变帧率等常见问题,并生成代理文件;利用场景检测和均匀采样生成帧格联系表,方便 AI 审查内容;还包含音视频元数据检查(如音轨响度、编码器、快启动等)和 WebP/GIF 循环导出功能。**主要平台**:macOS(作为 OpenFilm 的主开发环境),但脚本本身跨平台,FFmpeg 作为底层依赖。**工作流程**:制作时先写 HTML 页面,渲染帧后查看联系表再修复;理解视频时先探测元数据,再生成代理文件和帧格联系表及时间戳;交付前用 `footage.py check` 确保兼容性。该技能代替了 AI 直接观看视频的能力,让 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 调用之间传递。

你无法观看视频,因此每一步都将其转换为你可以阅读的内容:你查看的帧和你检查的数字。 制作电影的过程是:编写 → 渲染帧 → 读取联系表 → 修复。理解素材是:探测 → 代理 → 带时间戳的帧格表 + 转录稿 → 判断。交付是一个检查编解码器、帧率、快启动和响度的脚本,因此“它随处可播放”是一个可验证的事实。

首次在 Mac 上使用

请自行运行 sh $S/setup.sh。它会检查 mise 和 ffmpeg(必要时通过 Homebrew 安装 ffmpeg),首次使用时安装固定版本的 OpenFilm 并运行 openfilm doctor。修复它打印出的每个 TODO,或者直接向用户解释清楚。可安全地重复运行。

制作电影:OpenFilm

OpenFilm(MIT 许可证)是一种创作格式:一部电影是一个包含 film.html 的文件夹,该 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 集成值 适用于最终混音(播客、大多数网络视频);流媒体平台通常标准化到 -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 48kHz、快启动):

  • HDR(iPhone 默认录制 HLG:color_transfer=arib-std-b67,BT.2020)。在 SDR 模式下观看时,画面会显得褪色且颜色偏移:朱红色会变成橙色。proxy 会优先使用 macOS 内置的 avconvert 进行色调映射,否则使用 ffmpeg 的 zscale(许多 Homebrew 构建版本中缺失),如果都不行则发出警告。
  • 旋转:手机以带旋转标志的方式横向存储竖屏视频;某些工具会忽略此标志。
  • 可变帧率:标称 24 fps,平均 23.997 fps。帧时间漂移,音频在剪辑后会不同步。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。
  • 保持帧格表的长边不超过约 2500 像素,并一次只读取几张;对于长时间素材,可将帧格表分发给子代理,每个子代理为每个格子 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)。通过时间将单词与帧关联起来。专有名词可能会出错(如“torii”变成“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 之前(快启动:边下载边播放)、时长、响度 ±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 代码检查/布局/对比度门控、快照功能、Claude Code 插件
RemotionReact 组件成熟,拥有官方代理技能;源代码可用的许可证,超过一定规模的公司需要购买许可
Manim(MIT 许可证)Python 场景数学和图表解说器
MoviePy(MIT 许可证)/ 原始 ffmpegPython / 滤镜图简单的剪辑和叠加效果;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 …
信任 look 的检查结果而不打开其输出的 PNG读取帧格表;检查通过并不代表布局没问题
直接剪辑或查看 iPhone 素材先 probe,然后 proxy:HDR、旋转和 VFR 都会带来麻烦
将主 MP4 文件发送到聊天工具使用 share 命令,然后对副本进行 check
为 README 或页面生成 GIF使用 WebP,大小约为 1/4
升级后 Studio 状态过时停止旧的 studio/server/main.mjs 进程(pgrep -fl openfilm);一个 Studio 实例对应两个进程

相关技能