# Chengfeng Subtitle

给剪好的口播做字幕：直接用已有的逐词稿加账本算出剪后时间（不必导出、不必重新转录）、用词典和作者文稿改写听错的专名、按句子分屏、在 Studio...

- Repository: https://github.com/Agentchengfeng/chengfeng-videocut-skills (3168 stars)
- Category: Engineering
- License: Apache-2.0
- Last updated: 2026-10-10
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add Agentchengfeng/chengfeng-videocut-skills --skill chengfeng-subtitle -g -a claude-code -y`
Codex: `npx skills add Agentchengfeng/chengfeng-videocut-skills --skill chengfeng-subtitle -g -a codex -y`
Cursor: `npx skills add Agentchengfeng/chengfeng-videocut-skills --skill chengfeng-subtitle -g -a cursor -y`
Gemini CLI: `npx skills add Agentchengfeng/chengfeng-videocut-skills --skill chengfeng-subtitle -g -a gemini-cli -y`

## Description

给剪好的口播做字幕：直接用已有的逐词稿加账本算出剪后时间（不必导出、不必重新转录）、用词典和作者文稿改写听错的专名、按句子分屏、在 Studio 里逐屏复核。用户说做字幕、加字幕、改字幕、重新分屏、字幕不对时使用。不要用于删词剪辑、物理剪切、分镜动画或成片渲染。

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# 字幕

**这是一件事，不是流程的一段。** 用户什么时候喊它就什么时候做, , 刚剪完可以做，
做完又删了两句可以再做一遍。

它只有一个前提：**账本已经存在**。不是因为它排在剪辑后面，而是因为没有账本，
它不知道哪几句留着、各自落在成片的第几秒。

```text
需要   edit-list.json（账本）、transcript.json（逐词稿）
产出   subtitles.json
```

干完就停，**不指挥用户下一步**。

先读取并执行 [业务 Skill 的阶段合同](../../references/business-workflow-contract.md)，
判据见 [字幕校对规则](references/subtitle-correction.md)，专名写法见
[AI 用词词典](../../references/ai-term-dictionary.md)。

## 谁说了算什么

这是这一段的地基，其余都从这里推出来。

```text
剪口播   说了算「留哪些话、在什么时候」    ← 时间的唯一真相
字幕     说了算「屏幕上显示什么字」        ← 显示的唯一真相
```

一屏字幕存的是**词 id 列表 + 显示文字**，**不存秒数**。时间每次从账本现算。
于是两本账没有第二份时间可以走偏，失效也能精确到屏：「第 7、第 12 屏的词被剪掉了」，
而不是那句谁也点不动的「字幕可能已过期」。

**字幕存自己的文字是故意的。** 转录回答「他说了什么」，字幕回答「给人看什么」, , 标点、去掉的口头禅、专名的正式写法，这些本来就该不一样。逼一份字符串同时干两件事，
字幕就永远加不了逗号。

## 0. 就绪

先执行 [检查更新](../chengfeng-check-updates/SKILL.md) 的「就绪检查」, , skills 是否
最新、Runtime 是否配套；**插件根**也在那里定位（本文命令里的 `<插件根>` 都代入
那个字面路径）。只有「就绪」才继续；「需新会话」或「停」按它的处置执行
（含「禁止自制替代界面」禁令），业务 Skill 不自带环境逻辑。

若就绪结果为 `runtime.kind=desktop-managed`，直接复用桌面 App 已安装的稳定 CLI 与
同一 `launchd/windows-task` 服务；不要解析 Electron 路径、另装依赖或起第二个
Runtime。

## 1. 入口断言

```bash
node "<插件根>/scripts/ensure-running.cjs" --json
node "<插件根>/scripts/videocut-cli.cjs" inspect "<项目目录>" --json
```

| 断言 | 不成立时 |
| --- | --- |
| `edit-list.json` 存在且有片段 | 说清楚缺账本，让用户先喊剪口播。**不要自己去剪。** |
| `transcript.json` 存在 | 项目没准备好，停止。不要自己造一份。 |

**不要断言 `source_cut.mp4`，也不要去转录。** 字幕两样都不需要, , 见下一节。

## 2. 改字：先词典，后文稿

**不需要重新转录。** 原来那份逐词稿已经带着时间戳，账本知道哪几段留着, , 每个词落在成片的第几秒是**算出来的**，不是再听一遍听出来的：

```text
词在源片的第几秒   转录里就有
哪几段留着         账本里就有
词在成片的第几秒   两者一算就出来
```

再送一遍 ASR 只是把同样的话重新听一次，花钱、花时间，而且听得更差, , 专名要重新改一遍。
（`transcript retranscribe` 是上一版设计的遗留，那时字幕打算靠转写剪后视频拿时间轴。
字幕改成锚词 id 之后这个问题就没了。**做字幕不要用它。**）

两件不同的工具，都要用。

```bash
# 词典：这个说话人的固定写法，不需要证据
node "<插件根>/scripts/videocut-cli.cjs" transcript dictionary "<项目目录>" --dictionary "<插件根>/references/ai-term-dictionary.md" --json

# 文稿：作者手上有稿子时才做，逐处要证据
node "<插件根>/scripts/videocut-cli.cjs" transcript align "<项目目录>" --script "<口播稿文件>" --json
```

The rest: https://github.com/Agentchengfeng/chengfeng-videocut-skills/blob/HEAD/plugins/chengfeng-videocut/skills/chengfeng-subtitle/SKILL.md
