内嵌字幕
一个目录,前端选取(CATALOG.md — 17种身份;其背后的三个引擎是后端细节)。标准模式(默认)构建了一条干净的逐字 轨道(承载大部分文本的下三路字幕)+ 一个 内嵌 高潮部分,在峰值时刻合成到主体后方的场景中。电影模式 是纯内嵌模式——无轨道,每条字幕都合成到主体后方(英雄字体、累积、遮挡作为效果)。主题模式 是一个完整的主题构成——主体范式 × 英雄场景 × 前端特效 × 面板反应,由注册表(themes/README.md)组成:ordnance terminal neonsign stardust stomp。大部分解说/画外音使用 标准模式;内嵌是稀缺的、值得展示的峰值——每个词都内嵌是常见错误;主题模式适用于 VFX 级要求(“炸”、“特效”、“像 AE 做的”)。
操作流程(TL;DR)
下面的创作散文很长;流水线本身很短——所有确定性内容均由计算或编译生成,从不手写:
- 决策门(拒绝不良片段)→ 从 CATALOG.md 中选取 一个身份(17种身份;引擎/编译器通过查找推导——绝不询问模式/类别问题)
hyperframes init(如果项目目录已存在且包含视频,则跳过——matte.cjs/transcribe.cjs会将该目录中的任何视频作为 source.mp4 采用)→bash scripts/prepare.sh <project>(并行执行 matte ∥ transcribe ∥ audio-envelope,然后使用场景调色板/光学/光照处理安全区域 v2——一条命令,无所遗漏)- 创作一个小的创意选择 JSON(先读取
safe-zones.json): 电影模式 →plan.json→fill-timings.cjs→fit-fonts.cjs→make-composition.cjs; 主题模式 →theme.json→make-theme.cjs(轨道/面板/诗/接管范式;anchor是安静的轨道默认值) - 视觉质量检查:
node scripts/preview-frames.cjs <project>→ 大约 2 秒/帧的可靠合成预览(无渲染)。在支付渲染费用前检查 § 视觉质量检查。 render-and-composite.sh→ 门控(时序 / 遮挡+英雄 / 溢出 / 交接) →final.mp4
人们容易忽略的承载规则:
- 轨道(默认)+ 内嵌(升级)。
drop(填充词,不显示)/rail(逐字下三路字幕,在前方,承载大部分文本)/embed(合成在主体后方的高潮词)。标准模式两者都做,仅内嵌峰值。参见 § 字幕模型。 - 视频原样交付(标准/电影模式;主题模式的PLATE 预算是唯一认可的例外——由每个主题 DNA 定义的注册表门控反应节拍(charge-dim、punch、shake、grain),在遮罩合成之后应用,使主体+文本+面板作为一个帧移动)——字幕是唯一添加的内容;遮罩仅让主体遮挡内嵌轨道。绝不调色/重着色/扫描线处理素材。
- 两本规则书:轨道 → references/rail.md(精简),内嵌工艺 → references/composition-craft.md(丰富,仅内嵌)。根据需要浏览。
字幕模型——轨道 + 内嵌
每个口语短语属于以下三种之一:
| 内容 | 显示方式 | |
|---|---|---|
| drop | 填充词——嗯/呃、口吃、自我修正 | 不显示 |
| rail | 默认——普通口语内容(逐字) | 清晰的下三路字幕,在前方,可读。突显词可以加内联 emphasis 高亮(强调色/活跃词弹出)——它保留在轨道上。 |
| embed | 升级的峰值——标题节拍 | 一个合成在 主体后方 的大词(遮罩遮挡),设计有入场和出场 |
轨道承载大部分文本;内嵌是稀缺的、值得展示的峰值。 稀缺性基于 每个节拍/块,而非每个片段:每块(想法)≤1 个英雄,永远不共现,英雄窗口之间至少有一个空气节拍(编译器在低于 0.6 秒时发出警告)。短片段 → 通常 1–2 个;长解说 → 大约每个节部分一个。在多个英雄中,创作的最大者是 APEX(它独自获得完整的锁定内嵌 + 宽度适配提升);较小的英雄是 次要峰值,它们在其列中充当超大强调行(前景,阻尼运动)——不是每个节拍都需要遮罩展示,这正是保持 APEX 为事件的原因。每个词都内嵌仍然是常见错误。
轨道表面身份精确构建此模型(轨道 = rail.html,内嵌 = index.html 中的高潮)。列流身份放弃轨道,并将所有内容变为内嵌风格——仅在要求情绪重于逐字可读性时推荐它们,绝不在解说/画外音中推荐,因为必须阅读文字(CATALOG.md 为每个身份编码了这一点)。
步骤 0——从目录中选取一个身份
一个前端,三个后端引擎。 用户从 CATALOG.md 中选取一个身份(17 个条目:12 个经典 + 5 个主题);引擎、编译器和创作文件通过从目录行查找推导。绝不将“标准 vs 电影 vs 主题”作为问题提出——这些是后端名称(即使有多个引擎,一个产品只有一个用户体验)。目录编码了路由所需的一切:阅读表面、语音、推荐场景、场景需求、真正接近的配对(loud↔ordnance,neon↔neonsign,cream↔stardust)的邻接说明。
流程:探查片段 → 从目录中短名单 2–3 个身份 → 推荐一个并提供一行理由 → 用户选择 → 创作该身份的文件。身份锁定在引擎上(无交叉组合;打开一个身份是一个验证事件——参见 dna/README.md)。
始终先给出推荐,让用户选择后再创作。不要无声地默认。
(完整的身份表位于 CATALOG.md —— 路由的单一事实来源。下面的引擎文档描述了每个后端的创作合同。)
推荐启发式:使用 CATALOG.md 中的“短名单启发式”——它们是身份级别的(例如,“炸”短名单 ordnance/stomp/terminal/loud 并根据应该爆炸的内容来选择),绝不低于类别级别。不确定时 → anchor。
- 电影模式 → 为锁定模板编写
plan.json,由make-composition.cjs编译。 - 主题模式 → 阅读 themes/README.md,创作
theme.json,运行scripts/render-theme.sh(编译 + 渲染 + 面板反应 → final_fx.mp4)。
决策门——首先运行
在两种模式之前,探查视频并分类场景。
ffprobe <video.mp4> # 规格
ffmpeg -ss <t> -i <video.mp4> -vframes 1 sample.png # 在 20%/50%/80% 位置
读取样本。在以下情况下拒绝:
- 多个说话者/硬切(分割并渲染每个镜头,或拒绝)
- 无人类主体(此技能适用于半身/头部特写)
- 时长少于 3 秒,无语音,或面部从未清晰可见——
transcribe.cjs在音频接近静音时发出警告(Whisper 会在静音中幻觉像“Thank you.”这样的词);注意警告并拒绝,而不是为虚构出的词添加字幕 - 源素材已有烧录字幕/副标题/大量文字图形——添加第二个字幕系统会产生冲突,且素材原样交付(无覆盖/修复)。烧录文字通常只在片段中间出现:采样一个 1fps 联系表(
ffmpeg -i in.mp4 -vf "fps=1,scale=160:-1,tile=10x5" sheet.png),不要相信 3 个随机帧。 - 转录文本是垃圾——非母语/重口音语音可能会被转录为自信的乱码。在创作前对
transcript.json进行常识性阅读;如果它无法解析为语言,尝试一次WHISPER_MODEL=medium,否则拒绝(逐字轨道中虚构的词比没有字幕更糟糕)。 - 快速运动的繁忙手持拍摄(遮罩闪烁)
前期探查(零成本,防止最严重的失败)
- 镜头切探查。 在 20%、50%、80% 位置采样帧。如果出现不同的主体/场景,在切之前修剪片段。
- 信箱/竖框探查。 第一帧有黑条?计算安全内容矩形并将字幕放置限制在内部。
- 亮度探查。 采样字幕区域的平均亮度——
低于 60→ 浅色文本直接可读,60-180→ 添加字形遮罩,180+→ 不透明文本 + 遮罩(绝不使用裸露的浅色文本)。电影模式模板是 cream+screen且 LOCKED——使用此探查来 选择一个合适的身份(亮场景 →ink,或不透明轨道anchor主题),绝不重新着色一个身份。 - 按语调推荐身份(您推荐;用户选择——参见步骤 0 + CATALOG.md)。 解说/采访/必须阅读的文字 → 轨道/面板表面身份;诗意/社交/“电影感” → 按语域使用列流身份;“炸 / 特效 / VFX” / 命名世界 → 主题身份。不确定时 →
anchor(文字可读,场景安全)——但提供短名单并让用户选择。
流水线——5 个步骤
1. hyperframes init <project> --non-interactive --video <video.mp4> --skip-skills
2. bash scripts/prepare.sh <project> # 并行执行 matte ∥ transcribe → safe-zones。一条命令。
# → frames_fg/ transcript.json safe-zones.json
3. [智能体步骤——唯一创意步骤] 创作一个小型 JSON;见下方按模式划分
电影模式:创作 plan.json → node scripts/fill-timings.cjs → fit-fonts.cjs → make-composition.cjs
主题模式:创作 theme.json → bash scripts/render-theme.sh <project> (编译 + 渲染 + 面板特效)
4. node scripts/preview-frames.cjs <project> # ~2 秒/帧合成预览 → § 视觉质量检查(在渲染之前)
5. bash scripts/render-and-composite.sh <project> # 门控 → final.mp4 + history/ 快照
(主题模式:跳过步骤 3b/5——render-theme.sh 已经运行编译 + render-and-composite
+ _postfx.sh;交付物是 final_fx.mp4,final.mp4 是面板反应前的版本)
步骤 3 因模式而异:
步骤 3——电影模式(纯内嵌)
- 首先读取
safe-zones.json。 旁白平面放置于zones.hugLeft/hugRight—— 紧贴轮廓的干净条带(远离身体的文本读起来像漂浮的,而不是内嵌的;远角是备用方案,不是默认方案)。英雄默认位于heroAnchor/heroBands.best(居中在主体上,约 30–55% 被遮挡)。recommendation:"fg"将旁白移至前方以便于阅读;只要heroBands.feasible,英雄保持内嵌 —— 如果不可行则降级为heroBands.best(逻辑内置在prepare.sh中)。