mcpField
C
camera-3d-captions

camera-3d-captions

github.com/heygen-com创意与媒体236282 次安装5 周前更新
代码仓库

关于 camera-3d-captions

用于 HyperFrames 的技能,可为固定机位的访谈画面制作逐帧渲染的 3D 深度字幕。适合希望文字环绕人物并穿插前后的剪辑创作者,而非制作普通字幕。

主要功能

  1. 01逐帧渲染 3D 镜头与文字
  2. 02深度分组、文字环绕与穿越
  3. 03利用人物遮罩实现文字遮挡
  4. 04按词语时间点制作字幕动画
  5. 05可选手绘文字精灵

适用场景

  1. 01为固定机位访谈画面添加深度字幕
  2. 02制作随语音环绕人物的文字动画
  3. 03创作环绕、阶梯或穿越式文字序列

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/heygen-com/hyperframes-community-skills --skill camera-3d-captions

安装后在 Claude Code 中输入/camera-3d-captions确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/kit/
cam3d.js
finish.js
tables.js
references/
recipes.md
worked-film.html
scripts/
font-metrics.py
frame-bounds.js
glyph-gaps.js
prep-take.sh
scripts/hand/
build-sprites.py
hand-word.anim.js

详细介绍

3D 摄像机字幕

将 After Effects 动效(3D 摄像机、景深、路径文字、Posterize Time 15、运动模糊)重建为 HyperFrames 的确定性逐帧绘制器。一个时钟绘制背景画面、蒙版和每个字形。没有任何内容是 CSS 动画。

适用场景 / 不适用场景

  • **适用:**静态摄像机拍摄的谈话类镜头(虚拟形象或真人)、风景、中景或更广的画面,每段 5–20 s。文字必须在说话者周围的纵深空间中运动。
  • **不适用:**普通字幕、摄像机移动或手持拍摄(蒙版和背景画面的变换都假设镜头固定)、极端特写(头部后方或周围没有空间),或者人物分割模型无法分离的主体。

要求和副作用(完整列表)

  • 工具:
    • Node 22+ 和固定为已测试版本的 HyperFrames CLI,即 npx [email protected](从 registry.npmjs.org 下载)。以下每条命令都使用该确切版本。
    • PATH 中可用的 ffmpeg。
    • Python 3,以及 fonttools、brotli、numpy、pillow。
  • 蒙版:npx [email protected] remove-background 在本地运行。首次运行时,会将人物分割模型(约 170 MB)下载到 ~/.cache/hyperframes/。
  • **渲染时间:**合成会在预览/渲染时从 cdn.jsdelivr.net 加载 GSAP 3.14.2。
  • **文字时钟:**用户已在本地运行的任意词级转录器。起始时间的准确性很重要;普通 Whisper 的起始时间偏晚。
  • **字体:**由用户提供的文件。请确认许可证允许嵌入。
  • **手绘风格(可选):**需要安装并配置 p5-paint-animation 技能(其设置过程会下载固定版本的 puppeteer、Chrome for Testing、p5 和 p5.brush)。build-sprites.py 会以无头模式运行;帧会写入该技能的 out/,之后会被删除。
  • **除此之外无其他要求:**无需凭据,无付费调用,不会上传任何内容。文件只会写入项目目录(assets/、renders/)。

准备(每个镜头一次)

  1. 截取片段并准备背景画面。bash scripts/prep-take.sh <take.mp4> <start_s> <dur_s> <project>/assets 会生成:
    • portion.mp4:音频源。
    • plate-tall.mp4:左右各以反射填充 240 px,顶部填充 480 px,底部填充 240 px,因此快速摇摄、横向移动和拉远都不会露出边缘。
    • person.webm:对应帧的 alpha 蒙版。
    • 随后,脚本会检查背景画面和蒙版是否与片段一致(尺寸、帧率、帧数),任何一项不匹配都会导致失败。
  2. **文字时钟。**片段中每个词的时间,以片段起始处为 0 秒。
  3. **字体。**选择 2–3 种用途(字幕 / 主视觉 / 环绕文字),然后运行 python3 scripts/font-metrics.py assets/metrics.js key=font.woff2[@wght=…,opsz=…] …。
    • 可变字体的轴必须在此处传入,并在 CSS 中固定(font-variation-settings、font-optical-sizing: none)。否则浏览器的 opsz 会随字号变化,导致文字重叠。
  4. **轮廓。**在放置任何内容之前,根据 person.webm 的 alpha 蒙版读取头部框和肩线。

构建

  • 将 assets/kit/{cam3d.js,tables.js,finish.js} 和 metrics.js 复制到项目的 assets/ 目录。
  • references/worked-film.html 是完整的参考影片。它包含两个镜头、一次人物遮挡擦除、两种环绕文字、一次穿越效果、一个终章和调色;其中不包含媒体文件。
  • references/recipes.md 包含按深度排列的组、环绕文字、阶梯式排列和手绘文字的做法。
  • C3.init(metrics, {W, H}):
    • 镜头保留教程中的垂直视场角(F = 1326.1·H/1080),因此 tables.js 在任何宽度下都可直接应用,无需缩放。
    • 对于宽度超过 1440 的帧,将 (W − 1440) / 2 加到 wipe.x。

镜头语法

选取 4–6 个节拍。将每个口语分句拆分成单独的组。

节拍构建方式规则
快速推进camA 表格(从 502 px 低位开始,共 19 f),然后进行 linear 缓慢推进素材 S0 为 1.1–1.3;画面不会停稳
深度分组每个分句设置 2–3 个字幕组,深度为 D 1250 / 1500 / 2200越近越大,阴影也越大;缓慢推进和横移展现视差
主标题置后主视觉词放在素材深度的后置图层,以片头标题样式横跨人物头部头部遮住中间字母;至少 60 % 清晰可读;字母上伸部分位于画面内
视差横移swing 段,tx 420旧布局分 3 步淡出;新布局通过视差进入
人物擦除使用说话者自身的遮罩、brightness(0) blur(),擦除前沿由 wipe.x 控制镜头 A 在擦除带左侧裁切,镜头 B 在右侧裁切;两侧都向外拉开
环绕圆环圆环水平置于说话者前方(中心 Z 2000),从上方倾斜 11–16°,并持续转动单词随说话内容从侧面以较小尺寸进入,绕至前方,然后停稳;下半圆弧翻转,使文字正向可读
穿越镜头短语分别位于 D 1500 / 2000 / 2500,摄影机在它们之间摆动焦点跟随短语
阶梯式收尾推进段;字幕中的每个词沿对角线逐渐变深、变小推进使近处的文字彼此分开

规则

  • 运动:
    • 文字以 15 fps 逐帧定格(包括自身动画和它所看到的摄影机)。素材和遮罩每帧都移动。
    • 动态模糊为半个 15-fps 步长内的 7 个残影。转动圆环时使用 shutter: 0.5。
    • 字幕比语音提前 0.2 s,并对齐到 15-fps 网格:fr(t) = 2·round((t − 0.2)·15)。
    • 入场时向上移动 ENTRY:字幕为 30 px,主视觉文字为 110–260 px。圆环文字沿路径缓动经过最后 30–44 px。 只有在尚无相邻文字停稳时,才使用 RING_ENTRY 的过冲效果。
  • 深度:
    • 每个组都要有自己的 D。素材为 3000,字幕为 1250–2400,环绕圆环约为 1100–2700。
    • 深度阴影 [6, 16, 0.5, 1500] 按 1500/(D − cz) 缩放。
    • 在 1080 像素高的画面中,DOF σ = 6.7·|D − focus|/D px。平面字幕的模糊上限为 1.2 px;圆环字形使用完整模糊。
  • 尺寸: size / rise 是着陆摄影机处(tland)的屏幕像素值。精灵图按其 屏幕尺寸渲染。
  • 间距:
    • 圆环文字始终通过 ringLine 排列(屏幕间距;字体:track 1.10,gap 26–30;手绘文字:track 1.0, gap 28)。
    • 转动的圆环每次改变姿态时都要重新排布。
  • 遮挡:
    • 圆环绘制在说话者前方。
    • 只有当某个单词需要从头部后方经过时,才将其拆成后置/前置实例(side、zSplit)。
  • 可读性:
    • 字幕放在画面的暗部。
    • 文字跨过皮肤或浅色衣物时,添加深色光晕。
    • 屏幕上不要保留句末点号。
  • 调色(可选): finish.js 提供曲线、针对肤色的饱和度 1.12,以及每帧重新生成的颗粒。将 不透明场景(素材 + 后置文字 + 遮罩)放入带滤镜的包装层中。前置文字使用相同调色,并将颗粒合成在其上方,这样拆分为后置/前置部分的文字仍保持同一颜色(参见 references/worked-film.html)。

风格

  • 编辑风: 使用窄体展示衬线字体,主视觉文字用斜体;字幕用正文衬线字体;采用奶油色加一种强调色。
  • 粗犷风: 主视觉文字使用粗黑体,字幕使用细体,搭配一种高饱和强调色(参见完整示例影片)。
  • 手绘风: 使用 scripts/hand/build-sprites.py 生成 p5.brush 描边动画精灵图:
    • 每个词从其起始时刻开始逐笔显现。
    • 圆环上的词以完整词形排列,旋转至与切线平行,并按深度缩放;圆环本身更大、更扁。
    • 具体做法见 references/recipes.md。

验证

  1. npx [email protected] check . --no-contrast。幽灵图层会导致 WCAG 对比度检查失败;鞭甩和擦除接缝按设计会重叠。
  2. 在预览页中粘贴 scripts/frame-bounds.js 并运行 __frameBounds(0, dur)。
    • 必须返回 []:可见期间,连续 5 步或更长时间都没有组超出画面。
  3. 粘贴 scripts/glyph-gaps.js 并在静止时运行 __glyphGaps(t)。
    • 单词之间不能相互接触。
    • 平直的单词测量结果应为一个框(下伸部会造成误报)。斜体 f 的悬伸部分读数为负。擦除带两侧的单词都应显示。
  4. 单词间距:渲染后的单词间距 ≈ 一个空格的字宽。
  5. 对每个节拍进行快照,使用 npx [email protected] render . --crf 12 渲染,并逐节拍检查全分辨率帧。

限制

  • 哑光边缘在细发丝上会闪烁。鞭甩时,镜像补边会短暂显示。
  • 填满画面的说话者身后几乎没有空间:将字幕置于顶部高度,或藏在肩膀后面。
  • snapshot --at 共用一个页面,因此不同捕获之间的颗粒不会重新生成。请通过渲染结果判断颗粒效果。
  • 使用调色和大量幽灵图层进行渲染,耗时约为普通渲染的 2 倍。

评论

支持 Markdown