手里有一集播客的 SRT、一堂网课的 VTT,想要一份能读的文字稿——最直觉的做法是把时间码全删了。试过就知道结果没法看:句子在奇怪的位置断开,自动字幕还整段整段地重复。字幕和文字稿之间差的不是删时间轴,而是三步结构还原。
先看字幕文件的本质:它是给播放器的显示指令序列,每条 cue 说的是「这个时间段,屏幕上摆这几个字」。切分依据是屏幕宽度和阅读速度,不是句子结构。拿显示指令当文章读,当然处处别扭。
第一步:去滚动重复
打开一份 YouTube 自动字幕的 VTT,多半会看到这种结构:
00:00:01.000 --> 00:00:03.500
今天我们来讲
00:00:02.800 --> 00:00:05.900
今天我们来讲 文件编码的问题
00:00:05.100 --> 00:00:08.200
文件编码的问题 很多人第一反应是
每条 cue 都拖着上一条的尾巴,时间上还互相重叠。这是滚动式字幕:为了让文字随语音逐词浮现,自动字幕把「渲染过程」编码进了内容里。播放器看到的是平滑滚动,逐条抽出来就是大面积重复——直接拼接的文字稿里,每句话都会出现两遍。
去重不能靠「删除相同行」——重复的两条并不完全相同,是前缀/包含关系。正确的判断依据是相邻 cue 的时间重叠 + 文本包含同时成立,然后只保留每句的最终完整形态。
这个特征也是区分字幕来源的试金石:人工字幕的 cue 首尾相接或留有间隙,滚动字幕大量重叠。人工精校字幕没有重复问题,这一步会自动跳过,不会误删正常内容。
第二步:按标点和停顿合并断句
去重之后的文本仍然是碎的——一句 30 字的话被切成两三条 cue,因为一屏放不下。合并要靠两个信号:
- 标点:cue 结尾没有句末标点(。!?),说明句子没完,和下一条拼接。
- 时间间隔:相邻 cue 间隔小于约 1 秒是句内停顿;超过 1.5–2 秒往往是换话题的自然停顿,即使没有标点也该断开、甚至分段。
两个信号冲突时标点优先。真正的难点是无标点的自动字幕——语音识别常常不打标点,这时只剩时间间隔一个信号,遇上语速快、不换气的讲者,会拼出超长句。这正是下一步要保留时间戳的原因之一。
顺带处理内容噪声:ASS 文件里 {\pos(400,570)} 这类内联样式标签、\N 换行符要先剥离(\N 要换成空格而不是删除,否则前后词粘连);弹幕、屏幕注释这类非对白内容按样式过滤。这部分机制在字幕样式标签清理里有完整展开。
第三步:时间戳留段落级,别全删
三种选择摆在面前:
| 方案 | 可读性 | 可回溯性 |
|---|---|---|
| 时间码全删 | 最好 | 无——引用时只能全文搜索再手动拖进度条 |
| 逐句保留 | 等于没整理 | 最好 |
| 段落级保留 | 接近全删 | 误差不超过一段 |
段落级是明确的甜点位:每个自然段开头留一个 [12:34],正文流畅,需要核对时能跳回原视频。会议纪要(谁在第几分钟说了什么)、课程笔记(复习跳回原片段)尤其受益;后面把文字稿交给 AI 总结时,还可以要求 AI 在结论后附时间戳,输出的每个论点都可回溯验证——这是对付 AI 幻觉最便宜的手段。
格式上把时间戳放段首、用 [mm:ss],别嵌在句子中间,否则会干扰后续的搜索和 AI 处理。
两个特殊格式的注意点
LRC 歌词:一行就是一个完整乐句,不需要断句合并,转文字稿主要是去时间标签。但去重逻辑要反过来——副歌的重复是真实内容。区分依据仍然是时间:滚动残影在时间上互相重叠,副歌重现相隔几十秒,按时间重叠判断的去重不会误伤。老 LRC 常见 GBK 编码,乱了先修,机制见乱码的产生与还原。
双语字幕:中英对照的 SRT 转出来两种语言逐行交错。只要一种语言的话,先过滤次要语言行再走流程。
实际操作
上面三步不需要手写脚本:把文件拖进字幕转文字稿,格式与编码自动识别,滚动重复自动清理,断句合并和段落时间戳可调,全程本地处理不上传。手里还没有字幕文件、只有视频的,先用视频提取音频拿到音轨再走语音转写;各字幕格式本身的差异和选型,见SRT / ASS / VTT / LRC 怎么选。
整理好的文字稿如果长到一次塞不进 AI 对话框,别硬贴——分块策略见长文字稿喂给 AI:token、分块与提示词。