SRT 文件的构成
SRT 文件是一系列带编号的字幕块。每个字幕块由三部分组成:编号、以 时:分:秒,毫秒 格式书写的开始和结束时间,以及一到两行文字。空行表示一个字幕块结束。
329
00:24:22,584 --> 00:24:23,784
absence ...
视频播放器只读取时间。它会在开始时间到结束时间之间显示文字,其余内容一概忽略。所以译文本身可能读起来毫无问题,播放时却很糟糕:文字没错,只是配到了错误的时间上。
翻译破坏时间轴的三种方式
以下示例来自我们对四项长任务的测试。在该测试中,三个聊天模型各自在一次回复中,把同一份 1,200 行、长 85 分钟的 SRT 文件翻译成西班牙语。
1. 某一行被并入上一行。 原文件第 328 行是 "...take advantage of Lady Bracknell's temporary",第 329 行是 "absence ..."。有一个模型把整句话放进了第 328 行,并删掉了第 329 行。于是屏幕上,"absence" 提前一秒出现,而第 329 行的时间段则是空的。
2. 丢掉一行后,后面的行全部重新编号。 同一个模型随后从 329 起往后连续编号,中间没有留空。到第 357 行又发生了一次合并,1,200 行中就有 870 行的编号与原文件不同。文件仍然可以播放。但如果你或你的编辑按行号把译文与原文对照,329 行之后的每一行都会配错。
3. 时间码中的某个数字被改动。 另一个模型把原本是 00:54:45,839 --> 00:54:51,039 的一行写成了 00:54:55,839 --> 00:54:51,039。这一行的结束时间早于开始时间。根据播放器的不同,它可能被跳过、一闪而过,或者导致文件加载失败。
整体偏移则是另一类问题:从第一行起,每一行都偏差同样的时长,这是因为字幕是按视频的另一个剪辑版本或帧率制作的。翻译不会造成这种情况。
2分钟检查
用任意文本编辑器,把原文件和译文件并排打开。
- 最后一行。 跳到两个文件的末尾。最后一个编号和最后一个时间码应该完全一致。如果译文结束于 1,198,而原文是 1,200,就说明有两行被合并或丢掉了。
- 中间的三行。 从原文中取三个时间码,大致位于全文的四分之一、一半和四分之三处,在译文中搜索。每个时间码在两个文件中的编号应该相同。编号开始对不上的地方,就是丢行的位置。
- 不可能的时间。 找出结束时间早于开始时间的行。文件很长时,用一个小脚本或字幕编辑器的错误检查,可以立刻找出这类问题。
- 最后十分钟。 在播放器中加载译文,跳到接近结尾的位置。如果那里的字幕出现得准时,文件很可能没有问题。
如果你装了 Python,这段简短的脚本可以对任意一对文件执行检查 1 到 3(python3 srtcheck.py original.srt translated.srt)。对我们测试中的三份译文,它准确报出了上述错误。
import re, sys
def cues(path):
text = open(path, encoding="utf-8-sig").read().replace("\r", "")
return re.findall(r"^(\d+)\n(\d\d:\d\d:\d\d,\d{3}) --> (\d\d:\d\d:\d\d,\d{3})", text, re.M)
a, b = cues(sys.argv[1]), cues(sys.argv[2])
print(f"lines: {len(a)} original, {len(b)} translated")
print(f"last: {a[-1]} vs {b[-1]}")
times = {(s, e): n for n, s, e in a}
renumbered = sum(1 for n, s, e in b if (s, e) in times and times[(s, e)] != n)
changed = [n for n, s, e in b if (s, e) not in times]
broken = [n for n, s, e in b if e <= s]
missing = [n for n, s, e in a if (s, e) not in {(s2, e2) for _, s2, e2 in b}]
print(f"renumbered: {renumbered}, changed time codes: {changed[:10]}, "
f"end before start: {broken[:10]}, original lines missing: {missing[:10]}")
如果译文四项检查全部通过,就可以放心使用。如果有一项没通过,通常重新用能保留时间轴的工具翻译一遍,比手动修复文件更快。
行长度需要单独检查
翻译成西班牙语、德语或法语时,译文往往比英文原文更长。Netflix 的英语(美国)风格指南规定每行不超过 42 个字符,每条字幕最多两行。在我们的测试中,1,200 行里含有超过 42 个字符的行的译文行数,因模型不同,从 32 到 447 不等。我们自己的工具得到的结果是 105,所以无论你用什么工具,都值得检查一下:过长的行读起来吃力,但不会破坏时间轴。
如何避免这个问题
上述错误的根源在于,模型在翻译的同时还被要求把编号和时间一并写回。解决办法是不让它碰这些内容。我们的字幕翻译会读取你的 .srt 或 .vtt 文件,只把文本按每块最多 60 行发送给模型,对漏掉的行会再次请求翻译,并且所有编号和时间都直接从你的原文件复制。在同一份 1,200 行的测试文件上,全部 1,200 行返回的编号和时间码都与原文件完全一致。
每个任务的前段免费,无需注册。一整部电影或一整季剧集,最多 5,000 行、最多 30 个文件,只需 $5,一次付费。热门目标语言有专门页面:SRT 翻译成西班牙语、阿拉伯语和波斯语。
方法与数据
来源
- SubRip (SRT file format) — Wikipedia
- English (USA) Timed Text Style Guide — Netflix Partner Help Center
- Timed Text Style Guide: General Requirements — Netflix Partner Help Center