mcpField
V
video-add-captions

video-add-captions

github.com/whitetowerai创意与媒体1759 次安装3 周前更新
代码仓库

关于 video-add-captions

video-add-captions 是用于视频字幕规划、样式选择和审核的技能,面向按既定流程处理视频的创作者。它依赖 video-understand 提供的逐词转录与时间线,并生成可审核的字幕计划和透明字幕轨道。

主要功能

  1. 01使用逐词转录和时间线生成字幕
  2. 02选择 Standard 或 Expressive 呈现模式
  3. 03配置字幕预设与强调样式
  4. 04映射剪辑时间并处理字幕断点
  5. 05生成预览、审核证据和字幕轨道

适用场景

  1. 01为经过剪辑的视频生成时间线字幕
  2. 02根据内容选择标准或强调式字幕布局
  3. 03审核字幕样式、位置与生成结果
  4. 04为含说话者画中画的 B-roll 调整字幕位置

安装

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

$npx skills add https://github.com/whitetowerai/cut-as-code --skill video-add-captions

安装后在 Claude Code 中输入/video-add-captions确认已加载。

包含的文件

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

assets/
captions-review.html
assets/style-previews/
index.html
preview-manifest.json
props-boxed-blue.json
props-boxed-gray.json
props-boxed-green.json
props-boxed-pink.json
props-boxed-yellow.json
props-clean.json
props-minimal.json
props-pill-blue.json
props-pill-gray.json
props-pill-green.json
props-pill-pink.json
props-pill-yellow.json
props-shorts-blue.json
props-shorts-green.json
props-shorts-orange.json
props-shorts-pink.json
props-shorts-purple.json
props-shorts-yellow.json
props-social-bold-karaoke.json
props-social-bold.json
props-stroked-black.json
props-stroked-blue.json
props-stroked-green.json
props-stroked-pink.json
props-stroked-yellow.json
examples/
index.html
public/
gsap.min.js

详细介绍

视频添加字幕

依赖项

/video-understand 是前置依赖。请先运行它,以确保字幕使用经过验证的词级转录和规范时间线。 开始前,请确认已安装该依赖。如果未安装,请告知用户缺少此前置依赖,并停止处理媒体。

要求 ffmpeg/ffprobe 位于 PATH 中、Python 已安装 Pillow,以及 Node.js >= 22(用于 .mjs 脚本和按需获取的 npx hyperframes)。hyperframes render/snapshot 会驱动无头 Chrome——它会管理自己的 chrome-headless-shell;如果缓存的版本不可用,则会回退到系统 Chrome(设置 CHROME 可覆盖)。处理媒体前请检查这些依赖。

范围

此技能负责字幕分组、样式选择、审核和透明字幕轨道。它不会进行转录、剪辑、调整时间、调色、重新取景,也不会选择交付音频策略。

如果选择了内容卡片和动态图形中的任一项,请先制作字幕。获批的字幕布局会划定一个预留字幕区域,后续这两项操作都必须保持该区域无遮挡。即使只启用其中一项,这一相对顺序也同样适用。

请先使用 video-understand。如果存在剪辑,请为当前节目时间线添加字幕;不要将源转录中的秒数当作节目时间。

协议输入

必需:

  • work/project.json
  • work/understand/transcript.json,其中包含词级源时间戳
  • work/understand/media.json
  • work/timeline.json
  • work/project.json 中指定的源视频

时间线是唯一的源时间到节目时间映射。所有区间均为半开区间 [start_s, end_s)。scripts/build_captions.py 使用共享的 projectlib.map_transcript_to_timeline;已丢弃源区间中的单词会消失,保留的单词会移动到节目时间,字幕片段始终会在剪辑边界处断开。

持久化输出

work/captions/
|-- captions-plan.json
|-- caption-spatial-context.json (only for eligible B-roll composites)
`-- caption-interaction.json
work/cache/captions/
|-- preview-project/
|-- preview-snapshots/
|-- overlay-project/
`-- overlay-frames/frame_000001.png ...
review/05-captions/
|-- captions.srt
|-- captions-style-review-<UUID>.html
|-- captions-style-review.html
|-- captions-review.html
|-- preview-early.png
|-- preview-middle.png
|-- preview-late.png
|-- preview-no-caption.png
|-- captions-evidence.json
`-- captions-summary.md

生成的 HTML、复制的运行时文件、提取的源帧和叠加帧均为缓存。方案、可选空间上下文、SRT、决策回执和审核证据均为持久化内容。

字幕规划

work/captions/captions-plan.json 是规范的字幕规划,目标为 overlay,并使用节目时间。它记录:

  • timeline_id、program_duration_s 和源转录文本路径;
  • 字幕分组设置;
  • 已批准的样式、决策模式、理由、图库选项和完整解析后的样式;
  • 有源材料支撑的审核证据及批准者;
  • 包含兼容字段 start、end、text、lines 和 words 的字幕;
  • 每条字幕的 program_range 和 source_ranges;
  • 每个映射词的节目/源范围及 clip_id;
  • 包含精确有理数 FPS 和带哈希运行时资源的本地渲染器配方。

生成器也接受旧版顶层字幕数组。它只是独立的兼容适配器;无法表达时间线来源信息,也无法重新生成已批准的协议贡献。

Standard 是默认呈现模式。Standard 规划不需要 presentation 字段,也不得仅为添加该字段而迁移。Expressive 是一种显式呈现模式,而非预设:使用 --presentation-mode expressive 启用。构建步骤随后会添加稳定的字幕 ID、默认词语 semantic_role 值和草稿 presentation 规划框架;但不会猜测布局变体。

Expressive 仅支持 bottom-standard 和 center-emphasis。填写规划框架前,请阅读 reference/caption-rules.md。现有渲染器只使用已完成的 presentation.layout_beats;不会推断位置,也不会在一个节拍内更改布局。

Expressive 字幕也可以定义一个连续的短语级 hero_line。请使用规范的 level: hero;该短语会以金色显示在独立一行,字号为 1.5x。旧版 level: strong 仍可作为输入别名接受,且渲染效果相同,但新编写规划的 Agent 不得输出此值。维护的词语角色 keyword、number 和 contrast 均使用 1.22x;normal 仍为 1.0x。这些样式处理与预设相互独立,不会创建新的样式 ID。有关架构、溢出策略和 Karaoke 规则,请阅读 reference/caption-rules.md。

当某个处于活动状态且已通过审核批准的 B-roll 操作包含已批准或已验证的演讲者画中画合成素材时,字幕可以根据冻结的上游规划、证据、规范化合成素材以及显式子镜头 display_mode,推导出 caption-spatial-context.json。这不会修改或重新选择 B-roll 布局。它会在 Expressive 规划之前对齐字幕边界,并仅解析维护的 preset-bottom、frame-center、panel-center 和仅用于边界的 panel-bottom 放置方式。panel-bottom 仅允许用于紧邻下方中央聚焦面板的 unsplittable_word_boundary;这类字幕会在结构化演讲者矩形下方预留的条带中居中显示。此类字幕会根据与之相交的每个视觉上下文进行检查,而不仅是包含词语中点的上下文。若无此上下文,所有现有 Standard 和 Expressive 放置行为均保持不变。

样式

维护的预设包括 clean、minimal、social-bold、pill、boxed、 stroked 和 shorts。画廊组合 ID 会添加维护的主题,例如 pill-yellow、stroked-blue 和 shorts-green。Karaoke 是一个选项, 不是单独的预设。

默认的委托选择:clean,关闭 Karaoke。只有在目标平台或素材足以支持时, 才选择更具表现力的预设。将特定任务的更改存储在 overrides JSON 中;对于常规 样式反馈,不要修改生成器。

Expressive 支持 semantic-only(关闭 Karaoke)和 semantic-plus-karaoke(开启 Karaoke)。在这两种配置中,语义强调都贯穿 整个字幕条目。在共存模式下,所有高亮模式中的语义强调和当前 Karaoke 单词 都会使用 style.wordHighlight.activeColor 作为前景色;背景高亮则是额外 效果。实际缩放比例为 max(语义缩放比例, Karaoke 激活缩放比例),而不是两者 的乘积。Expressive 从不渲染下划线,包括兼容的 contrast 语义角色。

现有审核协议继续以 semantic-only 作为 Expressive 的主要证据,并单独绑定 semantic-plus-karaoke。兼容性负载字段仍命名为 experimental_comparison; 未经审批协议迁移,不要重命名。

阅读:

  • 修改分组限制前,请先阅读 reference/caption-rules.md;
  • 样式词汇请参阅 reference/caption-style-themes.md;
  • 覆盖项映射请参阅 reference/caption-feedback-mapping.md。

决策模式

两种诚实模式共用同一套由哈希绑定的状态机:

  • human:将复制的完整画廊摘要传给 select,展示所有真实预览证据,并将 复制的完整批准或修订摘要传给 confirm 或 adjust。绑定审核页面的命令 不接受单独的批准短语。
  • agent:仅在用户明确委托字幕决策时使用。先提供非空的委托说明,然后使用 带有非空理由的 agent-select 和 agent-confirm。

在 agent 模式下,human 命令会失败;在 human 模式下,agent 命令会失败。未使用 空间上下文时,Standard 需要四张有来源依据且受维护的图像;Expressive 和支持 复合素材的审核则使用动态证据协议。对来源、计划、时间线、样式、覆盖项、项目 元数据、审核页面或证据的任何更改都会使批准失效;空间上下文、上游 B-roll 修订或已绑定复合素材的更改也会使批准失效。请重新构建受影响的产物并再次审核。

标准工作流

在仓库根目录运行。设置项目路径:

$RepoRoot = (Resolve-Path ".").Path
$SkillRoot = Join-Path $RepoRoot "skills\video-add-captions"
$ProjectRoot = (Resolve-Path "<project-root>").Path
$Work = Join-Path $ProjectRoot "work"
$SourceVideo = "<absolute path from work/project.json>"
$Plan = Join-Path $Work "captions\captions-plan.json"
$SpatialContext = Join-Path $Work "captions\caption-spatial-context.json"
$SpatialArgs = @()
$SpatialReviewArgs = @()
$Receipt = Join-Path $Work "captions\caption-interaction.json"
$Review = Join-Path $ProjectRoot "review\05-captions"
$Cache = Join-Path $Work "cache\captions"
$PreviewProject = Join-Path $Cache "preview-project"
$ComparisonProject = Join-Path $Cache "preview-project-expressive-karaoke"
$OverlayProject = Join-Path $Cache "overlay-project"
$OverlayFrames = Join-Path $Cache "overlay-frames"
New-Item -ItemType Directory -Force -Path (Split-Path $Plan),$Review,$Cache | Out-Null

构建字幕计划前,先询问用户选择呈现模式,除非当前请求已明确指定模式。以用户 当前对话所用的语言呈现问题,同时保留 Standard 和 Expressive 标识符,不作 翻译。将下方的英文源提示保留在此文件中,在当前会话中展示本地化选项,然后 展示并停止:

Choose the caption presentation mode:

1. Standard: Uses stable conventional placement and suits most content.
2. Expressive: Switches between bottom and center placement based on meaning and emphasizes keywords and numbers.

Reply with Standard, Expressive, or "Use the default (Standard)."

在用户回复前,不要运行 build_captions.py。如果用户以任何措辞明确委托选择, 则选择 Standard。构建计划前,说明已选择 Standard 作为保持兼容性的默认选项。

构建节目时间字幕条目和审核 SRT:

python "$SkillRoot\scripts\build_captions.py" `
  "$Work\understand\transcript.json" `
  $Plan `
  "$Review\captions.srt" `
  --timeline "$Work\timeline.json" `
  --source-transcript "understand/transcript.json" `
  --max-chars 42 --max-lines 2 --max-dur 6 --gap 0.6

用户选择 Standard 后,上述命令会生成未更改的 Standard 计划。用户选择 Expressive 后,使用以下参数运行同一命令:

  --presentation-mode expressive

生成草稿提示词后,以只读方式检查当前激活的 B-roll 操作及其绑定的计划。仅当操作处于激活状态、其状态为 approved 或 verified、review.status 为 approved、说话人画中画分析/Agent 输入/预览/许可绑定完整,且至少一个已验证或已规范化的镜头具有维护中的合成布局时,才启用感知合成的定位。空间构建器使用明确的子镜头 display_mode: enabled 来确定说话人几何信息;pure_broll 和缺失的说话人证据都不能推断出说话人矩形。

符合条件时,在填充任何 Expressive layout_beats 或 hero_line 之前,将草稿提示词与每个 B-roll 视觉边界对齐。仅在词间空隙处分割,并以原子方式写回;若边界位于单词内部,则保留完整单词,并记录必须进行审核的证据:

python "$SkillRoot\scripts\caption_spatial_context.py" align `
  --project-root $ProjectRoot --plan $Plan --out-plan $Plan

对于符合条件的项目,准备后续每个关卡都会用到的可选参数:

$SpatialArgs = @("--spatial-context", $SpatialContext)
$SpatialReviewArgs = @("--spatial-context", $SpatialContext, "--project-root", $ProjectRoot)

如果没有符合条件的合成内容,则跳过全部四个空间命令,并将 $SpatialArgs 和 $SpatialReviewArgs 留空。不要创建或附加空上下文。

在开始风格选择或生成预览之前,Agent 必须一次性规划完整的 Expressive 程序:

  1. 阅读转录文本、可用的理解产物、规范时间线、生成的字幕提示词,以及任何用于证明布局变更合理性所需的真实源帧证据。
  2. 填充所有 presentation.layout_beats,为特殊单词标注 semantic_role 值;在有必要时,为某个提示词添加至多一个连续的 hero_line,并使用规范的 level: hero;为每个节拍/主视觉行撰写一条理由,并撰写整体的 presentation.planner.rationale。
  3. 仅当每个提示词都恰好覆盖一次后,才将 presentation.planning_status 设为 complete。
  4. 在生成预览前验证完整计划:
python "$SkillRoot\scripts\build_captions.py" --validate-plan $Plan

对于符合条件的合成内容,只有在最终提示词 ID 和 Expressive 候选方案都已完成后,才构建、验证并附加上下文。这样可以保留上游布局,并将其当前修订版本和哈希绑定到字幕计划中:

python "$SkillRoot\scripts\caption_spatial_context.py" build `
  --project-root $ProjectRoot --plan $Plan --out $SpatialContext
python "$SkillRoot\scripts\caption_spatial_context.py" validate `
  --project-root $ProjectRoot --plan $Plan --context $SpatialContext
python "$SkillRoot\scripts\caption_spatial_context.py" attach `
  --project-root $ProjectRoot --plan $Plan --context $SpatialContext

不要让用户逐条选择提示词的位置。用户会审核现有的 HTML 证据,并仅修正少数异常节拍。在规划完成后再开始交互,可确保现有的字幕计划哈希绑定具有权威性。

启动一种决策模式。对于人工模式,将维护中的离线图库发布到项目审核目录,无需询问用户文件位置:

$StartOutput = node "$SkillRoot\scripts\caption_interaction.mjs" start `
  --state $Receipt --source $SourceVideo --captions $Plan `
  --review-dir $Review --no-open true @SpatialArgs
$StartOutput | Write-Host

start 会打印权威的 captions-style-review-<UUID>.html 项目页面路径和固定问题。captions-style-review.html 仅是一个非权威的最新便捷别名。Agent 必须使用 Caption style review: 后打印的 UUID 路径,将该准确路径赋值给 $StyleReviewPage,并使用对应宿主操作系统的原生命令打开页面:

Windows PowerShell:

$StyleReviewPage = "<authoritative UUID page path printed after Caption style review:>"
Start-Process -FilePath (Resolve-Path $StyleReviewPage)

macOS:

open "$StyleReviewPage"

Linux:

xdg-open "$StyleReviewPage"

如果打开失败,请诊断命令或路径并重试。不要让用户查找页面。展示已打开的图库和原样打印的固定问题,然后展示并停止。在人工从页面复制结构化摘要之前,不要继续。摘要格式如下:

Caption style review
Review: <UUID from the opened page>
Decision: select
Choice: pill-yellow

将用户提供的确切摘要原样传递给 select --response。在 PowerShell 中,单引号 here-string 可以安全保留各行内容:

$StyleResponse = @'
Caption style review
Review: <UUID from the opened page>
Decision: select
Choice: pill-yellow
'@
node "$SkillRoot\scripts\caption_interaction.mjs" select `
  --state $Receipt --response $StyleResponse

上面的代码块展示了格式;请使用用户返回的代码块,包括其审核 UUID 和选择。绝不要推断、规范化或模拟人工响应。

对于明确委派的情况,创建单独的 Agent 模式回执。保留绑定的图库,禁用脚本仅限 Windows 的自动打开功能,使用上述匹配的原生命令打开权威 UUID 页面,并在选择前检查页面:

$StartOutput = node "$SkillRoot\scripts\caption_interaction.mjs" start `
  --state $Receipt --source $SourceVideo --captions $Plan `
  --review-dir $Review `
  --decision-mode agent `
  --delegation-note "User delegated caption style and preview approval." `
  --no-open true @SpatialArgs
$StartOutput | Write-Host

node "$SkillRoot\scripts\caption_interaction.mjs" agent-select `
  --state $Receipt --choice clean `
  --rationale "Conservative readable treatment preserves the talking-head frame."

仅在检查绑定的图库后使用 agent-select,并记录真实依据。在 Agent 模式下,不要编造人工摘要或使用 select。

生成透明的预览合成。项目仅包含本地 GSAP 和字体文件,并在 project-meta.json 中保留合理的 FPS:

node "$SkillRoot\scripts\generate_caption_project.mjs" `
  --video $SourceVideo --captions $Plan --out $PreviewProject `
  --interaction-state $Receipt --project-root $ProjectRoot --mode preview @SpatialArgs

npx.cmd hyperframes check $PreviewProject --at 1 --timeout 10000 --no-contrast

对于主要的 Expressive 审核,追加 --karaoke false。从相同的源、计划、交互选择和时间安排生成受支持的共存对比,只更改输出目录并追加 --karaoke true:

node "$SkillRoot\scripts\generate_caption_project.mjs" `
  --video $SourceVideo --captions $Plan --out $ComparisonProject `
  --interaction-state $Receipt --project-root $ProjectRoot `
  --karaoke true --mode preview @SpatialArgs

对于 Standard,构建映射后的早期/中期/晚期/无字幕证据。此命令会捕获透明的 HyperFrames 快照,通过 timeline.json 映射每个节目时间,提取匹配的原始源帧,并使用 Pillow 将二者合成:

python "$SkillRoot\scripts\build_caption_review.py" `
  --source $SourceVideo --timeline "$Work\timeline.json" --plan $Plan `
  --project $PreviewProject --cache "$Cache\review-cache" --out $Review `
  --interaction-state $Receipt @SpatialReviewArgs

对于 Expressive,同一个构建器会生成完整的机器采样、精简的人工审核索引,以及单独绑定的纯语义/Karaoke 对比:

python "$SkillRoot\scripts\build_caption_review.py" `
  --source $SourceVideo --timeline "$Work\timeline.json" --plan $Plan `
  --project $PreviewProject --comparison-project $ComparisonProject `
  --cache "$Cache\review-cache" --out $Review --interaction-state $Receipt `
  @SpatialReviewArgs

构建器会将 captions-review.html 写为唯一权威页面。不含空间上下文的 Standard 恰好包含四个维护中的证据标签。对于 Expressive 或支持合成背景的审核,captions-evidence.json.samples 会保留所有密集机器证据,而 review_samples 对实际存在的每个类别最多包含一个代表样本:bottom-standard、center-emphasis、preset-bottom、frame-center、panel-center 和 Hero 1.5x。一张 PNG 可以带有多个类别标签;不存在的类别不会被伪造。no-caption 仍是机器证据,Karaoke 对比也不计入代表样本数量。 Agent 必须使用宿主操作系统的原生命令打开该页面;例如,设置 $EvidenceReviewPage = "$Review\captions-review.html",然后运行以下命令之一:

Start-Process -FilePath (Resolve-Path $EvidenceReviewPage)
open "$EvidenceReviewPage"
xdg-open "$EvidenceReviewPage"

如果打开失败,请诊断并重试。检查每张主要代表图像的可读性、安全区域位置、裁切、文字换行、节拍位置稳定性和多余像素。在此关卡之前,机器验证必须已通过所有密集采样,包括 no-caption。不含空间上下文的 Standard 绑定以下四张维护中的图像:

$Evidence = @(
  "$Review\preview-early.png",
  "$Review\preview-middle.png",
  "$Review\preview-late.png",
  "$Review\preview-no-caption.png"
) -join ","

node "$SkillRoot\scripts\caption_interaction.mjs" preview-ready `
  --state $Receipt --project-meta "$PreviewProject\project-meta.json" `
  --evidence $Evidence --review-page "$Review\captions-review.html" `
  --timeline "$Work\timeline.json"

有空间上下文时,保留这些维护中的 Standard 采样;仅对带有合成背景的位置节拍,添加起始/25%/50%/75%/结束的密集证据。不要为 A-roll 位置节拍添加密集证据。

仅在 Standard 没有空间上下文时使用这条固定的四图命令。对于包含绑定空间上下文的 Standard,仅绑定代表性 PNG,并单独绑定完整的机器证据文档。Standard 没有共存对比,因此不要传递 --comparison-evidence:

$StandardSpatialEvidenceDocument = Get-Content "$Review\captions-evidence.json" -Raw | ConvertFrom-Json
$Evidence = @($StandardSpatialEvidenceDocument.review_samples | ForEach-Object {
  Join-Path $Review $_.preview
}) -join ","

node "$SkillRoot\scripts\caption_interaction.mjs" preview-ready `
  --state $Receipt --project-meta "$PreviewProject\project-meta.json" `
  --evidence $Evidence --evidence-document "$Review\captions-evidence.json" `
  --review-page "$Review\captions-review.html" `
  --timeline "$Work\timeline.json"

Expressive 从 captions-evidence.json 绑定代表性 PNG、完整机器文档和单独的共存对比对:

$EvidenceDocument = Get-Content "$Review\captions-evidence.json" -Raw | ConvertFrom-Json
$Evidence = @($EvidenceDocument.review_samples | ForEach-Object {
  Join-Path $Review $_.preview
}) -join ","
$ComparisonEvidence = @($EvidenceDocument.experimental_comparison.samples | ForEach-Object {
  Join-Path $Review $_.preview
}) -join ","

node "$SkillRoot\scripts\caption_interaction.mjs" preview-ready `
  --state $Receipt --project-meta "$PreviewProject\project-meta.json" `
  --evidence $Evidence --evidence-document "$Review\captions-evidence.json" `
  --comparison-evidence $ComparisonEvidence `
  --review-page "$Review\captions-review.html" --timeline "$Work\timeline.json"

在人类模式下,展示已打开的页面及其图像,然后 展示并停止。 人工审核者从页面复制以下结构化摘要之一:

Caption preview review
Review: <UUID from the opened page>
Decision: approve
Evidence: early, middle, late, no-caption

Expressive 批准使用动态证据令牌,并要求在检查绑定的对比证据后明确选择 Karaoke:

Caption preview review
Review: <UUID from the opened page>
Decision: approve
Evidence: expressive-layout-beats
Karaoke: on|off

绑定 caption-spatial-context.json 时,权威页面会生成支持合成背景的令牌。Standard 使用同一代码块,但不包含 Karaoke 行;Expressive 则需要明确选择 Karaoke:

Caption preview review
Review: <UUID from the opened page>
Decision: approve
Evidence: composite-aware
Karaoke: on|off
Caption preview review
Review: <UUID from the opened page>
Decision: revise
Changes: Raise captions 20 pixels.

将返回的摘要原样传递给 confirm --response 或 adjust --response。在 PowerShell 中安全地引用多行响应:

$PreviewResponse = @'
Caption preview review
Review: <UUID from the opened page>
Decision: approve
Evidence: early, middle, late, no-caption
'@
node "$SkillRoot\scripts\caption_interaction.mjs" confirm `
  --state $Receipt --response $PreviewResponse

对于 revise 摘要,以相同方式将其保存在 $PreviewResponse 中,然后运行:

node "$SkillRoot\scripts\caption_interaction.mjs" adjust `
  --state $Receipt --response $PreviewResponse

应用请求的更改,然后重新生成预览项目、审核页面和所有证据,再次展示此关卡。绝不要将人工反馈转化为 Agent 决策。 在委派模式下,Agent 必须检查同一个 captions-review.html 页面和所有主要证据,以及任何共存方案的比较,然后才能记录自己的理由。 对于 Standard,保留现有命令不变:

node "$SkillRoot\scripts\caption_interaction.mjs" agent-confirm `
  --state $Receipt `
  --rationale "All bound primary frames are readable and collision-free; coexistence comparison evidence was inspected separately when present."

对于 Expressive,传入根据比较结果明确选择的 Karaoke 选项:

node "$SkillRoot\scripts\caption_interaction.mjs" agent-confirm `
  --state $Receipt --karaoke off `
  --rationale "The semantic-only comparison is clearer for this footage."

生成已批准的叠加层项目。此正式渲染是唯一会在规范计划中最终确定 style、review 和带哈希的运行时资源的步骤。 Expressive 叠加层生成使用预览批准的 Karaoke 选项;明确指定的 --karaoke 值必须与该批准一致:

对于 Expressive,正式叠加层生成会将 Human 可见的代表性 PNG 存储在 review.representative_evidence 中。它会将 review.evidence 保留为共享交付编译器兼容集合:每个布局节拍包含一个已绑定的机器样本,再加上 no-caption,这些样本从 captions-evidence.json 中选取。此操作不会向人工审核添加卡片,也不表示用户检查过仅供机器使用的样本;完整的文档路径、哈希和样本数量仍保存在 review.machine_evidence_document 中。

node "$SkillRoot\scripts\generate_caption_project.mjs" `
  --video $SourceVideo --captions $Plan --out $OverlayProject `
  --interaction-state $Receipt --project-root $ProjectRoot --mode overlay @SpatialArgs

npx.cmd hyperframes check $OverlayProject --at 1 --timeout 10000 --no-contrast

$RenderMeta = Get-Content -Raw "$OverlayProject\project-meta.json" | ConvertFrom-Json
$RenderFps = "$($RenderMeta.fpsRational.num)/$($RenderMeta.fpsRational.den)"
Push-Location $OverlayProject
try {
  npx.cmd hyperframes render --format png-sequence --fps $RenderFps --output $OverlayFrames
}
finally {
  Pop-Location
}

规范叠加层生成会使用所选样式、决策者/理由和哈希绑定结果,更新 captions-summary.md 中的 ## Approval 部分。它会有意将渲染帧和共享交付检查保留为待处理状态;在将操作标记为已验证之前,请用实测结果替换该待处理行。

删除缓存后,重新构建合成内容,无需重放批准:

node "$SkillRoot\scripts\generate_caption_project.mjs" `
  --video $SourceVideo --captions $Plan --out $OverlayProject `
  --approved-plan true --project-root $ProjectRoot --mode overlay @SpatialArgs

该命令会验证冻结的运行时哈希仍然匹配。

项目注册

在 work/project.json 中添加或修改一项 captions 操作。依赖 understanding;如果存在活动的 cut 操作,也要依赖它。 如果活动的 B-roll 提供了空间上下文,还要将 b-roll 添加到 depends_on;其 based_on 值必须等于绑定的活动 B-roll 修订版本。 如果没有空间上下文,则从 depends_on 和 based_on 中省略 b-roll。所有 based_on 值都必须等于当前依赖项的修订版本。

{
  "id": "captions",
  "skill": "video-add-captions",
  "revision": 1,
  "depends_on": ["understanding", "cut", "b-roll"],
  "based_on": {"understanding": 1, "cut": 1, "b-roll": 4},
  "status": "verified",
  "plan": "captions/captions-plan.json",
  "outputs": ["cache/captions/overlay-frames"],
  "target": {"sequence": "main", "scope": "captions"},
  "effects": {
    "changes_timeline": false,
    "changes_geometry": false,
    "changes_video_pixels": false,
    "changes_audio": false,
    "adds_track": "captions"
  },
  "check": {"status": "pass", "report": "../review/05-captions/captions-summary.md"},
  "render": {
    "kind": "overlay",
    "asset": "cache/captions/overlay-frames",
    "asset_type": "image-sequence",
    "pattern": "frame_%06d.png",
    "start_number": 1,
    "fps": {"num": 30000, "den": 1001}
  }
}

使用实际时间线 FPS。将 captions 插入活动的 content-cards 和 motion-graphics 操作之前。Captions 永远不会依赖这两种下游操作;如果项目中已包含 captions,则添加 captions 时必须重新排列活动序列。然后编译并渲染一次交付内容:

python "$RepoRoot\skills\video-understand\scripts\validate.py" project `
  "$Work\project.json" $ProjectRoot
python "$RepoRoot\skills\video-understand\scripts\build_render_plan.py" $ProjectRoot
python "$RepoRoot\skills\video-understand\scripts\render_project.py" `
  "$Work\render\render-plan.json"

共享渲染器仅在时间线为恒等映射且没有音频滤镜时复制音频。剪辑或变速需要编码/滤波后的音频。字幕代码绝不会覆盖此决策。

兼容性

不使用 --timeline 时,build_captions.py 仍会写入旧版提示词数组。 generate_caption_project.mjs 可接受该数组及交互回执。 独立的精确 ID 和跳过响应仅用于旧版兼容。独立的 approve 也是旧版兼容响应。 历史上的非英语别名仍可作为输入接受,以保持兼容,但绝不会作为用户指引输出或记录。 composite_caption_overlay.ps1 可接受叠加视频或 frame_%06d.png 目录,并在复制源音频的同时写入兼容的 H.264/yuv420p。仅当没有活动操作会改变时间时,才使用此独立路径;规范项目使用共享渲染器。

自检

在声明操作已验证之前运行:

python "$SkillRoot\scripts\check_project_protocol.py"
node "$SkillRoot\scripts\check_caption_style_config.mjs"
python "$SkillRoot\scripts\check_caption_spatial_context.py"
python "$SkillRoot\scripts\check_caption_review.py"
node "$SkillRoot\scripts\check_caption_interaction.mjs"
powershell.exe -ExecutionPolicy Bypass -File "$SkillRoot\scripts\check_structure.ps1"
node "$SkillRoot\scripts\caption_interaction.mjs" status --state $Receipt

还要验证:

  • 提示和词语的时间值均为有限值、顺序正确、在节目时长范围内,且绝不跨越剪辑;
  • 早期/中期/晚期字幕显示在正确映射的源像素上;
  • 被丢弃的语音没有对应提示;
  • 覆盖层的首帧存在,尺寸匹配,FPS 等于时间线有理 FPS,帧数等于 ceil(program_duration_s * fps.num / fps.den),时长覆盖完整节目,且非字幕像素透明;
  • 共享交付文件存在、音频已同步,且通过项目的交付报告;
  • captions-summary.md 记录了所选样式、审批模式/理由、证据和验证结果。

仅生成 HTML 并不代表成功。报告完成之前,请检查实际像素和最终交付文件。

评论

支持 Markdown