# Skill Captions

> Render, preview, validate, and burn consistent production subtitles from QC-passed real-timestamp caption artifacts. Use for AI-video production, washed-video production, IndexTTS2 explainers, practical long-form videos, talking-head edits, Kimi-style dark rounded captions, warm-white translucent captions, subtitle styling, subtitle overlays, or fixing caption size, position, shadow, drift, and 4K scaling. Always pair with ra-audio-to-subtitles when final word timestamps do not already exist.

- Skill: `pluviobyte/skill-captions` (Agent Skill, multi-file: 77 files)
- Install (CLI): `npx skillmds@latest add pluviobyte/skill-captions`
- Raw SKILL.md: https://api.skillmd.com/api/skills/pluviobyte/skill-captions/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: pluviobyte (https://skillmd.com/u/pluviobyte)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/pluviobyte/skill-captions

---


# Skill-字幕

Separate subtitle timing from subtitle appearance:

- Let `ra-audio-to-subtitles` own ASR, phrase grouping, timestamps, SRT/VTT, and
  `caption-qc.json`.
- Let this skill own typography, panel geometry, fixed anchoring, preview,
  overlay rendering, burn-in, and render QC.
- Never estimate production timing from character count, scene duration, or
  TTS segment duration.

## Required workflow

1. Lock the final narration audio or final merged video.
2. Run `ra-audio-to-subtitles` unless the project already has the canonical
   caption artifacts described in `references/timing-contract.md`.
3. Require `caption-qc.json` to report `status: pass`.
4. Select a style from `references/style-registry.json`. Use `anchor-dark`
   when the contract does not specify another style.
5. Generate a representative still preview before rendering a full video.
6. Inspect the preview against `references/layout-qc.md`.
7. Render the captioned derivative. Preserve the clean video and portable
   SRT/VTT.
8. Run `scripts/validate_caption_render.py` and archive its JSON report.

## Registered styles

`anchor-dark` reproduces the approved Kimi K3 subtitle treatment: STHeiti
Medium, warm white text, a tight charcoal translucent rounded panel, no text
stroke, no text shadow, no large panel shadow, and a fixed bottom-center
anchor. Read `references/style-anchor-dark.md` before changing its values.

`anchor-light` keeps the exact same typography, size, padding, width, bottom
anchor, line fitting, and resolution scaling as `anchor-dark`. Only its surface
changes: dark ink on a warm-white translucent panel with a fine border and
subtle soft shadow. Read `references/style-anchor-light.md` before changing its
values. This is the second registered style; `anchor-dark` remains the default.

Scale every 1080p metric by `target_height / 1080`. Render 4K captions at 2×
their 1080p measurements; never upscale a rasterized 1080p subtitle layer.

## Commands

Preview a QC-passed project:

```bash
python3 .claude/skills/skill-captions/scripts/render_captions.py \
  final.mp4 media/captions/captions.json \
  --qc media/captions/caption-qc.json \
  --preview qc/caption-preview.png \
  --preview-only
```

Burn the default style:

```bash
python3 .claude/skills/skill-captions/scripts/render_captions.py \
  final-clean.mp4 media/captions/captions.json \
  --qc media/captions/caption-qc.json \
  --out renders/final-captioned.mp4 \
  --preview qc/caption-preview.png
```

Burn the light translucent style:

```bash
python3 .claude/skills/skill-captions/scripts/render_captions.py \
  final-clean.mp4 media/captions/captions.json \
  --qc media/captions/caption-qc.json \
  --style anchor-light \
  --out renders/final-captioned.mp4 \
  --preview qc/caption-preview.png
```

Skip an interval that already contains burned captions:

```bash
python3 .claude/skills/skill-captions/scripts/render_captions.py \
  final-clean.mp4 media/captions/captions.json \
  --qc media/captions/caption-qc.json \
  --exclude 0:23.936 \
  --out renders/final-captioned.mp4
```

Create a reusable transparent caption band:

```bash
python3 .claude/skills/skill-captions/scripts/render_captions.py \
  final-clean.mp4 media/captions/captions.json \
  --qc media/captions/caption-qc.json \
  --overlay-out renders/caption-band.mov
```

Validate the result:

```bash
python3 .claude/skills/skill-captions/scripts/validate_caption_render.py \
  --source final-clean.mp4 \
  --render renders/final-captioned.mp4 \
  --captions media/captions/captions.json \
  --qc media/captions/caption-qc.json \
  --out qc/caption-render-qc.json
```

## Hard rules

- Use the final audio/video as the only timing source.
- Consume `captions.json` start/end values directly.
- Refuse final burn-in when caption QC is missing or failed.
- Keep a fixed bottom anchor. Let multiline panels grow upward.
- Keep captions inside the frame and clear of titles, UI, faces, and PiP.
- Keep English model/product tokens intact.
- Preserve one canonical caption timeline across renderers.
- Keep the clean master; a burned-caption MP4 is a derivative.
- For a new or materially changed style, show a short preview before the full
  render.
- Do not add karaoke, behind-person typography, VFX captions, or animated hero
  words unless the user explicitly requests the separate `embedded-captions`
  lane.

## Integration contract

Video orchestrators should call this skill after `ra-audio-to-subtitles`.
Handoff contracts may set `caption_style` to `anchor-dark` or `anchor-light`;
otherwise use `anchor-dark`.
Renderers may reproduce the registered CSS in Remotion or HyperFrames, but
must preserve the style metrics and fixed-anchor behavior.

