# Srt Aligner

> Match a user-provided script/copy with an audio file or timed transcript and generate clean SRT subtitles. Use when the user says they will provide 文案 and 音频, asks to 匹配文案和音频, generate SRT, create subtitles from a script, align narration copy to audio, or convert ASR/Whisper output into polished subtitle files.

- Skill: `kinkwanc22/srt-aligner` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add kinkwanc22/srt-aligner`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kinkwanc22/srt-aligner/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: kinkwanc22 (https://skillmd.com/u/kinkwanc22)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/kinkwanc22/srt-aligner

---


# SRT Aligner

Use this skill to turn a final script plus audio or a rough timed subtitle file into a clean `.srt` subtitle file.

For the user's Jianying/CapCut workflow, prefer the continuous mode below when they provide:

- A rough SRT generated by ASR.
- A correct final manuscript or correct line-broken subtitle copy.
- Requirements like `每一行文本对应一条字幕`, `无标点`, `字幕之间不要有空白`, `max_gap_between_cues_sec = 0`, `无重叠`, or `每行不超过17字`.

If the user only provides a line-broken subtitle text and asks to process long lines, do not generate SRT. Run the line-only mode below: preserve existing short lines, remove punctuation, and split only lines longer than the requested character limit.

## Workflow

1. Collect inputs:
   - Audio/video file path.
   - Final script/copy text, preferably as `.txt` or pasted text saved to a file.
   - Output filename, defaulting to the audio basename plus `.srt`.
2. Get timing data from the audio:
   - Strongly prefer Whisper JSON with word timestamps, such as `segments[].words[]`.
   - If no timed transcript exists yet, use the local ASR/video subtitle workflow and request word timestamps whenever the tool supports it.
   - If only segment timestamps or an existing `.srt` are available, the script can still produce a best-effort result, but it must be treated as review-needed.
3. For every Jianying/CapCut narration draft, default to `scripts/align_continuous_srt.mjs`. Do not wait for the user to repeat “字幕填满” or “无空白”.
4. Use `scripts/align_srt.mjs` only when the user explicitly wants natural silent gaps or the output is not intended for Jianying/CapCut continuous captions.
5. Read the generated report before calling the SRT final:
   - `timingMode: "word"` is the preferred mode.
   - `timingMode: "segment-text"` means segment text was used as pseudo word timing.
   - `timingMode: "segment-proportional"` means the result is rough timing only.
   - Check `weakCues` and `estimatedCues`; these are the subtitles most likely to need manual review.
6. Inspect the SRT for obvious timing/text problems:
   - Empty subtitles.
   - Overlong lines.
   - Large gaps caused by unmatched text.
   - Garbled ASR words leaking into the final script. The output text should come from the user script, not the raw ASR transcript.
7. Save the final `.srt` in the requested output location and mention whether the report found weak cues.

## Line-Only Text Mode

Use this when the user provides only 分行字幕 / pasted subtitle text and asks to handle lines over 17 characters. This mode does not need audio or SRT.

```powershell
node scripts/optimize_line_breaks.mjs `
  --script line-broken-copy.txt `
  --out optimized-lines.txt `
  --max-chars 17
```

Line-only mode:

- Preserves user-provided short lines as-is after punctuation/space cleanup.
- Splits only lines longer than `--max-chars`.
- Prefers semantic split points such as `或者`, `并且`, `但是`, `所以`, `因为`, `如果`, `甚至`, `而是`, `就是`, `以及`, and `和`.
- Avoids leaving obvious function words at line tails or heads when a nearby split is available.
- Writes a `.qa.json` beside the output with line count, max length, over-limit lines, blank lines, and punctuation issues.

If the user later provides audio and a rough SRT, feed the optimized line file into continuous mode with `--keep-lines`.

## Jianying Continuous Mode

Use this mode for long Chinese narration when the final subtitle must import into Jianying without visible blank spaces between cues.

```powershell
node scripts/align_continuous_srt.mjs `
  --script final-copy.txt `
  --timed rough-asr.srt `
  --out final-continuous.srt `
  --max-chars 17
```

If the script is already correctly line-broken and each line must become exactly one subtitle cue, add:

```powershell
--keep-lines
```

Default behavior is **repair/optimize the user's line-broken copy first, then align timing**. Do not add `--keep-lines` unless the user explicitly asks to preserve their exact line breaks without repairs.

Continuous mode does all of these:

- Uses the user's final script as subtitle text and uses rough SRT/ASR only for timing.
- Removes punctuation from subtitle text.
- Uses the user's pasted line breaks as the primary structure when the input already looks like line-broken subtitle copy.
- Treats manuscript line breaks as soft boundaries, so a word or sentence split across two pasted lines can be repaired locally before timing alignment.
- Avoids full-script reflow for line-broken subtitle copy; it only repairs suspicious adjacent boundaries unless the input is a long unbroken manuscript.
- Keeps each subtitle cue at or below `--max-chars`.
- Preserves one input line as one subtitle only when `--keep-lines` is provided.
- Uses Chinese word segmentation plus protected phrases to avoid splitting one word across cue boundaries.
- When `jieba` is available, continuous mode uses it as the primary Chinese dictionary layer, then derives subtitle-safe phrase blocks from the token stream. This helps keep phrases such as `人与人之间`, `并不友好的女人`, `择偶策略`, `远古时期`, and `情绪状态` from being split awkwardly.
- The jieba layer also derives limited collocation blocks, such as `社会道德绑架`, `给你灌输`, and `精密运转`, so the line breaker avoids splitting common noun-action and modifier-action structures.
- Uses a dedicated character-level global aligner for long Chinese narration, so repeated phrases are less likely to jump to the wrong later occurrence.
- Computes cue boundaries from the previous line's last matched character and the next line's first matched character, which is more stable when rough SRT has local ASR errors.
- Protects common relationship-copy phrases and fixed expressions such as `主动权`, `情绪价值`, `思维导图`, `游刃有余`, `吸血鬼`, `两性博弈`, `道德评价体系`, and `心理学机制` from bad line splits, while also using generic Chinese word boundaries for unseen words.
- Adds a semantic compound layer above the default Chinese tokenizer, so noun phrases such as `择偶策略`, `远古时期`, `现代社会`, `普通男人`, and `双重生存策略` stay together even when the platform tokenizer splits them into smaller pieces.
- Avoids leaving Chinese function words or measure words at bad line edges, such as splitting `一个`, `就是`, or `X的`.
- Repairs common phrase and sentence-anchor collisions inside one subtitle line, such as `游刃有余为什么因为...`, by splitting short logic anchors like `为什么`, `因为`, `只要`, `如果`, `但是`, `所以`, and `以及` into cleaner cue boundaries when the split is locally safe.
- Runs a final line-edge pass for Chinese particles, so subtitles do not start with orphaned fragments like `的...` or `起来...` when the previous line can donate the needed word group without exceeding `--max-chars`.
- Forces adjacent cues to touch exactly: previous `end` equals next `start`.
- Writes a `.qa.json` report checking line count, blank text, punctuation, overlaps, max gap, max characters per cue, and line-break QA issues.

Useful segmentation options:

```powershell
--segmenter jieba
```

Requires `python3 -m pip install --user jieba`. If `--segmenter jieba` is requested and jieba is unavailable, the script fails clearly. With the default `--segmenter auto`, it uses jieba when installed and falls back to the built-in tokenizer otherwise.

For the user's current standard, the QA target is:

- `blank_text: 0`
- `punctuation_issues: 0`
- `overlaps: 0`
- `max_gap_between_cues_sec: 0`
- `lineCountMatches: true`
- `max_chars_per_cue <= 17`
- `lineQa.summary.totalIssues: 0` or manually reviewed

## Downstream Video-Skill Handoff

Before an SRT is handed to `shuping-ziranliu`, `hengban-ziranliu`, or `jiepai-jianji`, require all of the following:

- Adjacent subtitle cues touch exactly: previous `end` equals next `start`.
- The first cue starts at the intended narration start.
- The final cue ends at the narration end; a sub-frame encoder tail is acceptable only when verified as inaudible.
- `blank_text = 0`, `overlaps = 0`, and `max_gap_between_cues_sec = 0`.
- The subtitle text comes from the final manuscript; ASR supplies timing only.

If a downstream draft already exists and its source subtitle track contains micro-gaps, do not patch an opened/encrypted Jianying timeline in place. Rebuild a new draft from a clean source or a copy. Fill ordinary narration gaps by extending the preceding cue to the next cue start. Preserve only deliberate non-narration sections introduced by the editing workflow, such as the 1.833333-second gear bridge in `shuping-ziranliu`.

## Alignment Script

Use the bundled Node script:

```powershell
node scripts/align_srt.mjs --script copy.txt --timed whisper.json --out output.srt
```

Useful options:

```powershell
node scripts/align_srt.mjs `
  --script copy.txt `
  --timed whisper.json `
  --out output.srt `
  --report output.report.json `
  --max-chars 30 `
  --min-duration 0.8 `
  --max-duration 5.5
```

Supported timed inputs:

- Whisper-style JSON: `{ "segments": [{ "start": 0, "end": 1.2, "text": "...", "words": [{ "word": "...", "start": 0, "end": 0.3 }] }] }`
- Whisper segment JSON without word timestamps.
- Existing `.srt` files, used as segment-level timing fallback.

Continuous mode is especially useful with existing rough `.srt` files because it can turn a noisy ASR subtitle into a clean final subtitle while preserving the rough timing skeleton.

## Heuristics

- Keep Chinese subtitle chunks around 18-30 characters unless the user asks otherwise.
- Keep English subtitle chunks around 42-70 characters.
- Prefer splitting at `。！？；，、,.!?;:` and line breaks.
- When the final script differs slightly from ASR, trust the user's script for subtitle text and use ASR only for timing.
- The aligner now uses global token matching for word timestamps, so skipped words, repeated phrases, and short ASR insertions should not push the whole SRT off track.
- If word timestamps are missing but segment text exists, it distributes segment time across segment tokens and performs global matching against that pseudo timing.
- If only empty segment timing exists, it distributes script chunks across the full segment duration by character count and marks all cues as estimated.
- If alignment confidence looks poor, tell the user and provide the best-effort SRT plus the report path.
- For long Chinese rough-SRT alignment, if confidence is unexpectedly poor, prefer continuous mode first. It has its own character-level report and `weakCues` list for local review.

## Output

Return:

- The `.srt` file path.
- The `.report.json` file path.
- The timing source used: word timestamps, segment text pseudo timing, or proportional fallback.
- Whether `weakCues` / `estimatedCues` need review.

