Communitygithub.com

overlays:与语音同步的图形叠加层

为说话人视频(如编辑类YouTube视频、教程、短视频)添加与语音词语同步的图形元素:下三分之一字幕、全屏引用、章节卡片、动画场景(数字、列表、时间线、文档、电子邮件、GIF)、插图照片、B-roll、自动录制的网站演示以及音效。

overlays:与语音同步的图形叠加层 是什么?

该技能用于在Adobe Premiere Pro中为说话人视频添加与语音精确同步的图形叠加层。它从Premiere项目时间线中提取词语时间戳,确保所有图形(下三分之一、全屏引用、章节卡片、动画场景、GIF、插图照片、B-roll和自动录制的网站演示)与说话人的话语精准对齐。该技能包含约20个Python脚本(如`timeline-from-prproj.py`、`render-segments.py`、`gifs.py`、`screencast-record.py`等),协同工作以进行时间线分析、资产搜索(照片、GIF、B-roll)、音频录制以及最终的XML导入生成。核心原则是只依赖Premiere项目时间线(而非粗剪时间码),并在计划叠加层之前等待用户确认编辑。它要求与配套的`motion-design`技能文件夹相邻放置,后者提供Remotion渲染引擎和动画组件。支持16:9宽屏和9:16竖屏(短视频)格式。该技能基于Claude Code / Cursor / Codex等AI代理工作流设计。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/ThomasHMD/premiere-rough-cut/tree/HEAD/skills/overlays

在你喜欢的 AI 中提问

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

文档

overlays:与语音同步的图形叠加层,放置在Premiere中

两项技能,一个工坊

此处 (overlays):放置和编辑工坊 (motion-design):制作
转录文本、.prproj 时间线、以短语锚点编写的计划唯一的Remotion项目:motion-design/src/,src/illustration/ 中的叠加合成组件(BrandedVideo、LowerThirdTrack、Screencast、Scene、FondAnime)
素材来源:照片、B-roll、GIF(gifs.py)、网页捕获、电子邮件卡片(mail-cards.py)public/:字体、scenes/<video>/(场景媒体)、sfx/(音效)
网站演示录制(screencast-record.py)主题(src/illustration/theme.ts)、音效调色板(reference/sound-palette.md、scripts/make-sfx.py、scripts/son.py)
render-segments.py、screencast-render.py、montage-tella.py:在工坊内部启动渲染,然后将所有内容放入Premiere XML音乐、混音

这两个文件夹必须是邻居(<skills>/overlays 和 <skills>/motion-design):脚本通过 ../motion-design 找到工坊。新的场景组件在 motion-design/src/illustration/scenes/ 中编写;新的音效则放入工坊的合成配方中。 安装(每台机器一次,插件安装):bash "${CLAUDE_PLUGIN_ROOT}/install.sh" --data "${CLAUDE_PLUGIN_DATA}"。 手动安装(四个技能文件夹并排复制):从工具包根目录运行 bash install.sh。插件更新后,工坊的 node_modules 链接会消失:重新运行安装行。详情:工具包的 INSTALL.md。

编辑黄金法则(默认设置,可根据频道调整)

视频由语音主导。图形不重复已经说过的话:它们锚定那些仅凭感觉无法把握的内容(专有名词、引文、地点、标题、数字),或者展示正在谈论的内容(文档、网站、图表)。

两种装饰级别:

  • 轻量:每章节1个高级叠加层 + 每45至60秒1个下三分之一,不在开场(0-30秒)和结尾部分;
  • 密集(演示、调查或教程视频):覆盖画面60%到70%的动画场景,每个场景与词语同步,没有场景静止超过3秒。说话人镜头保持原位。

如果没有说明,询问所需的级别。默认情况下不要做动画:开场(观众决定是否停留)、亲密轶事(动画会破坏情感)、制造悬念的问题、结尾和行动号召、形容词列表。

摄像头上说出的与脚本有偏差的内容(数字、术语、近似值)会在屏幕上更正:粗剪在其报告中标记这一点,计划将正确的值放在语音上,无需新拍。

零号规则:参考时间线是Premiere项目的时间线,绝不是粗剪的时间线

顺序始终是:粗剪 (rough-cut) -> 编辑者在Premiere中审查和修改剪辑 -> 叠加层。两者之间,剪切移动、片段被删除、时长变化:在粗剪上计算的时间会偏移30秒到1分钟,元素会在视频结束后结束。

在粗剪之后硬停止,即使用户说“粗剪然后叠加层,由你决定”:交付粗剪XML,然后等待用户说他们在Premiere中确认了。在此之前,没有计划,没有时间,没有放置。只有不依赖时间的内容可以继续(来源图片和GIF)。

python3 scripts/timeline-from-prproj.py "/path/clip.MOV" --list              # 哪些序列包含该片段
python3 scripts/timeline-from-prproj.py "/path/clip.MOV" --sequence "Derush_v1"
# -> <clip>_transcription.json(SEQUENCE时间内的词语)+ <clip>_timeline.json(映射片段 -> 序列)

它读取所选序列中素材的片段(刻度 = 254016000000/s)并继承 <clip>_Derush_vN_work/words_premiere.json 的词语(项目的转录,已由粗剪重新对齐)。多个序列包含该片段:它拒绝猜测(代码2),询问是哪一个。一个序列中有多个片段:按顺序全部传递(A.MOV B.MOV --sequence "...");每个时间线条目和每个词语都带有 media,输出采用第一个片段的名称。被剪切掉的词语如果开始于该片段内(至少早于剪切点80毫秒),则保留;真正被剪切的词语会破坏指向它的锚点:将锚点移动到前一个词语 + offset。检查最后一个放置的元素是否保持在序列的真实结尾之前。

切勿重复使用粗剪中的 cuts_final.json 或映射。没有Premiere项目(单独的片段):python3 scripts/transcribe.py "/path/clip.mp4"(本地whisper.cpp,在Apple Silicon上处理15分钟素材约需5分钟)。

当用户交回剪辑时,首先进行比较:他们在Premiere中所做的修改是最可靠的反馈。将他们的序列与粗剪XML进行比较,将每个重复出现的差异转化为修复、检查或规则,然后才编写叠加层计划。当用户确认最终剪辑时,对交付的叠加层XML执行相同操作:他们删除、移动(超过2帧)、调整大小或添加的内容(他们粘贴在V1上的自拍素材不计算在内)成为修复、检查或规则。没有删除或移动意味着该交付方法正确:保持它。

流程

0. (可选)B-roll

一个 Brolls/ 文件夹位于片段旁边,文件命名为 NN_description_K.mp4(编号、描述、变体):

python3 scripts/match-brolls.py "/path/clip.mp4"     # -> <clip>_broll-script.json 等待完成

对于每个B-roll:变体(file)、时间(timecode MM:SS,在转录中检查)、durationSec(null = 原始时长)。放置在 V2 轨道上。在网站演示之前运行(--force 覆盖文件)。在选择之前查看变体的联系表(每个变体3帧):文件名经常具有欺骗性(“street-photography-portrait”可能是一段城市夜景的无人机镜头)。切勿将B-roll放在说话人没有字面展示的句子上,并且在B-roll播放时不要有叠加音效。

0 bis. (可选)插图照片

对于引用人物、作品、书籍、地点的视频:

  1. 从视频脚本生成清单:按出现顺序的实体 -> illustrations-manifest.json:
    {"version": 1, "dest": "Illustrations", "items": [
      {"n": 1, "categorie": "reference", "nom": "First Last", "sujet": "portrait", "url": "https://...", "fallback_urls": [], "note": "source: ..."}]}
    
    参考脚本可以是任何格式(文本、Markdown、文档):它提供正确的拼写和要展示的内容。
  2. URL:优先使用免费来源(Wikimedia Commons、官方网站、开放获取博物馆),然后使用 python3 scripts/serp_images.py "Name Title" --num 5 --min-width 1200(通过SerpAPI的Google图片,需要密钥 SERPAPI_API_KEY)。检查图片是否正确(查看缩略图,而不仅仅是页面标题;拍卖页面是陷阱)。如果视频是出售的,检查版权。
  3. 下载:python3 scripts/source-illustrations.py illustrations-manifest.json -> Illustrations/NN-category-name-subject.ext(字节已检查,宽度已测量;如果URL缺失则退出 1)。
  4. 时间安排:python3 scripts/match-photos.py "/path/clip.mp4" -> <clip>_photos-script.json,时间通过模糊搜索转录中的名称自动预填(语音识别会破坏专有名词)。务必手动对照转录重新检查每个时间(模糊匹配可能选中后面的提及而不是第一个);enabled: false 丢弃一张照片。照片放在 V3 轨道上,优先于B-roll(与照片重叠的B-roll会从XML中移除并记录)。

照片处理:绝不裁剪(保持原始比例,竖版保持竖版);照片放在纯色背景上,四周留边(约占画面的86%),而不是充满全屏触碰到上下边缘。清单中不要使用 .webp 格式(Premiere在XML中将其读为零长度媒体:使用 sips -s format jpeg 转换)。宽度低于800像素的照片会显得模糊:render-segments.py 会打印低分辨率警告,在交付前列出这些照片。场景展示的书籍封面是从网上获取的出版商视觉图(其网站、高清样机),绝不是从说话人自己的素材中提取的图像。

当说话人展示一个物体时,不要有任何东西覆盖它。 扫描转录中“这里”、“正如你在这里看到的”、“这个”、“看”等词附近提及作品的地方:说话人正把书或相机举到镜头前。在那个时间段不要放置全屏照片(在交付的剪辑中,编辑者移除了每一个这样的封面);封面照片放在演示之前或之后,或者根本不放。

0 ter. GIF和表情包(基础功能,不是选项)

每2到4分钟一个GIF,用于情绪或自嘲时刻(“这非常困难”、“我完全是编的”),绝不在开场,绝不用来字面说明一个技术句子。一个 gif 场景(叠加层、白色边框、循环播放)在词语出现时到达,并带有音效。

python3 scripts/gifs.py chercher "that's a bug" --planche gifs-sheet.jpg   # 列表 + 编号联系表
python3 scripts/gifs.py prendre <id> --nom bug --public <video>            # 源MP4 + 场景数据

在选择之前查看联系表(GIPHY标题并不说明显示的内容;用英文搜索通常效果更好)。prendre 将MP4(绝不是.gif)下载到 Illustrations/gifs/,保留 gifs.json(每个GIF的来源),将其复制到 motion-design/public/scenes/<video>/gifs/,并打印 gif 场景的 data(src、srcW、srcH、loopSec)。需要密钥 GIPHY_API_KEY(免费)。GIF经常重复使用受保护的作品:对于出售的视频,请避免使用。

1. 片段的帧率和格式(关键)

ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate,width,height -of csv=p=0 "/path/clip.mp4"

当JSON未提供时,render-segments.py 会读取片段的帧率和尺寸。30 fps的JSON在60 fps的片段上会导致所有内容偏移2倍。对于29.97 fps,n个序列帧持续 n x 1.001 / 30 秒,每个渲染必须覆盖其片段(tailFrames 和 TenirFin 组件会处理)。片段以其媒体的帧率写入:Premiere在29.97 fps下读取 <in>(<file> 的帧率),而不是片段的 <rate>;脚本写入 in = round(t x fps x 1000/1001) 并设置 <ntsc>TRUE。

竖版9:16(短视频):相同的流程,相同的JSON。下三分之一会检测竖版并向上移动到字幕区域上方;照片保持完整(背景上的一个条带);16:9的B-roll获得填充宽度的缩放。短视频规则(通过比较交付与最终剪辑得出):照片持续2到3秒(默认2.5秒),下三分之一与其关联的肖像照片时间相同并与之一起开始,除非要求否则不使用库存B-roll,说话人展示物体时不使用封面。在开始系列之前,始终将一个下三分之一渲染为静态图像并合成在灰色帧上以检查竖版布局。

2. 在提出方案前先阅读

阅读整个转录。识别:人名(下三分之一 "nom")、作品标题("oeuvre")、地点("lieu")、术语或运动("term")、强引用(高级 quote-full)、章节宣布(section-title 或章节卡片)、引人注目的数字(stat 场景)、所讨论的文档、交流和网站(证据场景、演示)。每个被提及的名称、作品或书籍都会在某处展示(一个悬挂场景、一张照片、一张卡片),或者写下不展示的原因。用说话人自己的话语(在转录中重新阅读)阅读每个图表的内容,绝不要解释:错误的图表(将档案放在漏斗错误级别上)来自于转述。

3. 每个高级叠加层用一句话构思

“我想看到:大号句子、斜体、左侧强调线、小号署名。”如果描述是“出现的文本”,则它不是高级叠加层:下三分之一,或者什么都不做。

4. 基础目录

类型组件 / 种类轨道数据时长
motion(全屏高级)quote-fullV5 不透明text、author?、source?10-14秒
lower-thirdlower-third-nomV6 Alpha通道name、years?、tag?6秒
lower-thirdlower-third-oeuvreV6title、author、year?6秒
lower-thirdlower-third-lieuV6place、date6秒
lower-thirdlower-third-termV6term、subtitle?6秒
section-titleV6eyebrow?、title4秒
scene见“动画场景”V5 / V6 / V7data、cues跟随语音

一个名称及其作品在10秒内被引用:使用带有作品在 tag 中的单个“nom”下三分之一。说话人自己的引用:quote-full 没有 author(他们的语音签名)。动画以自动淡出结束(最后18帧)。

5. 时间精确到词语(关键)

绝不用估计:在 <clip>_transcription.json 中查找词语并取其 start。元素在词语开始时出现(下三分之一最多可以提前0.5秒;在句子开始时同步会读起来像过早的宣布)。render-segments.py 拒绝没有有效时间的片段,并对照转录检查每个时间(OK / WARN / UNKNOWN)。同时检查JSON中的帧率(第1步)。

6. 在编写前呈现计划

| # | 时间  | 时长  | 类型        | 组件              | 原因                            |
|---|-------|------|-------------|-------------------|--------------------------------|
| 1 | 01:24 | 6秒   | lower-third | lower-third-nom   | 首次提及First Last              |
| 2 | 02:14 | 12秒  | motion      | quote-full        | 第1部分的关键引用                |

在编写JSON和渲染之前等待批准。

7. 渲染和导入

(cd ../motion-design && npm ci)                                   # 一次
python3 scripts/render-segments.py "/path/clip.mp4"               # 全部:渲染 + XML
python3 scripts/render-segments.py "/path/clip.mp4" --lower-thirds-only
python3 s

…

[此处内容已截断]

Individual skills in this repo

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

相关技能