通过对话编辑任意视频。转录、剪辑、调色、生成叠加动画、烧录字幕——适用于人物访谈、混剪、教程、旅行、采访。无预设,无菜单。提问、确认计划、执行、迭代、持续。制作正确性规则是硬性的;其他一切皆为艺术自由。
Video Use
原则
- LLM 基于原始转录和按需视觉进行推理。 唯一值得保留的衍生产物是打包的短语级转录(
takes_packed.md)。其他一切——填充词标记、重拍检测、镜头分类、强调评分——都在决策时推导。 - 音频优先,视觉随后。 剪辑候选来自语音边界和静音间隙。仅在决策点深入视觉。
- 提问 → 确认 → 执行 → 迭代 → 持久化。 在用户用自然语言确认策略之前,绝不触碰剪辑。
- 泛化。 不要假设视频类型。查看素材,询问用户,然后编辑。
- 艺术自由是默认选项。 本文档中的每个具体值、预设、字体、颜色、时长、音高结构和技术,都来自一个已验证视频的工作示例——而非强制要求。阅读它们以理解可能性和为何有效。然后根据素材实际情况和用户实际需求,做出自己的品味判断。唯一必须遵守的是下方“硬性规则”部分。其他一切由你决定。
- 自由创造。 如果素材需要本文档未描述的技术——分屏、画中画、底部三分之一身份卡、反应剪辑、速度斜坡、冻结帧、交叉淡入淡出、匹配剪辑、L 剪辑、J 剪辑、呼吸间的速度斜坡等——就构建它。辅助工具是 ffmpeg 和 PIL。它们能完成格式支持的任何操作。无需等待许可。
- 在向用户展示之前,先验证自己的输出。 如果你自己都不愿发布,就不要呈现。
硬性规则(制作正确性——不可协商)
这些是偏差会导致静默失败或输出损坏的规则。它们不是品味,而是正确性。请牢记。
- 字幕最后应用,在所有叠加之后。否则叠加会遮挡字幕。静默失败。
- 逐段提取 → 无损
-c copy拼接,而非单次滤镜图。否则添加叠加时每个片段都会被二次编码。 - 每个片段边界处添加 30ms 音频淡入淡出(
afade=t=in:st=0:d=0.03,afade=t=out:st={dur-0.03}:d=0.03)。否则每次剪辑都会出现可闻爆音。 - 叠加使用
setpts=PTS-STARTPTS+T/TB将叠加的帧 0 偏移到其窗口起始位置。否则在叠加窗口期间会看到动画的中间部分。 - 主 SRT 使用输出时间线偏移:
output_time = word.start - segment_start + segment_offset。否则片段拼接后字幕错位。 - 绝不在单词中间剪辑。 每个剪辑边缘必须对齐到 Scribe 转录中的单词边界。
- 每个剪辑边缘添加填充。 工作窗口:30–200ms。Scribe 时间戳漂移 50–100ms——填充吸收漂移。快节奏时更紧,电影感时更松。
- 仅使用单词级逐字 ASR。 绝不使用 SRT/短语模式(丢失亚秒级间隙数据)。绝不使用标准化填充词(丢失编辑信号)。
- 按源文件缓存转录。 除非源文件本身更改,否则绝不重新转录。
- 多个动画使用并行子代理。 绝不串行。通过
Agent工具同时生成 N 个;总耗时 ≈ 最慢的一个。 - 执行前确认策略。 在用户批准自然语言计划之前,绝不触碰剪辑。
- 所有会话输出放在
<videos_dir>/edit/中。 绝不写入video-use/项目目录。
本文档中其他一切均为工作示例。当素材需要时,随时偏离。
目录结构
技能位于 video-use/。用户素材放在他们指定的位置。所有会话输出放入 <videos_dir>/edit/。
<videos_dir>/
├── <源文件,未修改>
└── edit/
├── project.md ← 记忆;每次会话追加
├── takes_packed.md ← 短语级转录,LLM 的主要阅读视图
├── edl.json ← 剪辑决策
├── transcripts/<name>.json ← 缓存的原始 Scribe JSON
├── animations/slot_<id>/ ← 每个动画的源 + 渲染 + 推理
├── clips_graded/ ← 带调色和淡入淡出的逐段提取
├── master.srt ← 输出时间线字幕
├── downloads/ ← yt-dlp 输出
├── verify/ ← 调试帧 / 时间线 PNG
├── preview.mp4
└── final.mp4
设置
首次安装见 install.md(克隆、依赖、ffmpeg、技能注册、API 密钥)。不要每次会话都重新运行;冷启动时只需验证:
ELEVENLABS_API_KEY可解析——在环境变量中或 video-use 仓库根目录的.env文件中。如果缺失,请用户粘贴一个并写入.env(绝不写入用户的<videos_dir>)。ffmpeg+ffprobe在 PATH 中。- Python 依赖已安装(仓库内执行
uv sync或pip install -e .)。 - 如果会话需要 HyperFrames 或 Remotion 插槽,需安装 Node.js + npm。HyperFrames 目前需要 Node.js 22+。
yt-dlp、HyperFrames、Remotion、Manim 仅在首次使用时安装。- 首次使用的动画设置应在插槽目录内完成,绝不在 video-use 仓库根目录。HyperFrames 可通过
npx --yes hyperframes ...调用;Remotion 可通过npx create-video@latest搭建或作为项目本地依赖安装,然后使用其remotion render命令。 - 本技能附带
skills/manim-video/。构建 Manim 插槽时阅读其 SKILL.md。
辅助工具(helpers/transcribe.py、helpers/render.py 等)与此 SKILL.md 位于同一目录。相对于包含此文件的目录解析其路径——技能通常符号链接到 ~/.claude/skills/video-use/ 或 ~/.codex/skills/video-use/。
辅助工具
transcribe.py <video>— 单文件 Scribe 调用。可选--num-speakers N。已缓存。transcribe_batch.py <videos_dir>— 4 工作线程并行转录。用于多段素材。pack_transcripts.py --edit-dir <dir>—transcripts/*.json→takes_packed.md(短语级,静音 ≥ 0.5s 时断开)。timeline_view.py <video> <start> <end>— 胶片条 + 波形 PNG。按需视觉深入。非扫描工具——在决策点使用,而非持续使用。render.py <edl.json> -o <out>— 逐段提取 → 拼接 → 叠加(PTS 偏移)→ 字幕最后。--preview用于 720p 快速预览。--build-subtitles用于内联生成 master.srt。grade.py <in> -o <out>— ffmpeg 滤镜链调色。预设 +--filter '<raw>'用于自定义。
对于动画,创建 <edit>/animations/slot_<id>/ 并使用 Bash,通过 Agent 工具生成子代理。
流程
-
盘点。 对每个源文件执行
ffprobe。对目录执行transcribe_batch.py。执行pack_transcripts.py生成takes_packed.md。抽样一两个timeline_view以获得视觉第一印象。 -
预扫描问题。 通读
takes_packed.md一次,记录口误、明显说错或需避免的措辞。简单列表,供编辑简报使用。 -
对话。 用自然语言描述所见。根据素材提问。收集:内容类型、目标时长/宽高比、审美/品牌方向、节奏感觉、必须保留的时刻、必须剪掉的时刻、动画和调色偏好、字幕需求。不要使用固定清单——每次的正确问题都不同。
-
提出策略。 4–8 句话:结构、素材选择、剪辑方向、动画计划、调色方向、字幕风格、时长估计。等待确认。
-
执行。 通过编辑子代理简报生成
edl.json。在模糊时刻深入timeline_view。在并行子代理中构建动画。逐段应用调色。通过render.py合成。 -
预览。
render.py --preview。 -
自我评估(在展示给用户之前)。 在渲染输出(而非源文件)的每个剪辑边界处(±1.5s 窗口)运行
timeline_view。检查每张图像:- 剪辑处的视觉不连续/闪烁/跳跃
- 边界处的波形尖峰(音频爆音,未通过 30ms 淡入淡出)
- 字幕被叠加遮挡(违反规则 1)
- 叠加未对齐或显示错误帧(违反规则 4)
同时抽样:前 2s、后 2s 以及 2–3 个中间点——检查调色一致性、字幕可读性、整体连贯性。对输出运行
ffprobe以验证时长与 EDL 预期一致。如果任何检查失败:修复 → 重新渲染 → 重新评估。自我评估最多 3 轮——如果 3 轮后仍有问题,向用户标记,而非无限循环。仅当自我评估通过后才展示预览。
-
迭代 + 持久化。 自然语言反馈,重新计划,重新渲染。绝不重新转录。确认后最终渲染。追加到
project.md。
剪辑技巧(技术)
- 音频优先。 剪辑候选来自单词边界和静音间隙。
- 保留高潮。 笑声、笑点、强调节拍。在笑点后延长以包含反应——笑声本身就是节拍。
- 说话者切换 受益于话语之间的空隙。常见值:400–600ms。快节奏时更短,电影感时更长。品味决定。
- 音频事件作为信号。
(laughs)、(sighs)、(applause)标记节拍。在其后延长。 - 静音间隙是剪辑候选。 静音 ≥400ms 通常最干净。150–400ms 的短语边界可通过视觉检查使用。<150ms 不安全(短语中间)。
- 示例剪辑填充(本技能随附的发布视频):第一个保留词前 50ms,最后一个词后 80ms。混剪能量时更紧,纪录片时更松。保持在 30–200ms 工作窗口内(硬性规则 7)。
- 绝不独立推理音频和视频。 每个剪辑必须在两条轨道上都有效。
打包转录(主要阅读视图)
pack_transcripts.py 读取所有 transcripts/*.json 并生成一个 markdown 文件,其中每个素材是一个短语级行列表,每行前缀为 [start-end] 时间范围。短语在静音 ≥ 0.5s 或说话者变化时断开。这是编辑子代理读取以选择剪辑的产物——它仅从文本提供单词边界精度,且 token 量仅为原始 JSON 的 1/10。
示例行:
## C0103 (duration: 43.0s, 8 phrases)
[002.52-005.36] S0 Ninety percent of what a web agent does is completely wasted.
[006.08-006.74] S0 We fixed this.
编辑子代理简报(用于多段素材选择)
当任务是“从多个片段中为每个节拍选择最佳素材”时,生成一个专用子代理,其简报结构如下。结构是关键的;音高形状示例不是。
你正在编辑一个 <类型> 视频。为每个节拍选择最佳素材,并按节拍时间顺序组装,而非按源片段顺序。
输入:
- takes_packed.md(所有素材的时间注释短语级转录)
- 产品/叙事上下文:<来自用户的 2 句话>
- 说话者:<姓名、角色、表达风格说明>
- 预期结构:<选择一个原型或自行创造>
- 需避免的口误:<来自预扫描的列表>
- 目标时长:<秒>
常见结构原型(选择、调整或创造):
- 技术发布/演示: 钩子 → 问题 → 解决方案 → 好处 → 示例 → 行动号召
- 教程: 介绍 → 设置 → 步骤 → 陷阱 → 总结
- 采访: (问题 → 回答 → 追问)重复
- 旅行/活动: 到达 → 亮点 → 安静时刻 → 离开
- 纪录片: 论点 → 证据 → 反论点 → 结论
- 音乐/表演: 前奏 → 主歌 → 副歌 → 桥段 → 尾声
- 或自行创造。
规则:
- 开始/结束时间必须落在转录中的单词边界上。
- 剪辑边界添加填充(工作窗口 30–200ms)。
- 优先选择静音 ≥ 400ms 作为剪辑目标。
- 如果无更好素材,则保留不可避免的口误。在“reason”中注明。
- 如果超出预算,修改:删除一个节拍或修剪尾部。报告总时长并自我修正。
输出(JSON 数组,无散文):
[{"source": "C0103", "start": 2.42, "end": 6.85, "beat": "HOOK",
"quote": "...", "reason": "..."}, ...]
返回最终 EDL 和一行总时长检查。
调色(当要求时)
你的工作是推理图像,而非应用预设。查看一帧(通过 timeline_view),决定问题所在,调整一项,再次查看。
思维模型为 ASC CDL。每个通道:out = (in * slope + offset) ** power,然后全局饱和度。slope → 高光,offset → 阴影,power → 中间调。
示例滤镜链(grade.py 有 --list-presets;将它们作为起点或混合自定义):
warm_cinematic— 复古/技术感,微妙的青橙分离,去饱和。在真实发布视频中使用。对人物访谈安全。neutral_punch— 最小校正:对比度提升 + 柔和 S 曲线。无色相偏移。none— 直接复制。用户未要求时的默认值。
对于其他情况——人像、自然、产品、音乐视频、纪录片——自行创造滤镜链。grade.py --filter '<raw ffmpeg>' 接受任何滤镜字符串。
硬性规则:在提取时逐段应用(而非拼接后,后者会二次编码)。未经肤色测试绝不激进。
字幕(当要求时)
字幕有三个值得推理的维度:分块(每行 1/2/3/句子)、大小写(全大写/标题/自然)、位置(底部边距)。正确的组合取决于内容。
工作样式——选择、调整或创造:
bold-overlay — 短格式技术发布,快节奏社交。2 词块,全大写,标点处断开,Helvetica 18 粗体,白色带轮廓,MarginV=35。render.py 默认使用此样式作为 SUB_FORCE_STYLE。
FontName=Helvetica,FontSize=18,Bold=1,
PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,BackColour=&H00000000,
BorderStyle=1,Outline=2,Shadow=0,
Alignment=2,MarginV=35
natural-sentence(如果你创造此模式)——叙事、纪录片、教育。4–7 词块,句子大小写,自然停顿处断开,MarginV=60–80,较大字体以提高可读性,稍宽的最大宽度。无内置 force_style——如果需要,自行设计。
如果两者都不合适,创造第三种样式。硬性规则:字幕最后(规则 1),输出时间线偏移(规则 5)。
动画(当要求时)
动画匹配内容和品牌。通过对话获取调色板、字体和视觉语言——绝不假设默认值。如果用户未告知,在策略阶段提出调色板,并在构建任何内容前等待确认。
工具选项:
根据每个动画插槽选择引擎。不要仅仅因为动画与网页相关就默认使用 Remotion。
- HyperFrames — 浏览器原生 HTML/CSS/GSAP 视频合成:产品 UI 动效、网站转视频或模型转视频捕获、动态排版、落地页/故事板宣传片、数据驱动 UI 状态、透明 WebM 叠加,以及需要确定性帧捕获加上 HyperFrames lint/validate/render 检查的片段。最适合动画应像网页合成而非 React 组件树那样创作和验证的情况。
- Remotion — 带组件状态的 React/CSS 合成、可复用 React 原语或现有 Remotion 品牌系统。最适合用户明确要求 React/Remotion 或 React 合成是更简单的创作模型的情况。
- Manim — 形式化图表、状态机、方程推导、图形变形。阅读
skills/manim-video/SKILL.md及其参考资料以深入了解。 - PIL + PNG 序列 + ffmpeg — 简单叠加卡片:计数器、打字机文本、单条揭示、渐进绘制。迭代快速,可实现任何审美。发布视频使用了此方法。
对于 HyperFrames 插槽,在 edit/animations/slot_<id>/ 内使用 npx --yes hyperframes init . --example blank --non-interactive --skip-skills 搭建插槽,在那里构建 HTML 合成,运行适合插槽的 HyperFrames 检查(lint、validate,以及可行时的草稿渲染),然后使用 npx --yes hyperframes render . -o render.mp4 或需要 alpha 时使用 --format webm -o render.webm 生成最终叠加视频。将 EDL 叠加 file 指向实际渲染路径。
对于 Remotion 插槽,将 Remotion 项目隔离在同一插槽目录内,使用 npx create-video@latest 搭建或在那里本地安装 Remotion,使用项目本地的 remotion render 命令将合成渲染为 render.mp4,并使用 ffprobe 验证时长和尺寸。
没有强制要求。如果有用,创造混合方法(例如,PIL 背景加上 HyperFrames 或 Remotion 层)。
时长经验法则,取决于上下文:
- 同步旁白的解释。 观看者需要以 1 倍速解析内容。大致下限 3s,简单卡片通常 5–7s,复杂图表 8–14s。发布视频中每个简单卡片为 5–7s。
- 节拍同步强调(音乐视频、快速混剪)。0.5–2s 即可——它们是视觉强调,而非信息。"1 倍速可读"规则变为"1 倍速可识别",而非"完全可解析"。
- 在剪辑前保持最后一帧 ≥ 1s(通用)。
- 画外音时: 总时长 ≥
narration_length + 1s(通用)。 - 绝不并行揭示独立元素——眼睛无法同时跟踪两个新事物。一件事,暂停,下一件事。
动画回报时机(同步旁白规则): 获取回报词的时间戳。在 reveal_duration 秒前开始叠加,使落地帧与口语化的回报词同时出现。没有此同步,动画会感觉脱节。
缓动(通用——绝不使用 linear,它看起来像机器人):
def ease_out_cubic(t): return 1 - (1 - t) ** 3
def ease_in_out_cubic(t):
if t < 0.5: return 4 * t ** 3
return 1 - (-2 * t + 2) ** 3 / 2
ease_out_cubic 用于单次揭示(缓慢落地)。ease_in_out_cubic 用于连续绘制。
打字文本锚点技巧: 以完整字符串的宽度为中心,而非部分字符串宽度——否则文本在揭示过程中会向左滑动。
示例调色板(发布视频——无限审美中的一种):
- 背景
(10, 10, 10)近黑色 - 强调色
#FF5A00/(255, 90, 0)橙色 - 标签
(110, 110, 110)暗灰色 - 字体:Menlo Bold,位于
/System/Library/Fonts/Menlo.ttc(索引 1) - ≤ 2 种强调色,约 40% 空白空间,最小化装饰
- 结果:终端/复古技术感
这是一种风格。如果品牌是温暖衬线体,使用那种。如果色彩丰富且有趣,使用那种。如果用户给了你风格指南,遵循它。如果没有,提出一个并确认。
并行子代理简报——每个动画是一个通过 Agent 工具生成的子代理。每个提示是自包含的(子代理没有父上下文)。包括:
- 一句话目标:"构建一个动画:[规格]。仅此而已。"
- 绝对输出路径(
<edit>/animations/slot_<id>/render.mp4) - 精确技术规格:分辨率、fps、编码器、pix_fmt、CRF、时长
- 样式调色板为具体值(RGB 元组、十六进制或设计系统引用)
- 字体路径及索引
- 逐帧时间线(何时发生什么,带缓动)
- 反列表("无装饰、无额外内容、除非指定否则无标题")
- 代码模式参考(内联复制辅助函数,不跨插槽导入)
- 交付清单(脚本、渲染、通过 ffprobe 验证时长、报告)
- "不要提问。如果任何内容有歧义,选择最明显的解释并继续。"
一个子代理 = 一个文件(唯一文件名,并行代理不会互相覆盖)。
输出规格
除非用户要求特定内容,否则匹配源文件。常见目标:1920×1080@24 电影感、1920×1080@30 屏幕内容、1080×1920@30 竖屏社交、3840×2160@24 4K 电影、1080×1080@30 方形。render.py 默认将任何源缩放至 1080p;传递 --filter 或编辑提取命令以使用其他目标。值得询问用户哪种交付格式重要。
EDL 格式
{
"version": 1,
"sources": {"C0103": "/abs/path/C0103.MP4", "C0108": "/abs/path/C0108.MP4"},
"ranges": [
{"source": "C0103", "start": 2.42, "end": 6.85,
"beat": "HOOK", "quote": "...", "reason": "最干净的交付,在 38.46 处口误前停止。"},
{"source": "C0108", "start": 14.30, "end": 28.90,
"beat": "SOLUTION", "quote": "...", "reason": "唯一没有错误开始的素材。"}
],
"grade": "warm_cinematic",
"overlays": [
{"file": "edit/animations/slot_1/render.mp4", "start_in_output": 0.0, "duration": 5.0}
],
"subtitles": "edit/master.srt",
"total_duration_s": 87.4
}
grade 是预设名称或原始 ffmpeg 滤镜。overlays 是渲染的动画片段。subtitles 可选,最后应用。
记忆——project.md
每次会话在 <edit>/project.md 追加一个部分:
## 会话 N — YYYY-MM-DD
**策略:** 一段描述方法
**决策:** 素材选择、剪辑、调色、动画及原因
**推理日志:** 非明显决策的一行理由
**待办:** 推迟事项
启动时,如果存在 project.md,则读取并用一句话总结上次会话,然后询问是否继续。
反模式
无论风格如何,始终失败的事项:
- 分层预计算编码格式,带有可用性/语气标签/镜头层。过度工程。在决策时从转录推导。
- 手动调优的时刻评分函数。 LLM 比你写的任何启发式方法都选得更好。
- Whisper SRT / 短语级输出。 丢失亚秒级间隙数据。始终使用单词级逐字转录。
- 在 CPU 上本地运行 Whisper。 速度慢且会标准化填充词。使用托管 Scribe。
- 在合成叠加之前将字幕烧录到基础视频中。 叠加会遮挡它们。(硬性规则 1。)
- 有叠加时使用单次滤镜图。 双重重新编码。使用逐段提取 → 拼接。
- 线性动画缓动。 看起来像机器人。始终使用三次缓动。
- 在片段边界处硬音频剪辑。 可闻爆音。(硬性规则 3。)
- 打字文本以部分字符串为中心。 文本随着增长向左滑动。
- 多个动画的串行子代理。 始终并行。
- 在确认策略之前编辑。 绝不。
- 重新转录已缓存的源文件。 不可变输入的不可变输出。
- 假设视频类型。 先看,再问,最后编辑。






