视频剪辑 是做什么的?
原则
- LLM 从原始转录和按需视觉素材进行推理。 唯一值得保留的衍生产物是紧凑的短语级转录文件(
takes_packed.md)。其他所有内容——填充词标记、重拍检测、镜头分类、重点评分——都在决策时实时推断。 → 验证:步骤输出与预期结果一致 - 音频是首要的,视觉素材次之。 剪辑候选来自语音边界和静音间隙。仅在决策点深入分析视觉素材。 → 验证:步骤输出与预期结果一致
- 询问 → 确认 → 执行 → 迭代 → 持久化。 在用户以简单明了的英语确认策略之前,绝不触碰剪辑。
- 泛化。 不要假设这是什么类型的视频。观察素材,询问用户,然后进行剪辑。 → 验证:差异与预期更改一致
- 艺术自由是默认的。 本文档中的每一个具体的数值、预设、字体、颜色、时长、音调结构和技术,都只是来自一个经过验证的视频的实例——而不是硬性规定。阅读它们是为了理解什么是可能的以及为什么它们有效。然后根据素材的实际情况和用户的真正需求,做出你自己的审美判断。你必须做的唯一事情在下面的“硬性规则”部分。 其他一切由你决定。 → 验证:文件内容与预期形状一致
- 自由创造。 如果素材需要本文档未描述的技术——分屏、画中画、下部三分之一身份信息卡、反应剪辑、速度变速、冻结帧、交叉溶解、匹配剪辑、L型剪辑、J型剪辑、呼吸时的速度变速等等——那就去构建它。辅助工具是 ffmpeg 和 PIL。它们可以做格式支持的任何事情。无需等待许可。 → 验证:步骤输出与预期结果一致
- 在向用户展示之前,先验证你自己的输出。 如果连你自己都不愿意发布,就不要展示。
硬性规则(生产正确性——不可协商)
以下规则如果偏离,会导致静默失败或输出损坏。这些不是审美问题,而是正确性问题。请牢记它们。
- 字幕在滤镜链中最后应用,在所有覆盖层之后。否则覆盖层会隐藏字幕。静默失败。 → 验证:步骤输出与预期结果一致
- 逐段提取 → 使用
-c copy进行无损拼接,而不是单遍滤镜图。否则在添加覆盖层时,每个片段都会被双重编码。 - 每个片段边界添加 30 毫秒音频淡入淡出(
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–200毫秒。Scribe 时间戳有 50–100 毫秒的漂移——填充可以吸收这种漂移。快节奏视频填充更紧,电影感视频填充更松。 → 验证:步骤输出与预期结果一致
- 仅使用词级别的逐字 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
设置
ELEVENLABS_API_KEY在项目根目录的.env文件中或环境变量中。如果缺失,询问用户并写入.env。ffmpeg+ffprobe在 PATH 中。- Python 依赖:
pip install -e .。 yt-dlp、manim、Remotion仅在首次使用时安装。- 该技能自带
skills/manim-video/。在构建 Manim 插槽时,请阅读其 SKILL.md 文件。
辅助工具
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.5 秒处断开)。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合成。 → 验证:命令退出代码为 0 -
预览。 运行
render.py --preview。 → 验证:步骤输出与预期结果一致 -
自我评估(在向用户展示之前)。 在渲染输出(而不是源文件)的每个剪辑边界处(±1.5 秒窗口)运行
timeline_view。检查每张图片是否存在以下问题: → 验证:命令退出代码为 0- 剪辑点的视觉不连续性 / 闪烁 / 跳动
- 边界处的波形尖峰(漏过 30 毫秒淡入淡出的音频爆音)
- 字幕被覆盖层遮挡(违反规则 1)
- 覆盖层未对齐或显示错误的帧(违反规则 4)
同时检查:前 2 秒、后 2 秒以及 2–3 个中间点——检查调色一致性、字幕可读性和整体连贯性。对输出运行
ffprobe,验证时长是否与 EDL 预期一致。如果任何项目失败:修复 → 重新渲染 → 重新评估。自我评估最多进行 3 轮——如果 3 轮后问题仍然存在,则向用户标记问题,而不是永远循环。只有在自我评估通过后,才向用户展示预览。
-
迭代 + 持久化。 接收自然语言反馈,重新规划,重新渲染。绝不重新转录。在用户确认后进行最终渲染。将内容追加到
project.md。 → 验证:步骤输出与预期结果一致
剪辑技巧(技术)
- 音频优先。 剪辑候选来自单词边界和静音间隙。
- 保留高潮。 笑声、点睛之笔、重音节拍。将剪辑点延伸到点睛之笔之后,以包含反应——笑声本身就是节拍。
- 说话者交接得益于话语之间的间隙。常用值:400–600 毫秒。快节奏视频使用更短的值,电影感视频使用更长的值。这是审美判断。
- 音频事件作为信号。
(笑)、(叹气)、(掌声)标记节拍。将剪辑点延伸到它们之后。 - 静音间隙是剪辑候选。 静音 ≥ 400 毫秒的间隙通常是最干净的。150–400 毫秒的短语边界在视觉检查后可以使用。< 150 毫秒不安全(可能在短语中间)。
- 剪辑填充示例(本技能附带的产品发布视频):第一个保留词前 50 毫秒,最后一个保留词后 80 毫秒。蒙太奇节奏更紧,纪录片更松。保持在工作窗口 30–200 毫秒内(硬性规则 7)。
- 切勿独立处理音频和视频。 每次剪辑必须在两条轨道上都有效。
打包后的转录(主要阅读视图)
pack_transcripts.py 读取所有 transcripts/*.json 文件,并生成一个 Markdown 文件,其中每段素材是一系列短语级行,每行以其 [开始-结束] 时间范围作为前缀。短语在任何静音 ≥ 0.5 秒或说话者变化处断开。这是编辑子代理读取以选择剪辑的依据——它仅从文本中提供词边界精度,且令牌数仅为原始 JSON 的十分之一。
示例行:
## C0103 (时长:43.0秒,8个短语)
[002.52-005.36] S0 A web agent spends ninety percent of its effort on things that don't matter.
[006.08-006.74] S0 We fixed that.
编辑子代理简报(用于多段素材选择)
当任务是“在多段素材中为每个节拍挑选最佳片段”时,生成一个结构如下的专用子代理。结构是负载承载的;音调形状示例则不是。
你正在剪辑一个 <类型> 视频。请为每个节拍挑选最佳片段,并按节拍的时间顺序(而非源素材剪辑顺序)进行组装。
输入:
- takes_packed.md(所有素材的时间注释短语级转录)
- 产品/叙事背景:<来自用户的 2 句话>
- 演讲者:<姓名、角色、表达风格说明>
- 预期结构:<选择一个原型或自行创造>
- 需避免的口误:<来自预扫描步骤的列表>
- 目标时长:<秒>
常见的结构原型(选择、调整或创造):
- 技术发布/演示: 钩子 → 问题 → 解决方案 → 好处 → 示例 → 号召性用语
- 教程: 介绍 → 设置 → 步骤 → 注意事项 → 总结
- 采访: (问题 → 回答 → 追问) 重复
- 旅行/活动: 到达 → 亮点 → 安静时刻 → 离开
- 纪录片: 论点 → 证据 → 反驳 → 结论
- 音乐/表演: 前奏 → 主歌 → 副歌 → 桥段 → 尾声
- 或自行创造。
规则:
- 开始/结束时间必须落在转录中的单词边界上。
- 为剪辑边界添加填充(工作窗口 30–200 毫秒)。
- 偏好的输出形状: