Communitygithub.com

skailabinfo/claude-video-harness

从原始录制片段到成片的完整视频剪辑流程:查找重复片段和假启动、剪除静默、修正字幕、为海报抠出人物、生成卡片和贴纸的节拍列表、交付审阅帧、输出定稿、制作封面并归档。运行指令如“剪辑 takes/1.MOV”、“新视频”、“这是片段”。

claude-video-harness 是什么?

此技能专用于将原始录制片段(take)自动化为专业级短视频成品。它围绕“从片段到定稿”的理念设计:首先检查片段质量,检测并删除重复镜头和假启动;然后依据用户定义的编辑品味进行精确剪裁(去除静音、调整语速),同时自动生成人物遮罩(matte)用于海报。技能支持处理字幕修正与关键词语调色、生成由卡片和贴纸组成的节拍列表(bit-list),并通过定制的 React Remotion 合成渲染成片。它适用于需要一致性风格(基于 `brand-kit.md` 和 `editing-taste.md`)和高效重复工作流的创作者,支持 macOS/Linux 上的 Claude Code 等 AI 编码代理。最终交付物包括预览视频、封面图以及结构化归档,便于后续发布。

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

在你喜欢的 AI 中提问

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

文档

新视频:从片段到定稿

开始前:harness.config.json → configured: true(否则运行技能 setup),bash video/scripts/doctor.sh 无 MISSING。阅读 brand-kit.md、editing-taste.md、“口味档案”在 exemplars.md、anti-patterns.md、delivery-specs.md。视频风格仅从用户档案中获取: 是否有海报、卡片、贴纸、B-roll、音效、图形量及节奏。档案中未提及的,请询问用户,不要自行决定。代码的起点是当前 video/src/。

如果 video/public/footage.mp4 已存在于上次视频且未归档到 edits/,请先归档(步骤 11),然后开始。

1. 检查片段

ffprobe -v error -show_entries format=duration:stream=width,height,r_frame_rate:stream_side_data=rotation -of default=nw=1 takes/1.MOV

根据 rotation 判断方向,而非 width(iPhone 竖屏录制约为 1920x1080 + 旋转标记)。查看 3-4 帧(ffmpeg -ss N -i … -frames:v 1 out/peek-N.jpg)。不要进行防抖处理,如果使用三脚架拍摄——vidstab 将引入抖动。仅当明显手持拍摄时:对原始文件进行防抖(vidstabdetect=shakiness=6:accuracy=15 → vidstabtransform=smoothing=25:optzoom=1:interpol=bicubic,-c:a copy;需要含 libvidstab 的 ffmpeg),然后基于防抖后的文件继续操作。

2. 重复镜头和假启动——在剪裁之前

cd video && python3 scripts/chunks.py ../takes/1.MOV

完整的转录会隐藏重复内容,而观众会立即注意到。识别:相邻的包含相同短语的片段(重复——保留最后一个),一二个词被下一片段重新开始的片段(假启动)。向用户展示要剪除的列表及时间码,并征得“同意”。边界应在静音内。

3. 剪裁

cp public/captions.json out/captions.backup.json 2>/dev/null   # cut.py 会覆盖转录
DROP="12.40-15.80" python3 scripts/cut.py ../takes/1.MOV

节奏取自档案中的 cut(根据参考视频调整)。脚本输出 DURATION、拼接帧及“拼接点在语音上”的检查。如果对于用户期望的节奏,拼接点太少,则传递低于档案的参数,例如 … 0.4 0.2(大约 ~0.35 / 0.2);太多则高于档案。完全没有拼接点——房间嘈杂:QUIET=-46。语速快/节奏慢:SPEED=1.1。如果拼接点在语音上,请移动 DROP 或参数,不要留下。

4. 蒙版——立即启动(如果 style.poster.enabled)

TITLE_OUT = cut.py 输出中的第一个拼接点(海报在该帧上淡出),通常为 4-7 秒。蒙版是最耗时的部分(CPU 上约 8 秒/帧,2 个工作线程 ≈ 6 帧/分钟),请在后台启动并在其运行时继续编码:

python3 scripts/matte.py <TITLE_OUT> 2 > out/matte.log 2>&1      # 在后台(run_in_background)

在其运行时不要渲染静态帧,这会拖慢它。等待完成通过 ps -axo command | grep "[m]atte.py",而非 pgrep。脚本会跳过已完成的帧——重启后直接再次运行。

5. 转录

打开 public/captions.json(w、s、e 以秒为单位,em):

  • 修正听写错误:姓名、品牌、术语、英语外来词;缩写保持原样(AI、ROI);whisper 喜欢在尾静默中插入“Спасибо за просмотр” / “Thank you.”——删除;
  • em: 2(如果 style.captions.highlight 为 size 或 both)和 "accent": 1(如果为 color 或 both)——根据含义,按照档案中描述的数量和词汇(brand-kit.md §2、§4)。未描述,请询问用户要强调哪些词。

6. 节拍列表

亲自或通过子代理 script-beats(对于长视频)编写 video/SCRIPT.md:

  • 海报——仅当 style.poster.enabled:使用用户自己的措辞和语气,强调语和引爆点如档案所述;
  • 卡片——如果 style.cards 不是 none,密度依据 editing-taste.md §3(数字 → count;步骤 → num + head;列举 → head + lines 或 row 在单词上带图标);from = 短语首词 + 4 帧;
  • 贴纸 FLOATS——仅当 style.stickers:单字标题,紧凑图标(ART_NAMES);
  • 卡片 pain: true——仅当用户希望“别这样”。

在编码前向用户简要展示节拍列表(内容及位置)——这是他们的视频,他们的决策。

7. 编码

  • src/Composition.tsx:DURATION、TITLE_OUT、KICKER、TITLE、BEATS、FLOATS;Captions from = 第二条短语的开始(如果有海报),否则为 0。
  • src/ui/Footage.tsx:严格按 cut.py 中的拼接点使用 BEATS 表格,全强度(特写 1.16–1.21×,常规 1.06–1.09×)——style.motion.punch 将自身减轻或关闭。何时使用特写:依据 editing-taste.md §4;特写后回复更宽,否则特写效果“粘滞”;如果有海报,则在第一个拼接点使用。
  • 新组件——仅当卡片、贴纸、Photo/Clip/Tag 均无法表达该内容(则使用 scene-builder)。
  • B-roll 来自 Higgsfield——如果已连接且档案要求(brand-kit.md §5):通过 <Clip> 显示(事先裁剪并静音:ffmpeg -an -t <сек>),在插入前检查生成帧上的文字/面部/手部。首先询问用户并说明价格。
  • 音效——仅当 style.sfx:缺失的素材(card、count、end)——通过子代理 audio-agent 依据档案中的描述生成。
  • npm run lint——干净。

8. 审阅帧(蒙版完成后)

为每个卡片和贴纸渲染一个完全组装的静态帧,海报在寿命中期渲染(最后一行文字在头发上方可读),几条字幕帧,最后一帧:

npx remotion still MyComp out/key/f<N>.png --frame=<N> --scale=0.5 --timeout=120000

将这些帧拼接成每行 4 张并附编号标签的列表(PIL;使用含西里尔字母的字体,例如 /System/Library/Fonts/Supplemental/Arial Bold.ttf),显示给用户(SendUserFile)。定稿仅在他们“OK”之后。 列表几分钟,定稿 10-20 分钟。

在显示前自行检查:关键文字不在底部 15% / 顶部 8% 内;无重叠;贴纸不与卡片相交;最后一帧非空且不截断;一切符合用户档案且无多余内容。

9. 定稿

npm run master        # 在后台;等待进程,而非文件出现

脚本自行检查裁剪、计算帧并生成 out/preview.mp4。检查音量:ffmpeg -i out/final-master.mp4 -af ebur128 -f null - 2>&1 | grep -A3 Summary ≈ 目标源自 audio.lufs。向用户发送预览。

定稿修改(“剪掉这句话”)——自行剪辑定稿(使用 ffmpeg trim+concat 基于静音),不要重新裁剪原始片段或重新渲染全部内容;提前告知 ETA。检查接缝:剪除周围 6 秒并通过 whisper 运行——应当恰好拼合出所需的两句话。

10. 封面

如果档案中未提及,询问用户需要哪种封面:带标题的帧(Cover)、视频海报(PosterCover)或自定义。与用户共同选择帧:提供 3-4 张眼睛睁开的清晰帧(ffmpeg -ss <сек> -i takes/1.MOV -frames:v 1 -q:v 2 out/cover-N.jpg)。

  1. 选定的帧 → public/cover-bg.jpg。
  2. rembg i -m birefnet-portrait public/cover-bg.jpg out/cover-matte.png
  3. python3 scripts/cover-sticker.py public/cover-bg.jpg out/cover-matte.png public/cover-cutout.png 20
  4. 在 Root.tsx → Cover defaultProps.lines:用户语言的标题,accent / em 按用户意愿。尺寸自动调整——不要修改字号。
  5. npx remotion still Cover out/cover.png --timeout=120000——显示。

备选:PosterCover——将视频海报作为封面(帧及其剪裁在 poster-bg.jpg / poster-cutout.png)。

11. 归档

edits/<N>/(在项目根目录,而非 video/ 内):Composition.tsx、Footage.tsx、captions.json、SCRIPT.md、cover.png、final-master.mp4、preview.mp4。如果用户希望,下一步执行技能 publish。

Individual skills in this repo

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

相关技能