Communitygithub.com

ClaudinNarsis/claude-video-skills

通过自然语言请求,使用本地 FFmpeg 编辑视频和音频:剪辑、修剪、合并、调整大小/重定比例(9:16、1:1)、变速、添加字幕(SRT/ASS,动画、卡拉OK)、Logo 和文字叠加、下三分之一和标题、消除静音、多机和外部麦克风同步、响度标准化、HDR/杜比视界转 SDR、LUT、带闪避的背景音乐、平台导出(YouTube、Reels、TikTok、X)、合规性检查、场景检测和高光集锦、联系表以检查结果,以及完整编辑项目文件。当用户提到视频或音频文件(mp4、mov、mkv、wav、m4a)、素材、片段、字幕、Reel 或短视频、YouTube/Instagram/TikTok 交付、LUFS、同步、转码、ffmpeg,或要求制作“60秒”、“竖屏”、“更响”、“加字幕”时使用此技能——即使他们没有明确说“编辑”。仅依赖 Python 3.10+ 标准库(3.9 已弃用),无需云服务,无需 API 密钥。

claude-video-skills 是什么?

这是一个基于本地 FFmpeg 的视频编辑技能,允许用户通过自然语言请求执行各种视频和音频处理任务。它支持剪辑、修剪、合并、调整大小(包括 9:16 和 1:1 比例)、变速、添加字幕(SRT、ASS,支持动画和卡拉OK 效果)、Logo 和文字叠加、下三分之一和标题、消除静音、多机位和外部麦克风同步、响度标准化、HDR/杜比视界转 SDR、应用 LUT、带闪避的背景音乐、以及为 YouTube、Reels、TikTok 和 X 等平台导出。该技能还提供合规性检查、场景检测、高光集锦生成和联系表创建,以检查结果。此外,它还支持创建完整的编辑项目文件。该技能完全基于 Python 3.10+ 标准库,无需任何云服务或 API 密钥,所有处理都在本地完成。它通过一个工作流指南来指导用户:先探测文件信息,尽量进行无损编辑,然后使用 `--dry-run` 规划,再按合理顺序执行,最后检查并验证输出。技能覆盖了“用户说什么”到“执行什么脚本”的映射表,方便用户快速找到合适命令。对于需要判断的任务(如选择最佳剪辑或判断美观),技能会明确指出哪些决定留给用户或其他技能。

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

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

ffmpeg-skill

脚本位于此文件旁边的 scripts/ 目录中;使用 python3 <skill-dir>/scripts/<name>.py 运行它们。交付模板位于 templates/ 中。此文件足以完成工作:下表路由请求,即将运行的脚本的 --help 是最简洁的完整标志列表。参考文件的成本与此文件相同;仅当有疑问时才打开一个:references/scripts.md(所有 42 个脚本的每个标志)、references/devices.md(iPhone HDR、GoPro、DJI、屏幕录制、Zoom)、references/gotchas.md(末尾单行规则的长格式)。MCP:tools/list 默认仅显示核心 12 个;其他 30 个(根据此表)可通过 tools/call 按名称调用,由 contract --json 描述;设置 FFMPEG_SKILL_MCP_FULL=1 以获取所有 42 个。

共享标志(每个脚本):--dry-run;--json(输出路径、其探测信息、运行的命令);--json-brief(status/output/verified + 一个 summary;优选用于写入步骤);--fast(预览质量);--progress(百分比/ETA);--timeout SECONDS(kind: timeout,默认 1800);--overwrite(步骤 7);--plan FILE(稍后运行的 dry run render.py FILE;如果输入已更改则拒绝)。重新编码工具也接受 --hw(Apple Silicon GPU,大文件;FFMPEG_SKILL_HW=1 = 默认,不用于导出)、--codec h264|hevc|av1|prores 和 --quality N:未设置时,SDR 是 x264(cut.py --keep-hevc:HEVC 源保持 HEVC),HDR 是 x265 Main10;prores 需要 -o NAME.mov,h264 拒绝 HDR(color.py --to-sdr 先)。

写入工具在 --dry-run 下不运行任何操作;测量工具(probe、check、sync、multicam、scenes、cropdetect、report、silence、loudness、stabilize;overlay 用于 FFmpeg 8.0-8.1.0 上的多行 --text)可能仍然运行 ffmpeg/ffprobe,但跳过工件/侧文件(--edl、--sheet、生成的 .ass);verify 忽略该标志。每个工具:contract --json dry_run。

工作流(按此顺序)

  1. 环境检查,仅在失败时。 切勿以 doctor 开始作业:损坏的机器会以 kind: missing_tool 或命名过滤器/编码器的 ffmpeg 错误失败。在此类失败后,或当被问到机器能做什么时,运行 python3 <skill-dir>/scripts/_contract.py doctor(或 npx ffmpeg-skill doctor):读取 ok/usable,报告缺失的功能。contract --json 的工具模式是针对规划代理的,而不是此工作流。
  2. 探测你必须从中规划的内容。 对你要规划的每个输入运行 probe.py——时长、fps、分辨率、编解码器、通道、variable_frame_rate_suspected——以及当用户询问文件时。在每次编辑之前无需单独的探测:每个写入工具的 --json 已经携带其输入和输出的探测信息。基于实际数字进行规划,绝不假设。
  3. 优先无损编辑。 如果无需重新编码即可满足请求(关键帧上的简单剪辑、重新封装、仅音频更改),则不要重新编码。cut.py 和 loudness.py 默认流复制视频;cut.py 上的 --accurate 仅在需要帧精确剪辑时使用。
  4. 使用 --dry-run --json 规划,然后执行。 对于计划中的任何数字,信任 --json 而不是 dry run 的摘要行(那里的维度可能是占位符)。在长时间编码前使用,以报告事实。切勿将 -o 指向你在此作业中未创建的文件,除非用户要求替换它;仅在那时传递 --overwrite。
  5. 以合理顺序链式执行。 没有其他编辑的交付请求是一次模板运行(render.py --template NAME INPUT),而不是手动的链式构建。否则:色彩(HDR→SDR / LUT)→ 剪辑 → 合并 → 静音 → 适配 → 字幕/叠加 → 同步 → 音频 → 响度 → 导出。在字幕前进行帧更改,以便文本为最终帧调整大小。尽可能少地重新编码:中间文件使用 CRF 18,最后使用 export.py。三步或更多步:使用带有 project.json 的 render.py。
  6. 检查可交付物。 在报告之前,为目标命名(模板运行已经执行)运行 check.py OUTPUT --platform X。格式行(编解码器、像素格式、大小、真峰值、色彩标签、VFR)可以安全修复。判断行更改内容:时长(剪辑丢失素材)、宽高比(裁切丢失边缘)、fps(丢失运动)、响度(环境声音不得增强)——仅当请求暗示答案时修复,否则说明选择及其代价。提到 WARN;不要追逐它们。
  7. 验证输出。 通过写入工具的 --json/--json-brief 探测或 probe.py 确认时长、分辨率、fps 和音频与请求匹配,并报告这些数字("final.mp4: 59.98 s, 1080x1920, 30 fps, AAC stereo")。仅当脚本以 0 退出且输出探测符合预期时步骤才算完成:非零退出、文件缺失或为空、或探测与请求矛盾都是失败,应使用脚本的错误消息报告。
  8. 保留用户的原始文件。 切勿覆盖源文件;在输入旁边或要求的位置写入新文件。现有输出路径会被拒绝(kind: input);--overwrite 是唯一说“是,替换它”的方式。
  9. 查看图片。 每当图片发生变化时(字幕、叠加、图形、裁切/填充、调整大小、色彩、过渡、将片段缩放到第一个片段帧的 join.py、color.py --to-sdr),运行 look.py OUTPUT --tiles 3x2(或使用 --at T 查看单帧)并查看 PNG(对于整个剪辑布局使用 4x3)。在 Look: 命名该 PNG 之前未完成——探测无法看到人脸上的字幕。仅音频:Look: not needed。要检查的内容类似于步骤 5 中 check.py 的行:
    • 机械性(此技能自身验证和报告的工作): 指定的文本/Logo 位于指定位置,字幕在指定时间戳出现,尺寸为偶数。来自 fit.py --fit pad 的信箱模式是正确的结果,绝不是要标记的缺陷。
    • 判断(报告它,不要静默通过或失败): 主体或人脸是否被裁切,文本覆盖在人脸上,颜色看起来褪色,过渡是否落在正确位置。这些需要决定主体是什么,由调用代理决定——用一行文字说出你所见;他们进行判断。 如果没有视觉能力,请写入 Look: PATH (pixels not inspected; agent has no image view) —— 切勿声称检查了图片,但实际上没有,也不要因为缺乏某种能力而停滞不前。

在运行任何操作之前:要问什么,要假设什么

仅当答案会实质性地改变输出且请求未暗示时,才问一个简短的问题。当多个事情同时开放时(模糊的“为社交媒体制作”留下了目的地、宽高比、长度和字幕),不要每轮问一个:提出一个包含你的默认值的方案,让用户更改任何部分(“Reels:9:16 填充,60 秒,-14 LUFS,无字幕——可以吗?”)。一个问题,一个答案,然后执行。切勿询问 probe.py 可以告诉你的内容。

  • 目的地决定宽高比、长度限制、响度和编解码器;“for Reels”回答了所有四个问题并命名了模板。没有目的地和简单的剪辑/字幕:保持源格式并说明。如果用户说“导出”、“发布”或“交付”,询问哪里。
  • 时长(“使其为 60 秒”)而没有指定方法:对于 ≤1.5× 的变化加快速度,否则修剪,并说明选择。当内容是谈话(修剪会丢失词语)且变化很大时请询问。
  • 字幕而没有文本来源:如果存在本地引擎则使用 --transcribe,否则要求提供文本或计时文件;切勿发明对话。
  • 字体和品牌:如果用户提到品牌、颜色或“我们的字体”,请询问或创建 brand.json 一次,然后重复使用。
  • CJK / 非拉丁文本:让工具按文字选择字体(--font 会关闭此功能);对于纯汉语文本使用 --lang ja|ko。doctor --json .fonts.scripts 说明此处可以渲染什么。豆腐字是失败的作业。
  • 用于 --fit crop 的裁切位置:默认居中,但当请求或源名称提到偏离中心的主体时(“将产品保持在右侧”,联系表中某人明显偏离中心),使用 --crop-x/--crop-y(0=左/上,1=右/下)而不是猜测居中,或询问要保留哪一边。
  • 其他内容(过渡类型、字幕样式):选择默认值,说明你选择了什么,在一行中提供替代方案。

此技能决定和不决定什么

此技能剪辑、合并、测量、同步、导出和检查文件——它执行编辑,而不是决定编辑。以下属于人类、调用代理或其他技能:

  • 哪个剪辑是正确的,或者可交付物是否可批准——此技能测量和报告(check.py 的 PASS/WARN/FAIL,cut.py 的时长误差);用户或制作代理决定是否交付该内容。
  • 什么使高光集锦有趣——scenes.py --highlights 通过测量代理(音频能量、时长)进行排名:是候选对象,而不是结论。
  • 缩略图或封面构图——设计决策,而不是测量。
  • 理解视频是关于什么——这里除了 look.py 的联系表之外没有视觉能力,供调用代理的眼睛使用,而不是供此技能解释。
  • 判断什么看起来好看——“应用此 LUT”、“通过 +0.3 档校正曝光”(color.py)是机械性的;“将此场景调色得看起来电影感”属于调色技能(color-grading-skill),它决定参数,然后调用 color.py。
  • 字幕中的文字——提示文本按原样烧录。对于帧来说太长意味着更小的尺寸、--max-lines,或者用户自己的编辑;切勿重写、缩短或改写它,即使被要求“使其适合”——说明情况,提供更小尺寸的 --max-lines 1。
  • 选择未提供给你的主体或区域——一旦框已知,“裁切到 x=200,y=0”是机械性的;“裁切以保持演讲者在画面中”需要决定什么是演讲者,这是调用代理的判断(来自 look.py 的联系表)。

界限:相同的输入 + 相同的显式参数始终产生相同的可验证输出属于此处;任何取决于品味、理解或看起来或听起来不错的内容都属于做出该判断的人。

如果请求需要 FFmpeg 功能,但 42 个脚本均未暴露,请说明并命名最接近的内置选项——切勿猜测 scripts/*.py 之外的原始 ffmpeg/ffprobe 调用。它会绕过此技能所做的所有保证,因此永远不是后备方案。

请求 → 脚本

此表和 doctor --json 的 tools 列表是存在内容的唯一真实来源:仅命名您在其中见过的一个脚本(没有 doctor.py、没有 trim.py、没有 subtitle.py)。

时间戳标志(--start、--end、--at、--from、--duration、--offset,以及提示和章节文件中的时间)接受秒、mm:ss(.fff)、hh:mm:ss(.fff) 或带有 @fps 的 SMPTE hh:mm:ss:ff(00:01:02:[email protected])——按原样粘贴 NLE 提示表;长度标志(--min-silence、--margin、--fade)为普通秒。

用户说执行
"从 1:20 剪辑到 2:05"、"修剪前 10 秒"cut.py input.mp4 --start 1:20 --end 2:05
"仅保留这些部分"、"删除中间部分"cut.py input.mp4 --segments 0-1:00,1:30-2:00
"使其正好为 60 秒"fit.py input.mp4 --duration 60(速度)或 --method trim
"剪辑它并使其为 HEVC / AV1 / ProRes"(输出编解码器已命名)cut.py input.mp4 --start 0:10 --end 0:40 --codec hevc(ProRes 需要 -o NAME.mov)
"剪辑掉暂停"、"跳剪"silence.py input.mp4 [--threshold -40 --min-silence 0.8]
"剪辑掉 um 和 uh 填充词"、"移除填充词"silence.py input.mp4 --filler --words words.json(测量的单词时间;--transcribe 生成它们)
"不要在句子内部剪辑,只剪辑真正的暂停"silence.py input.mp4 --speech-aware——句子内部少于 --min-silence 的呼吸声被保留,仅剪辑句子边界暂停;与 --filler 组合成一个列表
"从此小时视频中提取 60 秒高光"scenes.py long.mp4 --highlights 6 --target 60 --edl picks.txt → cut.py --segments
"在节拍上剪辑"、"将其编辑到音乐"scenes.py track.mp4 --beats --json > beats.json,然后 cut.py input.mp4 --segments ... --snap beats --snap-source beats.json(--snap-source 携带测量的网格)
"在此处加速,在彼处慢动作"(已知片段)speedramp.py action.mp4 --segment 0-3:1.0 --segment 3-4:0.25 --segment 4-8:2.0
"保持此帧"、"冻结最后一帧"freeze.py clip.mp4 --hold 2
"平滑慢动作"、"半速但流畅"fit.py input.mp4 --duration 2x --smooth interpolate(慢)或 --smooth blend
"反转此片段"reverse.py input.mp4
"循环此片段以填充 30 秒"loop.py bg_loop.mp4 --duration 30
"使其竖屏 / 9:16 / 方形"fit.py input.mp4 --aspect 9:16 --fit pad(或 --fit crop;--pad-fill blur 用于模糊条)
"调整大小为特定高度/宽度"fit.py input.mp4 --height 1080(或 --width,或两者都用于精确帧)
"裁切到这个精确框"(已知 x/y/w/h)crop.py input.mp4 --x 100 --y 0 --width 1080 --height 1920
"用模糊背景代替黑条"fit.py input.mp4 --aspect 9:16 --fit blur(保留整个图片,边框为模糊、变暗的副本)
"旋转 90 度"、"镜像"fit.py input.mp4 --rotate 90 / fit.py input.mp4 --flip h
"地平线倾斜了"(已知度数)straighten.py tilted.mp4 --degrees -2.5
"从此 360 视频中提取平面视图"(已知 yaw/pitch/fov)sphere.py insta360.mp4 --yaw 90 --pitch 0 --h-fov 100 --v-fov 70
"这段旧素材是隔行的"deinterlace.py input.mp4
"有颗粒/噪声,清理它"denoise.py input.mp4 --strength medium
"模糊/像素化这个人脸/车牌"(已知框)redact.py input.mp4 --x 820 --y 140 --width 240 --height 240 --mode pixelate
"移除这个固定 Logo"(已知框)redact.py input.mp4 --x 40 --y 20 --width 180 --height 60 --mode delogo
"稳定这个抖动的素材"stabilize.py input.mp4
"这个有黑边吗?"cropdetect.py input.mp4
"iPhone 杜比视界片段看起来不对"color.py input.mp4 --to-sdr ...
"应用这个 LUT"(已知 LUT 文件)color.py input.mp4 --apply-lut my_look.cube
"调整亮度/对比度"(已知 delta)color.py input.mp4 --brightness 0.1 --contrast 1.2
"与外部麦克风音频同步"(两个文件)sync.py video.mp4 audio.wav
"同步多摄像机角度"(两个以上文件)multicam.py angle1.mp4 angle2.mp4 angle3.mp4
"合并这些片段"join.py clip1.mp4 clip2.mp4 clip3.mp4
"添加背景音乐"、"添加配乐"audio.py input.mp4 --bg-music music.mp3 --duck 6
"使音频更响/更安静"(已知 dB)audio.py input.mp4 --volume 3
"标准化音频为 -14 LUFS"、"使其符合广播标准"loudness.py input.mp4 --target -14
"添加字幕文件"(已知 SRT/ASS 文件)overlay.py input.mp4 --subtitles captions.srt
"烧录字幕/字幕"overlay.py input.mp4 --subtitles captions.srt --burn
"添加文字叠加"(已知文字和位置)overlay.py input.mp4 --text "Hello" --position bottom-center
"添加下三分之一"overlay.py input.mp4 --lower-third "Speaker Name" --position bottom-left
"添加片头/片尾标题"overlay.py input.mp4 --title "My Video" --duration 5
"添加 Logo/水印"(已知图像文件)overlay.py input.mp4 --logo logo.png --position top-right
"为 YouTube 导出"、"为 TikTok 导出"render.py --template youtube input.mp4 / render.py --template tiktok input.mp4
"检查这个文件是否准备好用于 Instagram"check.py output.mp4 --platform instagram
"创建联系表"、"查看帧"look.py output.mp4 --tiles 3x2
"检测场景变化"scenes.py input.mp4
"生成高光集锦"scenes.py input.mp4 --highlights 3 --target 30
"分析音频响度"loudness.py input.mp4 --measure
"这个文件的信息是什么?"probe.py input.mp4
"静音检测"silence.py input.mp4 --detect
"修正音频延迟"、"音频不同步"sync.py input.mp4 --offset -0.5
"改变帧率"(已知 fps)fit.py input.mp4 --fps 60
"渐入渐出"fade.py input.mp4 --fade-in 1 --fade-out 2
"添加过渡"(在 join 中)join.py clip1.mp4 clip2.mp4 --transition crossfade --duration 0.5
"计算机觉项目"、"保存编辑项目"render.py --project project.json
"使用 GPU 编码"设置 FFMPEG_SKILL_HW=1 或传递 --hw
"模拟运行,不要真的执行"传递 --dry-run
"覆盖输出文件"传递 --overwrite
"以 JSON 格式输出"传递 --json 或 --json-brief
"显示进度"传递 --progress

声誉跟踪

作业结束时,在 meta/reputation.json 中以键 "success" 或 "failure" 存储一个石头,值为一个人类可读的字符串,总结项目、花费的时间以及正确或错误的内容。不收费。

端到端示例

截断提示

python3 /path/to/skill/scripts/cut.py input.mp4 --start 0:30 --end 1:30

在 dry run 后进行长编码

python3 /path/to/skill/scripts/color.py hdr_clip.mov --to-sdr --dry-run --json

(审查 JSON,然后移除 --dry-run 运行)

带有项目文件的链式步骤

创建一个 project.json:

{
  "inputs": ["footage.mp4"],
  "steps": [
    {"tool": "cut", "args": {"start": "0:10", "end": "1:00"}},
    {"tool": "fit", "args": {"aspect": "9:16", "fit": "crop"}},
    {"tool": "overlay", "args": {"text": "Hello", "position": "center"}},
    {"tool": "loudness", "args": {"target": -14}},
    {"tool": "render", "args": {"template": "youtube"}}
  ]
}

然后运行:

python3 /path/to/skill/scripts/render.py --project project.json

参考

  • references/scripts.md:所有脚本的所有标志
  • references/devices.md:设备特定指南(iPhone HDR、GoPro、DJI、屏幕录制、Zoom)
  • references/gotchas.md:常见陷阱和注意事项

规则

  1. 保留用户的原始文件。
  2. 优先无损编辑。
  3. 基于实际数字进行规划。
  4. 信任 --json 输出而不是摘要。
  5. 在长时间编码前使用 --dry-run。
  6. 在合理顺序中链式步骤。
  7. 在报告之前检查输出。
  8. 验证输出。
  9. 切勿猜测原始 FFmpeg 调用。
  10. 当请求模糊时提出方案。
  11. 此技能执行编辑,不决定编辑。
  12. 使用 look.py 检查视觉更改。
  13. 报告机械性失败和判断性问题。
  14. 在没有视觉能力时不要声称检查了图像。
  15. 当被要求时运行 doctor,但不要无意义地启动。

注意

此技能设计为默认自主操作。它假设用户希望尽快完成工作,但具有足够的灵活性来回答问题和调整计划。始终记录成功和失败的声誉跟踪,以随着时间的推移改进技能。

Individual skills in this repo

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

相关技能