关于 hyperframes-captions
hyperframes-captions 是用于 Hyperframes 项目的字幕制作技能,面向生成视频字幕的创作者。它指导逐词时间戳、内容适配的样式,以及防止字幕溢出或残留的动画处理。
主要功能
- 01按音频语言选择 Whisper 模型
- 02根据转录内容判断字幕风格
- 03按词设置视觉强调效果
- 04按语气与停顿分组字幕
- 05测量文本以避免溢出
- 06确保字幕组按时隐藏
适用场景
- 01为视频语音生成同步字幕
- 02为营销或教程内容选择字幕样式
- 03突出品牌名、数字和行动号召
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ heygen-com/ hyperframes --skill hyperframes-captions安装后在 Claude Code 中输入/hyperframes-captions确认已加载。
附带文件dynamic-techniques.mdtranscript-guide.md
详细介绍
字幕
语言规则(不可妥协)
除非用户明确说明音频为英语,否则绝不要使用 .en 模型。 .en 模型(small.en、medium.en)会将非英语音频翻译成英语,而不是转录。这会在不知不觉中破坏原始语言。
转录时:
- 如果用户说明了语言 → 使用
--model small --language <code>(不带.en后缀) - 如果用户说明音频是英语 → 使用
--model small.en - 如果语言未知 → 使用
--model small(不带.en,不加--language)——whisper 会自动检测
默认模型是 small(不是 small.en)。 只有在用户明确说明音频为英语时,才添加 .en。
分析口述内容,以确定字幕风格。如果用户指定了风格,就采用该风格。否则,根据转录文本判断语气。
转录文本来源
项目的 transcript.json 包含一个已规范化的单词数组,并带有单词级时间戳:
[
{ "text": "Hello", "start": 0.0, "end": 0.5 },
{ "text": "world.", "start": 0.6, "end": 1.2 }
]
这是字幕合成唯一使用的格式。请直接使用:
const words = JSON.parse(transcriptJson); // [{ text, start, end }]
有关转录命令、whisper 模型选择、外部 API(OpenAI、Groq)和支持的输入格式,请参阅 transcript-guide.md。
风格判断(默认——未指定风格时)
选择风格前,请先阅读完整的转录文本。风格应由内容决定,而不是套用模板。
四个维度
1. 视觉观感 — 整体美学气质:
- 企业/专业类脚本 → 干净、简约、克制
- 充满活力/营销类脚本 → 大胆、有冲击力、效果突出
- 讲故事/叙事类脚本 → 优雅、温暖、富有电影感
- 技术/教育类脚本 → 精准、高对比度、结构清晰
- 社交媒体/休闲类脚本 → 活泼、动感、亲切
2. 配色方案 — 根据内容的情绪确定:
- 高能量内容使用深色背景搭配明亮点缀色
- 专业或平静的内容使用柔和/中性色调
- 使用高对比度(黑底白字、白底黑字)确保清晰易读
- 使用一种强调色突出重点,而不是多种颜色
3. 字体气质 — 关注排版特点,而非具体字体名称:
- 强调效果和能量时使用粗重/窄体
- 现代、专业风格使用简洁的无衬线字体
- 友好、亲切的风格使用圆润字体
- 优雅、叙事风格使用衬线字体
4. 动画特征 — 单词如何出现和消失:
- 有力、充满活力的效果使用缩放弹出/猛然出现
- 平静或专业的效果使用柔和淡入/滑动
- 强调重点时逐词显示
- 技术或叙事节奏使用打字机效果
单词级样式
扫描脚本,找出值得采用独特视觉处理的单词。并非所有单词都同等重要——有些承载着核心信息。
要检测的内容
- 品牌名/产品名 — 使用更大的字号、独特的颜色和特别的入场效果
- 全大写单词 — 作者有意强调了这些词。可增强缩放效果、添加闪光或使用强调色。
- 数字/统计数据 — 使用粗体字重和强调色。在数据驱动的内容中,数字是关键信息。
- 情绪关键词 — “incredible”“insane”“amazing”“revolutionary” → 使用夸张动画(过冲、弹跳)
- 专有名词 — 人物、地点、事件的名称 → 使用独特的强调色或斜体
- 行动号召短语 — “sign up”“get started”“try it now” → 突出显示、加下划线或使用跳色
应用方法
为每个检测到的单词指定:
- 字号倍率(例如,强调时使用 1.3x,重要时刻使用 1.5x)
- 颜色覆盖(具体的十六进制值)
- 字重/样式变化(更粗、斜体)
- 动画变体(入场过冲、发光脉冲、缩放弹出)
- 标记高亮模式 — 除颜色/缩放之外,还可添加标记风格的视觉强调效果:在单词后方扫过高亮、用手绘圆圈圈出单词、从单词周围放射爆发线,或在单词下方添加涂鸦下划线。请参阅
/marker-highlight技能,了解模式和能量等级对应表。
脚本与样式映射
| 脚本基调 | 字体氛围 | 动画 | 颜色 | 大小 |
|---|---|---|---|---|
| 热血/发布会风格 | 粗重紧凑,字重 800-900 | 缩放弹出,back.out(1.7),快速 0.1-0.2s | 深色背景上的明亮强调色(青色、黄色、酸橙绿) | 大号 72-96px |
| 企业/推介风格 | 简洁无衬线,字重 600-700 | 淡入并向上滑动,power3.out,0.3s | 深色背景上的白色/中性色,搭配单一柔和强调色 | 中号 56-72px |
| 教程/教育风格 | 等宽或简洁无衬线,字重 500-600 | 打字机效果或柔和淡入,0.4-0.5s | 高对比度,尽量少用颜色 | 中号 48-64px |
| 叙事/品牌风格 | 衬线或优雅的无衬线,字重 400-500 | 缓慢淡入,power2.out,0.5-0.6s | 温暖柔和的色调,低不透明度(0.85-0.9) | 较小 44-56px |
| 社交/随意风格 | 圆角无衬线,字重 700-800 | 弹跳,elastic.out,逐词显示 | 活泼的颜色,胶囊形背景使用彩色 | 中大号 56-80px |
按基调分组词语
分组大小会影响节奏。快节奏内容需要快速切换字幕。
- 高能量: 每组 2-3 个词。快速切换以匹配快速表达。
- 对话式: 每组 3-5 个词。符合自然的短语长度。
- 沉稳/平和: 每组 4-6 个词。较长的分组与较慢的节奏相匹配。
在句子边界(句号、问号、感叹号)、停顿(间隔 150ms 以上)或达到最大词数时切分分组——以最先出现的条件为准。
定位
- 横屏(1920x1080): 底部 80-120px 处,居中
- 竖屏(1080x1920): 下半部分,距底部约 600-700px,居中
- 切勿遮挡主体的面部
- 使用
position: absolute——切勿使用 relative(会导致溢出) - 每次只显示一组字幕
字幕图层结构: 使用带边距的全宽容器,而不是 left: 50%; transform: translateX(-50%)。以 transform 居中的方式会使容器宽度收缩到内容宽度,文本较宽或词语缩放时,会导致画面构图边缘处被裁切。
/* ✓ Full-width with margins — safe for scaled words */
#caption-layer {
position: absolute;
bottom: 80px;
left: 80px;
right: 80px;
text-align: center;
overflow: visible;
}
/* ✗ Collapsed width — clips at edges */
#caption-layer {
left: 50%;
transform: translateX(-50%);
}
文本溢出预防
使用 window.__hyperframes.fitTextFontSize() 测量实际渲染的文本宽度,并计算正确的字号。此方法以像素级精准测量取代基于字符数的估算,测量由 pretext 提供支持。
GROUPS.forEach(function (group, gi) {
var result = window.__hyperframes.fitTextFontSize(group.text.toUpperCase(), {
fontFamily: "Outfit",
fontWeight: 900,
maxWidth: 1600,
});
wordEls.forEach(function (el) {
el.style.fontSize = result.fontSize + "px";
});
});
| 选项 | 默认值 | 说明 |
|---|---|---|
maxWidth | 1600 | 容器宽度(px)(横屏为 1600,竖屏为 900) |
baseFontSize | 78 | 起始字号——文本适配时使用 |
minFontSize | 42 | 下限——绝不缩小到此值以下 |
fontWeight | 900 | 必须与 CSS 的 font-weight 一致 |
fontFamily | "Outfit" | 必须与 CSS 的 font-family 一致 |
step | 2 | 每次迭代递减的步长(px) |
fontWeight 和 fontFamily 必须与应用于文本元素的 CSS 完全一致,否则测量结果会不准确。
为强调词预留缩放空间: 如果逐词样式会将单词放大到 1.0x 以上(例如将 "GOLDEN" 设置为 scale: 1.3),放大后的单词所占宽度会超过 fitTextFontSize 测量的宽度。请减小 maxWidth 以作补偿:maxWidth = safeWidth / maxScale。例如,在宽度为 1920px、边距为 80px 的画面中,最大缩放为 1.3x 时:maxWidth = 1760 / 1.3 ≈ 1350。
安全保障(仍需在 CSS 中设置):
- 为字幕容器设置
max-width(从画面宽度缩小,以适应强调词的缩放) - 使用
overflow: visible,不要使用overflow: hidden。隐藏溢出会裁切放大的强调词及其发光效果。应使用减小后的maxWidth并依靠fitTextFontSize。 - 为所有字幕元素设置
position: absolute - 为字幕容器显式设置
height(例如200px)
字幕退出保障
字幕停留在屏幕上是最常见的字幕错误。每个字幕组都必须在退出动画之后设置硬性清除。
// Animate exit (soft — can fail if tweens conflict)
tl.to(groupEl, { opacity: 0, scale: 0.95, duration: 0.12, ease: "power2.in" }, group.end - 0.12);
// Hard kill at group.end (deterministic — guarantees invisible)
tl.set(groupEl, { opacity: 0, visibility: "hidden" }, group.end);
为什么两者都需要? 当卡拉 OK 逐词补间动画与父级退出补间动画冲突、fromTo 入场补间动画锁定的值覆盖后续补间动画,或时间轴拖动停在退出开始与结束之间时,tl.to 退出动画可能无法完全隐藏字幕组。在 group.end 处设置的 tl.set 是确定性的清除操作——它会在精确时刻触发,不产生动画,也不会被覆盖。
自检规则: 构建时间轴后,确认每个字幕组都设置了硬性清除:
GROUPS.forEach(function (group, gi) {
var el = document.getElementById("cg-" + gi);
if (!el) return;
tl.seek(group.end + 0.01);
var computed = window.getComputedStyle(el);
if (computed.opacity !== "0" && computed.visibility !== "hidden") {
console.warn(
"[caption-lint] group " + gi + " still visible at t=" + (group.end + 0.01).toFixed(2) + "s",
);
}
});
tl.seek(0);
将此代码放在 window.__timelines[id] = tl 之前,以便在画面初始化时运行。
参考资料
动态动画技巧(卡拉 OK、clip-path 揭示、重击词、散射退出、弹性入场、3D 旋转、音频响应字幕、基于 pretext 的定位与分组)请参阅 dynamic-techniques.md。
与逐词样式搭配使用的动画文本强调效果(高亮扫过、手绘圆圈、爆发线、涂鸦下划线、素描显现效果)请参阅 /marker-highlight 技能。
转录命令、whisper 模型、外部 API 和故障排除请参阅 transcript-guide.md。
限制
- 结果必须确定。 不使用
Math.random(),不使用Date.now()。 - 与转录时间戳同步。 单词在被说出时显示。
- 同一时间只显示一个字幕组。 字幕组之间不能重叠。
- 每个字幕组都必须在
group.end处设置硬性tl.set清除。 仅靠退出动画并不足够。 - 默认使用 Google Fonts 之前,先检查项目根目录中的字体文件。