Skills DirectorySearch all skills ↗

AI agent skill · by @xiaohuailabs

字幕润色

专业字幕润色技能:将 ASR 转写或外语字幕翻译润色为高质量简体中文字幕。修正识别错误、优化断句、严格对齐时间戳、符合当代中文表达习惯。当用户说'润色字幕''翻译字幕''字幕校对''字幕润色''SRT翻译'时使用。

Archived 2026-10-23 · Source updated 2026-06-08 · License: MIT. Check the original repository for the latest version.

SKILL.md instructions

# 专业字幕润色技能

## 适用场景

- Whisper 等 ASR 转写的英文/中文原始字幕 → 润色为高质量中文字幕
- YouTube 自动生成字幕 → 纠错 + 翻译
- 任何 SRT/VTT 字幕文件的翻译和润色
- 配合 `xiaohu-video-download` 技能的字幕处理环节使用

## 使用方法

```bash
# 润色/翻译字幕文件
/xiaohu-subtitle-polish /path/to/subtitle.srt

# 指定输出路径
/xiaohu-subtitle-polish /path/to/subtitle.srt --output /path/to/output.srt

# 配合视频使用(可参考视频内容辅助理解上下文)
/xiaohu-subtitle-polish /path/to/subtitle.srt --video /path/to/video.mp4
```

## 角色定义

你是一名「专业字幕文案编辑」,擅长中文写作、口语还原与字幕排版规范。

## 润色规则(核心)

### 1. 纠正 ASR 识别错误
- 修正同音字、近音字错误
- 修正专有名词拼写(人名、地名、公司名、产品名、技术术语)
- 修正数字、外文缩写、单位等识别错误
- 如有 `--video` 参数,可参考视频画面文字辅助判断

### 2. 标点与书面化
- 补全标点使口语转为书面表达,但保留说话人的语气风格
- **最终输出的字幕文本中去掉所有标点符号**(逗号、句号、问号、感叹号等全部去掉)
- 英文和中文之间加一个英文空格(如:`这是 Google 的产品`)

### 3. 去冗余
- 去除无信息负载的口头语、重复、语气词(如"那个""呃""嗯""就是说")
- 删去冗余时确保语义连续,不丢关键信息
- 避免过度删减——宁可保留略冗余也不要丢失意思

### 4. 时间戳对齐(严格)
- 原始时间戳必须严格保留,不得随意偏移
- **翻译字幕时的细粒度转写**:当需要将英文 SRT 翻译为中文字幕时,必须先用 Whisper `-ml 50` 参数重新生成细粒度分段(约 100+ 段 vs 默认 ~50 段),以获得更精确的时间锚点。命令示例:
  ```bash
  # 此细粒度重转写需备份引擎 whisper-cli(whisper-cpp)+ ggml 模型,安装见 xiaohu-video-md/初始化.md
  whisper-cli -m ~/.cache/whisper-cpp/ggml-large-v3-turbo.bin -t 8 -ml 50 audio.mp3 -osrt -of output_short
  ```
- **绝不手动提前 start time**:每条中文字幕的 start time 必须 = 对应英文内容所在 Whisper 段的 start time。手动前移会导致字幕跑在说话人前面
- **超长挂屏裁剪(基于静音检测)**:当一条字幕的时间跨度 >6 秒且文本较短时,说明 Whisper 把语音后的静音/BGM 都算进了同一段。此时必须用 ffmpeg 静音检测来精确定位语音结束点,而不是用公式估算:
  ```bash
  # 检测该段时间范围内的静音区间(-30dB 以下持续 0.5 秒视为静音)
  ffmpeg -i <音频文件> -ss <start_time> -to <end_time> -af silencedetect=n=-30dB:d=0.5 -f null - 2>&1 | grep silence_start
  ```
  取第一个 `silence_start` 的时间点作为裁剪后的 end time(加回 start_time 偏移量)。如果没检测到静音(整段都有声音),保留原始 end time 不裁剪
- 如果原始字幕的一条时间跨度过长(>8秒)且文本较长,可拆分为多条,但时间戳必须在原始范围内合理分配
- **禁止合并相邻条目**,只允许拆分。短条(3-4字)也不合并,短条比长条的阅读体验好
- 拆分后重新编号(序号连续)
- 禁止出现时间戳重叠

### 5. 断句与分段
- **核心原则:可以拆,不可以合**
- **翻译时以原文 SRT 分段为节奏锚点**:一条原文对应一条译文,超 12 字按语义断点拆成两条(时间戳按比例分配)
- **以单行为主**,只在内容确实太长时才用两行,绝不超过两行
- 每行不超过 12 个中文字符(含空格和英文)
- 在语义自然的位置断句,不要把一个完整短语拆到两条里
- 优先在语气停顿处断开
- 宁可多拆一条短字幕,也不要在屏幕上堆多行文字

### 6. 专有名词处理
- 人名、地名、公司名、产品名保留原文,首字母大写
- 技术术语保留英文原文(如 API、GPU、AI、ASR)
- 广为人知的品牌/产品名不翻译(如 Google、iPhone、YouTube)
- 不常见的专业术语可附带简短中文释义(仅首次出现时)

### 7. 语言风格
- 符合当代年轻人用语习惯和网络流行表达
- 日常用语、网络用语、俚语翻译要自然接地气
- 避免翻译腔(如"这是非常令人兴奋的"→"这真的很酷")
- 旁白/解说用简洁书面语,对话/歌词保留口语感

### 8. 歌词处理(特殊)
- 视频中的歌词段落用 ♪ 符号包裹(如 `♪ 歌词内容 ♪`)
- 歌词翻译注重意境和押韵,不必逐字直译
- 歌词和旁白交替出现时,确保观众能区分

## 输出格式

**严格 SRT 格式**:

```
1
00:00:00,000 --> 00:00:03,500
这是第一条字幕内容

2
00:00:03,500 --> 00:00:07,200
这是第二条字幕内容
```

**格式要求**:
- 序号从 1 开始连续编号
- 时间戳格式:`HH:MM:SS,mmm`(用逗号分隔毫秒)
- 字幕文本无标点符号
- 英文与中文之间有英文空格
- 每条之间空一行
- 文件末尾空一行

## 双语字幕模式(中英对照,中文大 / 英文小)

**触发**:用户说"双语 / 中英 / 中英双语 / bilingual",或上游 video-md 传 `--bilingual`。

**核心目标**:中文是主角、英文是辅助。中文用大字号醒目,英文用小字号退居其次,形成反差对比——不是中英同样大小平铺。

### 双语流程(三步,不要走单语 SRT 的老路)

1. **翻译产出「双语 SRT」**:和单语一样逐条翻译,但每条保留**两行内容**——中文在上、英文(原文)在下,**时间戳与原文 SRT 一句对一句完全对齐**(不重新断句、不合并条目,原文怎么切中文就怎么对)。中文行照常去标点、规范术语;英文行保留原文(仅修正 ASR 识别错误,如 Claude 被听成 cloud、MCP 被听成 NCP)。
   ```
   1
   00:00:19,239 --> 00:00:21,239
   大家好吗
   Hello everyone, how are you?
   ```

2. **转双语 ASS**(中文大 / 英文小):调脚本,**不要手写 ASS**。
   ```bash
   python3 scripts/bilingual_ass.py <双语SRT> --output <双语ASS> [--cn-size N] [--height 视频高度]
   ```
   - 用户在对话里明确给了字号(如"字号 24")→ 传 `--cn-size 24`,英文自动按 中文 / 1.7 算(=14)。
   - 没给 → 脚本按视频分辨率选默认(见脚本内 SIZE_TABLE)。
   - 中文︰英文 ≈ **1.7 倍**是实测干净的反差比例(2026-05-31 定)。

3. **烧录走 `ass=` 滤镜**(不是 `subtitles=`):
   ```bash
   ffmpeg -y -i <视频> -vf "ass=<双语ASS>" -c:a aac -b:a 128k <输出>
   ```
   带水印时把 `ass=...` 和 drawtext 串在同一条 `-vf` 里。

### ⛔ 为什么双语必须走 ASS、不能用 SRT + force_style

`subtitles` 滤镜的 `force_style` FontSize 对**整条字幕统一生效**,没法让一条里中文大、英文小。而 SRT 文本里写 inline `{\fsN}` 会被 ffmpeg 的 srt 解码器**剥离**(2026-05-31 实测:三档字号烧出来 md5 完全相同 = inline 没生效)。只有真正的 ASS 文件喂给 libass,才能在一条字幕内 `\N` 换行 + inline 切字号。`bilingual_ass.py` 就是干这个的。

---

## 工作流程

### 步骤 1:读取字幕文件

1. 读取输入字幕文件(SRT 或 VTT 格式)
2. 如果是 VTT 格式,先转换为 SRT 格式处理
3. 检测字幕语言(中文/英文/日文/其他)

### 步骤 2:分析上下文

1. 通读全部字幕,理解整体内容和主题
2. 识别说话人风格(正式演讲/日常对话/教程讲解/产品介绍等)
3. 标记专有名词、技术术语
4. 区分旁白、对话、歌词等不同内容类型

### 步骤 3:逐条润色

按润色规则处理每一条字幕:
1. 纠正识别错误
2. 翻译为中文(如原文非中文)
3. 去冗余
4. 调整断句
5. 检查时间戳对齐

### 步骤 4:全局校验

1. **时间戳校验**:确认无重叠、无跳跃、序号连续
2. **语义校验**:通读全文确认翻译连贯、无遗漏
3. **格式校验**:每行字符数、标点已去除、空格正确
4. **编号校验**:从 1 开始连续编号

### 步骤 5:输出

1. 将润色后的字幕保存为 SRT 文件
2. 输出路径:
   - 有 `--output` 参数:按指定路径保存
   - 无指定:保存为 `<原文件名>_zh.srt`(同目录)
3. 报告处理结果:总条数、合并/拆分数、修正项

## 与 xiaohu-video-download 联动

当 `xiaohu-video-download` 技能的字幕处理环节需要翻译时,可直接调用本技能的润色规则:

1. video-download 完成 Whisper 转写 → 输出原始 SRT
2. 本技能接手润色 → 输出高质量中文 SRT
3. video-download 继续烧录字幕流程

联动时无需用户手动触发,由 video-download 在字幕翻译步骤自动应用本技能的规则。

## 烧录字幕样式(ffmpeg force_style)

### 默认样式(视频无已有硬字幕)

```bash
ffmpeg -y -i input.mp4 \
  -vf "subtitles=subtitle.srt:force_style='FontName=PingFang SC,Bold=1,FontSize=20,PrimaryColour=&H00FFFFFF,OutlineColour=&H40000000,Outline=1,Shadow=0,MarginV=30'" \
  -c:a aac -b:a 128k output.mp4
```

> 此样式经小互确认为"完美"(2026-02-19)。

### 避让样式(视频已有硬字幕时)

当视频底部已有烧录过的字幕(如英文原字幕),新字幕需上移避让。**按分辨率选参数**:

**720p 避让**:
```bash
ffmpeg -y -i input.mp4 \
  -vf "subtitles=subtitle.srt:force_style='FontName=PingFang SC,Bold=1,FontSize=18,PrimaryColour=&H00FFFFFF,OutlineColour=&H40000000,Outline=1,Shadow=0,MarginV=80'" \
  -c:a aac -b:a 128k output.mp4
```
> 720p + MarginV=80 + FontSize=18 经验证不遮挡(2026-03-17 NVIDIA Olaf 视频)。

**1080p 避让**:
```bash
ffmpeg -y -i input.mp4 \
  -vf "subtitles=subtitle.srt:force_style='FontName=PingFang SC,Bold=1,FontSize=19,PrimaryColour=&H00FFFFFF,OutlineColour=&H40000000,Outline=1,Shadow=0,MarginV=42'" \
  -c:a aac -b:a 128k output.mp4
```
> 1080p + MarginV=42 + FontSize=19 经验证不遮挡(2026-03-15 HydraDB 视频)。

**烧录后必须截帧确认不遮挡**,如有问题微调 MarginV。

### 样式参数说明

| 参数 | 默认值 | 720p避让 | 1080p避让 | 说明 |
|------|-------|---------|----------|------|
| FontName | PingFang SC | 同 | 同 | 苹方字体 |
| Bold | 1 | 同 | 同 | 加粗 |
| FontSize | 20 | 18 | 19 | 避让时略小 |
| PrimaryColour | &H00FFFFFF | 同 | 同 | 白字 |
| OutlineColour | &H40000000 | 同 | 同 | 半透明黑边 |
| Outline | 1 | 同 | 同 | 描边宽度 |
| Shadow | 0 | 同 | 同 | 无阴影 |
| MarginV | 30 | 80 | 42 | 底部边距 |

## 质量标准

- 翻译准确率 > 95%
- 时间戳偏差 < 200ms
- 无标点残留
- 无编号断裂
- 每条字幕可在显示时间内舒适阅读完毕

Related skills