srt-cn-translator
把单语英文 .srt 转换为书面正剧风格的中英双语 .srt。本 Skill 模型无关:不绑定任何 API,翻译由宿主 Agent 使用自己的模型完成;脚本只做确定性处理。
前置条件
- Python 3.9+,仅使用标准库,无需安装第三方包。
- 脚本位于本 Skill 的
scripts/目录。
工作流
1. 解析与清洗
在输入文件同目录创建 workdir(避免写 C 盘,例如 .<stem>.work),然后:
python scripts/srt_cli.py parse "<input.srt>" "<workdir>"
产物:<workdir>/blocks.jsonl(清洗后的可译块)、<workdir>/meta.json。
清洗会自动删除:说话人标签(LEX:)、音效((BIRDS CHIRPING))、ASS 标签({\an2}、{\pos(...)})、内联标签(<i>)、歌词音符(♪)。屏幕文字卡与歌词文本保留。
2. 分块
python scripts/srt_cli.py chunk "<workdir>" --max-tokens 3000 --overlap-tokens 200
--max-tokens是“输入 + 预估中文输出”的总预算;弱模型建议下调到 1500–2000。- 产物:
<workdir>/chunks.json,每个 chunk 含context_blocks(上文重叠,仅作上下文)与target_blocks(需要翻译)。
3. 逐块翻译(LLM)
对每个 chunk(1..K)循环:
- 渲染本块 Prompt:
python scripts/srt_cli.py translate render "<workdir>" --chunk <k>
第 1 块会自动读取<workdir>/context.md(首次为空)。 - 把渲染出的 User Prompt 连同下方 System Prompt 发给模型,让模型只返回
target_blocks的 JSON 数组。 - 保存本块结果:
python scripts/srt_cli.py translate save "<workdir>" --chunk <k> --json "<响应文件.json>" - 更新运行摘要(≤200 token,人物/机构/地名译名、剧情要点、风格与指代):
python scripts/srt_cli.py context set "<workdir>" "<摘要文本>" - 用
translate status检查进度,直到missing=0。
4. 校验与重译
python scripts/srt_cli.py validate "<workdir>" --translations "<workdir>/translations.json"
- 退出码 0 = 通过;1 = 有错误。
- 有错误时读
<workdir>/report.md,只修复对应id的译文(直接编辑translations.json或重跑对应 chunk 的translate render/save),再校验。 - 校验会动态读取本 Skill 根目录的
sensitive_words.txt;命中的具体词会写入报告。 - 单块最多重译 2 轮;仍不通过则停止并如实报告,不要产出残缺文件。
5. 合成双语 SRT
python scripts/srt_cli.py merge "<workdir>" --translations "<workdir>/translations.json"
产物:<原文件名>.zh-en.srt(UTF-8 无 BOM、CRLF,中文在上、英文在下)以及 <workdir>/index_map.json(输出序号 seq_id → 原始序号 index 的映射)。
6. 交付
向用户给出输出文件路径,并简述:保留块数、删除噪声块数、校验错误数。
System Prompt
你是一名资深影视字幕译者,负责把英文 SRT 字幕翻译成中文。
翻译要求:
1. 语体:始终使用书面正剧语体,庄重、自然、符合剧情时代;严禁脏话、俚语、网络流行语;避免翻译腔。
2. 标点:中文使用全角标点,句末补齐句号/问号/感叹号;英文保持原标点。
3. 实体:人名、机构、地名使用标准中文译名,并保持全片一致;优先参考 glossary 中已确认译名(如 KGB→克格勃,CIA→中央情报局)。
4. 屏幕文字卡(时间、地点、标题、演职员表等):中文译文用双引号 "" 包裹;职务/角色与人名之间用 \\ 分隔。
5. 歌词:正常翻译,不加任何标记。
6. 只翻译“可译文本”;不要输出解释、注释、Markdown 或额外文字。
输出:严格返回 JSON 数组,schema 为:
[{"id": 1, "zh": "中文译文"}]
不要返回英文原文,脚本会从源文件回填英文。
User Prompt(每个 chunk)
下面是第 {k}/{K} 块字幕。
前文摘要(如无则为空):
{context}
需要翻译的字幕(每行:id<TAB>英文):
{target_lines}
上文重叠字幕(仅作上下文,无需翻译):
{context_lines}
请翻译“需要翻译的字幕”并严格返回 JSON 数组,不要输出任何其他内容:
[{"id": 1, "zh": "中文译文"}]
context_lines为空时整行省略。target_lines每行格式为id<TAB>清洗后英文。
JSON Schema
[{"id": 1, "zh": "先生,把马交给我吧。"}]
id:清洗后块的seq_id。zh:中文译文。- 返回中的
en字段可省略;即使返回也会被忽略,脚本统一从blocks.jsonl回填英文。
风格红线
- 书面正剧风,禁脏话/俚语/网络流行语;强侮辱/强恶意词由敏感词库硬过滤,网络流行语由 Prompt 软约束。
- 屏幕文字卡用
""包裹,职务/角色与人名用\\(两个反斜杠)分隔。 - 歌词翻译保留,中上英下,不加标记。
- 同一实体译名全片一致。
敏感词库维护
- 文件:本 Skill 根目录
sensitive_words.txt,一行一词,#为注释,空行忽略。 - 只收录强侮辱/强恶意词;偏书面词(如“荡妇”)与网络流行语不进库,由翻译 Prompt 软约束。
- 查看:
python scripts/srt_cli.py sensitive list - 加入:
python scripts/srt_cli.py sensitive add "<词>"(用户说“把 XX 加进敏感词库 / 屏蔽 XX”时执行) - 移除:
python scripts/srt_cli.py sensitive remove "<词>"(用户说“XX 不算敏感词 / 放出来”时执行)
命令一览
parse:解析与清洗chunk:分块translate render|save|status:翻译脚手架(渲染 Prompt / 保存结果 / 查看进度)context get|set|clear:管理上下文摘要validate:校验merge:合成双语 SRT + 序号映射sensitive list|add|remove:维护敏感词库
异常处理
- 空文件/无字幕块:报告并请用户检查输入。
- 非
.srt:拒绝处理。 - 非 UTF-8:脚本会自动尝试常见编码;无法识别时提示用户转码。
- 模型返回多余字段/注释/Markdown:只取
id/zh,其余忽略并告警。 - 时间轴乱序/重叠:不修复,写入报告告警。