关于 camera-3d-captions
用于 HyperFrames 的技能,可为固定机位的访谈画面制作逐帧渲染的 3D 深度字幕。适合希望文字环绕人物并穿插前后的剪辑创作者,而非制作普通字幕。
主要功能
- 01逐帧渲染 3D 镜头与文字
- 02深度分组、文字环绕与穿越
- 03利用人物遮罩实现文字遮挡
- 04按词语时间点制作字幕动画
- 05可选手绘文字精灵
适用场景
- 01为固定机位访谈画面添加深度字幕
- 02制作随语音环绕人物的文字动画
- 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.jsfinish.jstables.jsreferences/recipes.mdworked-film.htmlscripts/font-metrics.pyframe-bounds.jsglyph-gaps.jsprep-take.shscripts/hand/build-sprites.pyhand-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。
- Node 22+ 和固定为已测试版本的 HyperFrames CLI,即
- 蒙版:
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/)。
准备(每个镜头一次)
- 截取片段并准备背景画面。
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 蒙版。- 随后,脚本会检查背景画面和蒙版是否与片段一致(尺寸、帧率、帧数),任何一项不匹配都会导致失败。
- **文字时钟。**片段中每个词的时间,以片段起始处为 0 秒。
- **字体。**选择 2–3 种用途(字幕 / 主视觉 / 环绕文字),然后运行
python3 scripts/font-metrics.py assets/metrics.js key=font.woff2[@wght=…,opsz=…] …。- 可变字体的轴必须在此处传入,并在 CSS 中固定(
font-variation-settings、font-optical-sizing: none)。否则浏览器的 opsz 会随字号变化,导致文字重叠。
- 可变字体的轴必须在此处传入,并在 CSS 中固定(
- **轮廓。**在放置任何内容之前,根据
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。
- 镜头保留教程中的垂直视场角(F = 1326.1·H/1080),因此
镜头语法
选取 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。
验证
npx [email protected] check . --no-contrast。幽灵图层会导致 WCAG 对比度检查失败;鞭甩和擦除接缝按设计会重叠。- 在预览页中粘贴
scripts/frame-bounds.js并运行__frameBounds(0, dur)。- 必须返回
[]:可见期间,连续 5 步或更长时间都没有组超出画面。
- 必须返回
- 粘贴
scripts/glyph-gaps.js并在静止时运行__glyphGaps(t)。- 单词之间不能相互接触。
- 平直的单词测量结果应为一个框(下伸部会造成误报)。斜体 f 的悬伸部分读数为负。擦除带两侧的单词都应显示。
- 单词间距:渲染后的单词间距 ≈ 一个空格的字宽。
- 对每个节拍进行快照,使用
npx [email protected] render . --crf 12渲染,并逐节拍检查全分辨率帧。
限制
- 哑光边缘在细发丝上会闪烁。鞭甩时,镜像补边会短暂显示。
- 填满画面的说话者身后几乎没有空间:将字幕置于顶部高度,或藏在肩膀后面。
snapshot --at共用一个页面,因此不同捕获之间的颗粒不会重新生成。请通过渲染结果判断颗粒效果。- 使用调色和大量幽灵图层进行渲染,耗时约为普通渲染的 2 倍。
评论
支持 Markdown