Use when an understood video project needs selective transcript-timed titles, lower-thirds, statistics, metric spotlights, comparisons, lists, quotes, chapter cards, or calls to action authored as HyperFrames HTML graphics.
设计与多媒体
video-add-captions
试用Add word-timed captions to an Open Recut program. Use this skill to map the canonical transcript through timeline.json, review a maintained style on source-backed pixels, render a local transparent HyperFrames PNG sequence, and register it as an overlay contribution for the shared delivery render.
它能做什么
Add word-timed captions to an Open Recut program. Use this skill to map the canonical transcript through timeline.json, review a maintained style on source-backed pixels, render a local transparent HyperFrames PNG sequence, and register it as an overlay contribution for the shared delivery render.
技能文档
Video Add Captions
Dependencies
/video-understand is a prerequisite. Run it first so captions use the validated
word-level transcript and canonical timeline.
Before starting, verify that it is installed. If it is not, warn the user that
this prerequisite is missing and stop before processing media.
Require ffmpeg/ffprobe on PATH, Python with Pillow, and Node.js >= 22 (for the .mjs scripts and npx hyperframes, fetched on demand). hyperframes render/snapshot drives a headless Chrome — it manages its own chrome-headless-shell, and falls back to a system Chrome (set CHROME to override) when the cached one is unusable. Check these before processing media.
Scope
This skill owns caption grouping, style selection, review, and the transparent caption track. It does not transcribe, cut, retime, grade, reframe, or choose the delivery audio policy.
Run captions before content cards and graphic motion whenever either is selected. The approved caption layout establishes a reserved subtitle region that both later operations must keep clear. This relative order also applies when only one pair is active.
Use video-understand first. If a cut exists, caption the active program
timeline; do not treat source transcript seconds as program seconds.
Protocol Inputs
Required:
work/project.jsonwork/understand/transcript.json, with word-level source timestampswork/understand/media.jsonwork/timeline.json- the source video named by
work/project.json
The timeline is the only source-to-program mapping. All ranges are half-open
[start_s, end_s). scripts/build_captions.py uses the shared
projectlib.map_transcript_to_timeline; words in dropped source ranges disappear,
retained words move to program time, and cues always break at clip boundaries.
Durable Outputs
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-.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
Generated HTML, copied runtime files, extracted source frames, and overlay frames are cache. The plan, optional spatial context, SRT, decision receipt, and review evidence are durable.
Caption Plan
work/captions/captions-plan.json is the canonical caption plan, targets overlay, and uses
program time. It records:
timeline_id,program_duration_s, and the source transcript path;- cue grouping settings;
- approved style, decision mode, rationale, gallery choice, and complete resolved style;
- source-backed review evidence and approval actor;
- cues with compatibility fields
start,end,text,lines, andwords; program_rangeandsource_rangeson every cue;- program/source ranges and
clip_idon every mapped word; - a local renderer recipe with exact rational FPS and hashed runtime assets.
The generator also accepts the old top-level cue array. That is a standalone compatibility adapter only; it cannot express timeline provenance or regenerate an approved protocol contribution.
Standard is the default presentation mode. Standard plans do not need a
presentation field and must not be migrated merely to add one. Expressive is an
explicit presentation mode, not a preset: request it with
--presentation-mode expressive. The build step then adds stable cue IDs, default
word semantic_role values, and a draft presentation planning shell; it does not
guess layout variants.
Expressive supports only bottom-standard and center-emphasis. Read
reference/caption-rules.md before filling the shell. The
existing renderer consumes only completed presentation.layout_beats; it does not
infer positions or change layout inside a beat.
Expressive cues may also define one contiguous phrase-level hero_line.
Use canonical level: hero; it renders the phrase gold on its own line at
1.5x. Legacy level: strong remains accepted as an input alias and renders
identically, but new Agent-authored plans must not emit it. The maintained word roles keyword, number, and
contrast each use 1.22x; normal remains 1.0x. These treatments are
orthogonal to presets and do not create new style IDs. Read
reference/caption-rules.md for the schema, overflow policy, and Karaoke rules.
When an active, review-approved B-roll operation contains approved or verified
speaker-inset composites, captions may derive caption-spatial-context.json from
the frozen upstream plan, evidence, normalized composites, and explicit subshot
display_mode. This does not modify or reselect the B-roll layout. It aligns cue
boundaries before Expressive planning and resolves only the maintained
preset-bottom, frame-center, panel-center, and boundary-only panel-bottom
placements. panel-bottom is allowed only for an unsplittable_word_boundary
adjacent to a lower-center focused panel; it centers the stable cue inside the
reserved strip below the structured speaker rect. Such a cue is checked against
every visual context it intersects, not only the context containing the word
midpoint. Without this context, all existing Standard and Expressive placement
behavior remains unchanged.
Styles
Maintained presets are clean, minimal, social-bold, pill, boxed,
stroked, and shorts. Gallery combination IDs add maintained themes, for
example pill-yellow, stroked-blue, and shorts-green. Karaoke is an option,
not a separate preset.
Default delegated choice: clean, Karaoke off. Choose a more expressive preset
only when the destination or footage justifies it. Store job-specific changes in
an overrides JSON; do not edit the generator for ordinary style feedback.
Expressive supports both semantic-only (Karaoke off) and
semantic-plus-karaoke (Karaoke on). Semantic emphasis persists for the full cue
in both configurations. In coexistence mode, semantic emphasis and the active
Karaoke word use style.wordHighlight.activeColor as their foreground color in
every highlight mode; a background highlight remains an additional effect. The
effective scale is max(semantic scale, karaoke active scale), never their
product. Expressive never renders an underline, including for the compatible
contrast semantic role.
The existing review contract continues to use semantic-only as the primary
Expressive evidence and binds semantic-plus-karaoke separately. The compatibility
payload field remains named experimental_comparison; do not rename it without an
approval-protocol migration.
Read:
reference/caption-rules.mdbefore changing grouping limits;reference/caption-style-themes.mdfor style vocabulary;reference/caption-feedback-mapping.mdfor override mapping.
Decision Modes
Two honest modes share the same hash-bound state machine:
human: pass the exact copied gallery summary toselect, show all real preview evidence, and pass the exact copied approval or revision summary toconfirmoradjust. Review-page-bound commands do not accept bare approval phrases.agent: use only when the user explicitly delegates caption decisions. Start with a non-empty delegation note, then useagent-selectandagent-confirmwith non-empty rationales.
Human commands fail in agent mode and agent commands fail in human mode. Standard without spatial context requires the four maintained source-backed images; Expressive and composite-aware reviews use their dynamic evidence contracts. A change to the source, plan, timeline, style, override, project metadata, review page, or evidence invalidates approval; spatial context, upstream B-roll revision, or bound-composite changes do the same. Rebuild the affected artifacts and review them again.
Canonical Workflow
Run from the repository root. Set project paths:
$RepoRoot = (Resolve-Path ".").Path
$SkillRoot = Join-Path $RepoRoot "skills\video-add-captions"
$ProjectRoot = (Resolve-Path "").Path
$Work = Join-Path $ProjectRoot "work"
$SourceVideo = ""
$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
Before building the caption plan, ask the user to choose the presentation mode
unless the current request already explicitly selects one. Render the question in
the user's current conversation language while keeping the Standard and
Expressive identifiers untranslated. Keep the English source prompt below in
this file, present the localized choice in the current session, then
Present + STOP:
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)."
Do not run build_captions.py until the user responds. If the user explicitly
delegates the choice in any wording, select Standard. State that Standard was
selected as the compatibility-preserving default before building the plan.
Build program-time cues and the review 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
After the user selects Standard, the command above produces the unchanged Standard plan. After the user selects Expressive, run the same command with:
--presentation-mode expressive
After draft cue generation, inspect the active B-roll operation and its bound plan
read-only. Enable composite-aware placement only when the operation is active, its
status is approved or verified, review.status is approved, the
speaker-inset analysis/agent-input/preview/clearance bindings are complete, and at
least one verified or normalized shot has a maintained composite layout. The
spatial builder uses explicit subshot display_mode: enabled for speaker geometry;
pure_broll and missing speaker evidence never imply a speaker rectangle.
When eligible, align draft cues to every B-roll visual boundary before filling any
Expressive layout_beats or hero_line. Alignment splits only at word gaps and
writes back atomically; a boundary inside a word keeps the word whole and records
mandatory review evidence:
python "$SkillRoot\scripts\caption_spatial_context.py" align `
--project-root $ProjectRoot --plan $Plan --out-plan $Plan
For an eligible project, prepare the optional arguments used by every later gate:
$SpatialArgs = @("--spatial-context", $SpatialContext)
$SpatialReviewArgs = @("--spatial-context", $SpatialContext, "--project-root", $ProjectRoot)
When no eligible composite exists, skip all four spatial commands and leave
$SpatialArgs and $SpatialReviewArgs empty. Do not create or attach an empty
context.
Before starting style selection or generating a preview, the Agent must plan the entire Expressive program in one pass:
- Read the transcript, available understanding artifacts, canonical timeline, generated caption cues, and any real source-frame evidence needed to justify layout changes.
- Fill all
presentation.layout_beats, annotate exceptional wordsemantic_rolevalues, add at most one contiguoushero_linewith canonicallevel: heroto a cue when warranted, write one rationale per beat/hero line, and write the overallpresentation.planner.rationale. - Set
presentation.planning_statustocompleteonly after every cue is covered exactly once. - Validate the completed plan before preview generation:
python "$SkillRoot\scripts\build_captions.py" --validate-plan $Plan
For an eligible composite, build, validate, and attach the context only after the final cue IDs and Expressive candidates are complete. This preserves the upstream layout and binds its current revision and hashes into the caption plan:
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
Do not ask the user to choose a position cue by cue. The user reviews the existing HTML evidence and corrects only a small number of anomalous beats. Starting the interaction after planning keeps the existing caption-plan hash binding authoritative.
Start one decision mode. For human mode, publish the maintained offline gallery into the project review directory without asking the user to locate a file:
$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 prints the authoritative captions-style-review-.html project page
path and the fixed question. captions-style-review.html is a non-authoritative
latest convenience alias only. The Agent must take the UUID path printed after
Caption style review:, assign that exact path to $StyleReviewPage, and open it
with the native command for the host OS:
Windows PowerShell:
$StyleReviewPage = ""
Start-Process -FilePath (Resolve-Path $StyleReviewPage)
macOS:
open "$StyleReviewPage"
Linux:
xdg-open "$StyleReviewPage"
If opening fails, diagnose the command or path and retry it. Do not ask the user to find the page. Present the opened gallery and the fixed question exactly as printed, then Present + STOP. Do not continue until the human copies the structured summary from the page. It has this form:
Caption style review
Review:
Decision: select
Choice: pill-yellow
Pass the user's exact summary unchanged to select --response. In PowerShell, a
single-quoted here-string preserves the lines safely:
$StyleResponse = @'
Caption style review
Review:
Decision: select
Choice: pill-yellow
'@
node "$SkillRoot\scripts\caption_interaction.mjs" select `
--state $Receipt --response $StyleResponse
The block above shows the structure; use the user's returned block, including their review UUID and choice. Never infer, normalize, or simulate a human response.
For explicit delegation, create a separate Agent-mode receipt. Keep the bound gallery, suppress the script's Windows-only auto-open, open the authoritative UUID page with the matching native command above, and inspect it before choosing:
$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."
Use agent-select only after inspecting the bound gallery and record the real
rationale. Do not manufacture a human summary or use select in Agent mode.
Generate a transparent preview composition. The project contains only local GSAP
and font files and preserves rational FPS in project-meta.json:
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
For the primary Expressive review, append --karaoke false. Generate the supported
coexistence comparison from the same source, plan, interaction selection, and timing by changing
only the output directory and appending --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
For Standard, build mapped early/middle/late/no-caption evidence. This command captures
transparent HyperFrames snapshots, maps each program time through
timeline.json, extracts the matching original source frame, and composites the
two with 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
For Expressive, the same builder emits exhaustive machine samples, a compact human-review index, and a separately bound semantic-only/Karaoke comparison:
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
The builder writes captions-review.html as the one authoritative page. Standard
without spatial context contains exactly the four maintained evidence labels. For
Expressive or composite-aware review, captions-evidence.json.samples retains all
dense machine evidence while review_samples contains at most one representative
for each category actually present: bottom-standard, center-emphasis,
preset-bottom, frame-center, panel-center, and Hero 1.5x. One PNG may carry
multiple category labels; absent categories are not fabricated. no-caption
remains machine evidence, and the Karaoke comparison remains separate from the
representative count. The
Agent must open that page with the native command for the host OS; for example,
set $EvidenceReviewPage = "$Review\captions-review.html" and run one of:
Start-Process -FilePath (Resolve-Path $EvidenceReviewPage)
open "$EvidenceReviewPage"
xdg-open "$EvidenceReviewPage"
If opening fails, diagnose and retry. Inspect every representative primary image for readability,
safe-area placement, clipping, word wrapping, stable beat placement, and unwanted
pixels. Machine validation must already have passed every dense sample, including
no-caption, before this gate. Standard without spatial context binds the
maintained four images:
$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"
With spatial context, keep those maintained Standard samples and add dense start/25%/50%/75%/end evidence only for placement beats that carry a composite background. Do not add dense evidence for A-roll placement beats.
Use that fixed four-image command only when Standard has no spatial context. For
Standard with a bound spatial context, bind only the representative PNGs and bind
the complete machine evidence document separately. Standard has no coexistence comparison, so do not pass
--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 binds the representative PNGs, complete machine document, and separate
coexistence pair from captions-evidence.json:
$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"
In human mode, present the opened page and its images, then Present + STOP. The human copies one of these structured summaries from the page:
Caption preview review
Review:
Decision: approve
Evidence: early, middle, late, no-caption
Expressive approval uses the dynamic evidence token and requires the explicit Karaoke choice made after inspecting the bound comparison evidence:
Caption preview review
Review:
Decision: approve
Evidence: expressive-layout-beats
Karaoke: on|off
When caption-spatial-context.json is bound, the authoritative page emits the
composite-aware token. Standard uses the same block without the Karaoke line;
Expressive requires the explicit Karaoke choice:
Caption preview review
Review:
Decision: approve
Evidence: composite-aware
Karaoke: on|off
Caption preview review
Review:
Decision: revise
Changes: Raise captions 20 pixels.
Pass the returned summary unchanged to confirm --response or
adjust --response. Quote the multiline response safely in PowerShell:
$PreviewResponse = @'
Caption preview review
Review:
Decision: approve
Evidence: early, middle, late, no-caption
'@
node "$SkillRoot\scripts\caption_interaction.mjs" confirm `
--state $Receipt --response $PreviewResponse
For a revise summary, preserve it in $PreviewResponse the same way and run:
node "$SkillRoot\scripts\caption_interaction.mjs" adjust `
--state $Receipt --response $PreviewResponse
Apply the requested change, then regenerate the preview project, review page, and all evidence before presenting the gate again. Never convert human feedback into an Agent decision.
In delegated mode, the Agent must inspect the same captions-review.html page and
all primary evidence plus any coexistence comparison before recording its own rationale.
For Standard, keep the existing command unchanged:
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."
For Expressive, pass the explicit Karaoke choice made from the comparison:
node "$SkillRoot\scripts\caption_interaction.mjs" agent-confirm `
--state $Receipt --karaoke off `
--rationale "The semantic-only comparison is clearer for this footage."
Generate the approved overlay project. This formal render is the only step that
finalizes style, review, and hashed runtime assets in the canonical plan.
Expressive overlay generation uses the preview-approved Karaoke choice; an
explicit --karaoke value must match that approval:
For Expressive, formal overlay generation stores the Human-visible representative
PNGs in review.representative_evidence. It keeps review.evidence as the shared
delivery compiler compatibility set: one already-bound machine sample per layout beat
plus no-caption, selected from captions-evidence.json. This does not add cards to
the human review or claim that the user inspected machine-only samples; the complete
document path, hash, and sample count remain in 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
}
Canonical overlay generation refreshes the ## Approval section in
captions-summary.md with the selected style, decision actor/rationale, and
hash-binding result. It deliberately leaves rendered-frame and shared-delivery
checks pending; replace that pending line with the measured results before marking
the operation verified.
After cache deletion, rebuild the composition without replaying approval:
node "$SkillRoot\scripts\generate_caption_project.mjs" `
--video $SourceVideo --captions $Plan --out $OverlayProject `
--approved-plan true --project-root $ProjectRoot --mode overlay @SpatialArgs
The command verifies that the frozen runtime hashes still match.
Project Registration
Add or revise one captions operation in work/project.json. Depend on
understanding; also depend on the active cut operation when it exists.
When active B-roll supplied the spatial context, also add b-roll to
depends_on; its based_on value must equal the bound active B-roll revision.
When there is no spatial context, omit b-roll from depends_on and
based_on. All based_on values must equal the current dependency revisions.
{
"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}
}
}
Use the actual timeline FPS. Insert captions before active content-cards and
graphic-motion operations. Captions never depend on either downstream operation;
adding captions to a project that already contains them requires reordering the active
sequence. Then compile and render delivery once:
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"
The shared renderer copies audio only for an identity timeline with no audio filters. Cuts or retiming require encoded/filtered audio. Caption code never overrides that decision.
Compatibility
Without --timeline, build_captions.py still writes the old cue array.
generate_caption_project.mjs accepts that array with the interaction receipt.
Standalone exact ID and skip responses are legacy compatibility only. Standalone
approve is also a legacy compatibility response. Historical non-English aliases
remain accepted as input compatibility but are never emitted or documented as
user instructions.
composite_caption_overlay.ps1 accepts an overlay video or frame_%06d.png
directory and writes compatible H.264/yuv420p while copying source audio. Use this
standalone path only when no active operation changes time; canonical projects use
the shared renderer.
Self Check
Run before declaring the operation verified:
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
Also verify:
- cue and word times are finite, ordered, within program duration, and never cross clips;
- early/middle/late captions appear on the correct mapped source pixels;
- dropped speech has no cue;
- overlay first frame exists, dimensions match, FPS equals timeline rational FPS,
frame count equals
ceil(program_duration_s * fps.num / fps.den), duration covers the complete program, and non-caption pixels are transparent; - the shared delivery exists, has synchronized audio, and passes the project's delivery report;
captions-summary.mdrecords the selected style, approval mode/rationale, evidence, and validation result.
HTML generation alone is not success. Inspect actual pixels and the final delivery before reporting completion.
相关技能
Use when a talking-head, interview, documentary, or explanatory video needs deliberate transcript-timed visual cutaways from local media or Pexels.
Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet `anchor` rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.
Package an existing talking-head / interview / podcast video with timed, designed GRAPHIC OVERLAY cards — kinetic titles, lower-thirds, data callouts, quotes, side panels, picture-in-picture — synced to the transcript, on a 16:9 / 9:16 / 4:5 canvas of your choice; the clip plays untouched underneath. Trigger on "graphic overlays", "on-screen graphics", "package / dress up my video". Not plain subtitles (/embedded-captions). Unclear → /hyperframes.
Add sound to a silent video - sound effects, narration, or a music bed. Use when the user says "this clip has no audio", "add sound effects to my video", "ma...
Generate timecoded SRT subtitles from local video or audio files. Use when a user wants a local low-cost subtitle workflow, asks to transcribe local media in...