Gavin,随笔
EN

头像里的妹妹让同一段声音在不同电脑上变成实时字幕

mimi 最早只跑在 Mac 上,现在已经是跨平台的实时字幕工具。它直接听电脑正在播放的声音,把日语、英语或韩语识别出来,再翻成简体中文、英语或日语,字幕浮在原来的画面上。

我做它,是因为没有字幕的日语视频一直很难看懂。十几岁时只能看表情、听语气,剩下全靠猜。后来同样的问题又出现在日剧、游戏和直播里,我干脆把它做成了一个通用工具。

名字来自日语「耳」的读音みみ,写成罗马字就是 mimi。没有更深的寓意,也不是谁的名字。

字幕晚两秒,翻对了也没用

第一版真正跑起来时,我还高兴了一下:系统声音能抓到,日语也能变成中文,整条链路算是通了。

然后我看了几分钟,开始受不了。

声音已经说完,字幕还在路上;下一句来了,上一句才慢悠悠地出现。有时翻译本身没错,体验却像一个人永远慢半拍给你解释剧情。字幕晚两三秒不是“稍微有点延迟”,它会直接把观看节奏切碎。

mimi 做的事其实不长:听系统声音,识别,翻译,再把字幕放到原画面上。问题是每一步都等上一部彻底完成,串起来就一定慢。要是非等整句话识别完、翻译完才显示,字幕永远只能追着声音跑。

同一句话,要跑草稿和终稿两条路

后来我不再等“完整答案”,把一句话拆成了草稿和终稿。草稿负责尽快出现,可以随时被更新的内容替换;终稿负责把确认过的整句留下,顺序不能乱。

语音识别会不断修正草稿。比如前半秒只听到「今日は」,后面又补成「今日は帰らない」。如果每个草稿都老老实实翻到底,旧翻译还没回来,新文本已经变了,屏幕上就会排起一队过期答案。

所以 mimi 只保留最新草稿。新的识别文本来了,旧翻译还没结束,就让它给更新的句子让路。

终稿反过来不能抢。上一句还没翻完,下一句就先显示,会把对话顺序弄乱,所以确认后的句子要一个个落地。

实时字幕最麻烦的地方就藏在这里:快的结果可以不稳定,稳定的结果必须按顺序。两条路混成一条,要么迟到,要么乱跳。

字幕不能一直堆下去

识别和翻译跟上以后,屏幕又开始出问题。人连续说一长段话,整段文字一直重排,眼睛根本找不到刚才读到哪。切得太碎也不行,一句话会变成几条弹幕,快是快了,读起来很累。

mimi 会尽量在一句话说完的地方切开。已经确认的小句留在上面,慢慢变淡;只有正在说的最后一小段继续更新,不让半成品把整个窗口占满。

听起来只是显示细节,实际上它决定了屏幕上的是字幕,还是一份不断刷新的终端日志。

现在能做什么

这里的“实时”当然不是零延迟。网络、识别和翻译都要时间,刚开始也得给它一点机会追上声音。零延迟做不到,旧任务别排队拖死新字幕倒是能管一管。

mimi 的目标也不是会议转写。它没有账号和云端历史,也不负责把一整晚的内容整理成稿。内存里留一点刚刚说过的话,只是为了屏幕显示和翻译上下文,不会把它们写进硬盘。

下面三张是使用场景的二次元示意图,不是产品截图:

日剧:字幕直接盖在播放器上,不用另外找字幕文件。

头像里的妹妹用 mimi 看没有字幕的日剧

游戏:锁定字幕窗以后,鼠标可以穿过去,原来的操作不受影响。

头像里的妹妹用 mimi 玩对白很多的游戏

直播:直接听系统声音,没有现成字幕也能跟。

头像里的妹妹用 mimi 听日语直播

代码和最新版下载都在 GitHub (opens in a new tab)。第一次使用可以配置默认的阿里云百炼档案,也可以新增 OpenAI Realtime 档案;模型调用可能产生费用,这一点还是得提前说清楚。

跨平台以后,第一次启动遇到的权限和安全提示会因系统而异;人名、作品名和说得太快的句子也还是会翻错。可现在遇到没有字幕的视频,我会先把 mimi 打开,不再到处搜字幕文件。