| name | segment-subtitles |
| description | 字幕断句(合并/分割)的规范。ASR 自动字幕常无标点,合并以语义完整性为判据而非标点;含英文预整理(游离单词归位)、两遍式定段、多说话人对白拆分、行宽规则、相邻段时间不重叠(共享 cue 整条归属 / 中间断句估算切分)。翻译工作流阶段一第一次遍历归位、阶段二断句时使用;分块见 redstone-conventions「长视频分块」。 |
字幕断句规范
适用范围
- 输入多为 YouTube 自动字幕:无标点、按 cue 切分、常把句子首尾单词甩到行外
- 断句 = 合并 ASR 碎片成完整句 + 分割超长句/对白为多段独立字幕
- 两遍式:翻译前只能靠英文语义做初步分组;"中文为主导"的最终定段在译成中文后进行
工作流程(处理顺序)
- 英文预整理(游离单词归位)-> 英文预整理
- 第 1 遍(英文侧,初步分组):以整理后的英文句的语义边界为据(标点仅最弱参考、不作依据),把碎片拼成句级单元,只保证语音/语义连续 -> 合并判据;说话人切换拆段 -> 对白拆分
- 分块(长视频)-> redstone-conventions#长视频分块
- 翻译(每块交 subagent,prompt 按 subagent-dispatch#派发配方 组装)
- 第 2 遍(中文侧,最终定段):以中文为主导做最终合并与分割 -> 合并判据 分割超长句:
- 中文读着零碎/别扭的片段 → 合并成语义完整单元(中文怎么顺就怎么分)
- 禁止段内多行(同一时间码内把一行中文拆成两行)
- 禁止把超宽整句一字不动留成一段
- 校验(时间边界 / 时间不重叠 / 段序 / 行宽)-> 输出与校验
以上为处理顺序;各步详细判据见对应章节。
长视频分块
分块是全流程通用机制(术语扫描/合并/翻译/去翻译腔都用),已不属于断句规范——工具、参数与结转规则见 redstone-conventions#长视频分块。
英文预整理(游离单词归位)
ASR 按 cue 切分常把句子的首尾单词甩到行外(如 ...a design. My 的 My 属下一句、...wrong. In 的 In 属下一句)。分组前先把这类游离单词归位到所属句子,整理出干净的英文句子流;归位只在既有 cue 内重分布文本,不改动时间码。
合并判据:语义完整性(不以标点为准)
ASR 可能完全无标点,合并的唯一判据是语义完整性——一个完整的思想/句子:
- 按内容判断句子是否说完(主谓宾完整、语义闭合)
- 辅助信号(非硬性):
- 相邻 cue 时间间隙偏大(≈0.5s 以上)
- 内容转折/承接词(so / but / and then / because 常开启新句或承接)
- cue 末尾明显未完(连词、介词收尾)
- 原字幕若有标点:有则参考、不作依据
- 边界只允许取整条 cue:合并后的段时间码 = 首 cue start → 末 cue end,必须 ⊆ 原字幕边界集合(项目硬规则)
- 相邻段时间不得重叠(项目硬规则):
段 i 的 end ≤ 段 i+1 的 start(允许相接、不允许交叉)——句子边界落在 cue 中间(共享 cue)时见 共享 cue 与整条归属
- 空 cue([Music]/[Laughter] 等无文本)不单独产出:时间并入相邻段;校验若报"未覆盖 cue"即这些空 cue,组装脚本自动并入前一段即可
语义锚点
英文行始终锚定原 ASR 的语义边界(标点仅最弱参考、不作依据),中文段与英文句一一配对——保证合并/定段后英文句与中文段一一对应。
共享 cue 与整条归属(时间不重叠)
- 硬规则:相邻段时间不得重叠——
段 i 的 end ≤ 段 i+1 的 start(允许相接,不允许交叉)。与「⊆ 原边界集」并用,杜绝"两段覆盖同一段时间"的坏结果
- 句子边界常落在 cue 中间(一个 cue 含两句首尾,即共享 cue)。此时整条 cue 归属一侧,边界回到 cue 边界:
- 归属判据:语义占多数的句子,或先开始的句子优先(其 start 已固定,只需定 end)——整条 cue 归它:前段 end = 该 cue 的 end,后段 start = 下一 cue 的 start
- 结果:文本仍按语义归位(各句文字完整),但共享 cue 内对方句子头尾几个词的时间会偏移一个小 cue 时长(ASR cue 通常 2–4s,可接受)——文本完整、时间近似、不重叠
- 禁止两段共用同一 cue 却不标注估算(=时间重叠,检测脚本报错);共享 cue 文本仍按归属句写入,不重复、不遗漏
- 若整条归属会造成明显错位(如同一 cue 内两人问答)、必须从中间断开且无时间戳参考 → 中间断句与估算时间
对白拆分(多说话人)
- 说话人切换 → 拆成独立段,不标注说话人
- 识别切换主要靠语义:问答句式、话题转换、句首呼名(如 "ragou, ...")、语气词变化
- 时间戳仅作辅助信号(间隙大 → 疑似切换),不作为分割依据——ASR 不一定在说话人切换时记录 cue
- 同一 cue 内两人对白(无时间戳参考):默认整条 cue 归属一侧;必须中间断开时 → 中间断句与估算时间
- 单人讲解中的"自问自答"不拆,保持一段
分割超长句
- 中文行超宽(>26 视觉宽度,硬限制)的整句 → 分割为几段独立字幕,每段独立序号与时间码(>22 软告警)
- 分割点优先在语义相对完整处,不硬切残句
- 分割后各段时间码取原段内连续 cue 的 start/end,仍 ⊆ 原边界集
- 分割点落在 cue 中间且无时间戳参考 → 优先整条 cue 归属;必须精确切分时 → 中间断句与估算时间
中间断句与估算时间(受控例外)
- 默认:优先整条 cue 归属(见 共享 cue 与整条归属),不新造时间点
- 何时需要估算:对白切换 / 超长句行宽切分,切分点必须落在 cue 中间,且无时间戳参考;整条归属会造成明显错位
- 估算切分点(对「⊆ 原边界集」的唯一受控例外,只此一种新造时间点):
- 公式:
split = start_c + (end_c − start_c) × w1/(w1+w2)(w = 该侧在 cue 内的文本视觉宽度/字符数)
- 严格落在父 cue 的
[start_c, end_c] 内
- 四舍五入到 100ms
- 单调且不重叠:
前段 end ≤ split ≤ 后段 start(相邻段同用该估算点时取等号 = 相接)
- 必须标注:03_segments.md 的 cue 范围加
~(如 39|c112-c114~|),检测脚本跳过其「⊆ 原边界集」检查、但仍强制不重叠;成稿 SRT 用 --allow-estimated 复核
- 估算点是例外不是常态:能用整条 cue 归属解决的不要估算
行宽规则
中文行按视觉宽度判断——CJK=1、拉丁≈0.5/字符、数字≈0.5/字符(半角标准,2026-08-11 由拉丁≈1.52/数字≈12 修正:虚高会把带英文行推成长句);目标 15-22、软告警 >22、硬限制 >26(必切);禁止用 Python len() 判断(会虚高拉丁行)。15-22 是上限方向的目标,不是下限——不因行过短而强行合并。行宽是「分割超长句」的触发判据(>26),也是第 2 遍定段的目标。
阅读时长(5 字/秒)
行宽管"一行放多少字"(视觉),阅读时长管"这条字幕够不够读完"(时间):
- 中文按 5 字/秒估算阅读时长:
字数 ÷ 5 ≈ 所需秒数——对照对应英文 cue 的显示时长(或切分后各单元时长),读不完(中文所需 > 显示时长)的单元:优先在语义完整处切短;切不动 → 交回填阅读插值兜底
- 阅读插值(回填侧):倒装语序 / 中英时长差异大时不能仅匹配英文 cue——按 5 字/秒在整句区间内按阅读时长比例重分配,切分点就近吸附真实 cue 边界(无则 100ms 预测点);触发 = 长句碎片(<1s)或显著失配(< 阅读所需×0.7 且失配 ≥300ms)
- 单条字幕时长通常 ≥1s:同一整句拆出的 <1s 单元 =「长句碎片」(语义自足独立短句除外)——分句/切分时应避免制造 <1s 单元;碎片由校验回报、Agent 裁决合并或调整切分点
输出与校验
- 断句定稿写入
s03_plan.md(格式见 translate-redstone#阶段二正式翻译 · 产物契约)
- 每次合并/分割后立即校验(必须通过才能进入下一步):
- 时间不重叠 + 边界归属 + 段序:
python scripts/srt_check_segments.py <03_segments.md 或 draft.srt> --orig <01_subtitle_asr_fixed.srt>(检查相邻段 end_i ≤ start_{i+1} 不重叠、时间边界 ⊆ 原边界集、不逆序、cue 覆盖完整;默认只给问题数,--expand 看每条明细)
- 中文行宽:
python scripts/srt_check_width.py <draft.srt> --order en-zh
- 成稿(04_translation_draft.srt)用
srt_check_segments.py 复核一次;含标注 ~ 的估算切分点时加 --allow-estimated(新造时间点降为告警)
- 一次性辅助脚本随视频放
_work/<视频>/,用后即弃;可复用的检测脚本在 scripts/