作为一位拥有 PlexPass Lifetime 的高贵的 NAS 用户,最佳的动画观赏姿势,自然是找一把老式躺椅,倒上满满一杯滋滋冒泡的 82 年的冰镇可乐,再打开 Apple TV、启动 Infuse,找个舒服的姿势(最好是能翘着二郎腿),按下遥控器上的播放按钮,伴着风扇吹出的阵阵微风,开始品味最新一集的《GIRLS BAND CRY》。

好吧,没有 Apple TV 不要紧,是不是用的 Infuse 也无所谓,但可乐千万别喝过期的。这里想举例的是,假如你准备好了一部没有内嵌字幕的影片,并从网上找到了大佬精心制作的带有特效的字幕(assssa 格式,这些字幕一般会使用大量的字体丰富显示效果)文件。可准备观看的时候却发现,观影设备的系统中,并没有安装字幕所需的字体,播放器因而调用默认字体渲染字幕。观影体验下降了一个档次不说,华丽的字幕特效也变成了累赘。

如果你用的是 PC 还好,把字幕所需的字体安装一下便可。可假设你想在蹲坑的时候用手机无缝观看呢?又或者是转向客厅的大屏幕电视呢?手机倒是可以想点办法把字体包都丢到播放器里,但电视呢?电视可是没办法安装字体的。(唔……可以的话就当我孤陋寡闻)

因此,为了解决这一问题,常见的做法是连同视频、音频、字幕和字体一并封装进一个 mkv 容器里,就能实现在任意设备上都能得到相同的字幕显示效果,也就是大多数内嵌字幕的新番所用的方法。可问题又来了,我们不可能大费周章把手头的 BDRip 资源加上字幕和字体重新打包,按我目前收集的 400 多部动画的量……我宁可不看特效字幕。

在最开始接触 NAS 的时候,我单纯地认为把字体塞到 Jellyfin 之类支持外部字体的程序中就完事了1,但最终事与愿违。可不内嵌字体,又如何才能以最简化工作流程,实现同等内嵌字体的播放效果呢?最近,我终于发现了另一种方法,可以轻微缓解这一痛点:字体子集化

何谓字体子集化

什么是字体子集化?简单地说,字体子集化就是从一个字体文件中提取出特定字符集合的过程。这在网页上十分常见,例如本站首页使用的「初之音」 ,就是使用了子集化的字体文件。相比完整的 6044 KB 大小的「方正粗金陵」字体文件,这个只包含「初之音」这 3 个字符的子集化字体最终大小只有 3 KB,显著减少了字体下载时间从而提高页面加载速度。

将「子集化」运用在字幕上,则是先将字幕文本分析拆解,生成新的只包含字幕所需字形的字体文件,再将这些子集化后的字体嵌入到 ass 字幕文件中。

字体内嵌示例
字体内嵌示例

例如,下面这个由 Nekomoe kissaten 制作的《铃芽之旅》字幕,所需的字体约为 70MB。

字幕本体为 367 KB。

将所需字体子集化处理后嵌入字幕中,仅为 1826 KB。

前期准备工作

1. 安装 AssFonts

前往 https://github.com/wyzdwdz/assfonts/releases 下载最新版本的 GUI 程序,或者使用我的 备份 下载。

解压后包含如下文件,一般使用 assfonts-gui.exe 即可。

如果有使用命令行的需求,可以将 assfonts.exe 添加至系统环境变量。

点击右下角环境变量。

双击「系统变量」中的 Path。

点击新建,将 AssFonts 的完整路径填入其中,例如我的是 D:\AssFonts,保存即可。

随后便可在 PowerShell 中使用 assfonts 命令。

2. 安装 otf2ttf

根据官方文档中的说明,ASS 字幕只能够嵌入 Truetype 字体,即 ttf 文件。但是 AssFonts 忽略了这个规定,允许任意类型的字体嵌入。这些非 ttf 字体可能不会被某些播放器识别,造成字幕显示异常。

因此,另行安装 otf2ttf 工具,将 otf 字体转换为可供嵌入的 ttf 字体。

使用 Python 安装(如未安装 Python,请自行搜索相关教程安装):

pip install otf2ttf

随后在 PowerShell 中,使用 otf2ttf otf字体文件路径 转换字体。

官方推荐是「先子集化生成 otf格式的子集化字体,再使用 otf2ttf 工具转换子集化字体,然后再嵌入字幕」。我觉得这个挺麻烦的,我是直接将整个 otf 字体转换为 ttf 后,另存他处,确保该经转换后的字体仅供 AssFonts 使用。官方并没有推荐直接转换整个字体,因此不建议像我这么做。

例如,我有个需要转换的字体路径为 D:\mikusa\FOT-UDKakugo_Large Pr6N DB.otf ,那么直接:

otf2ttf "D:\mikusa\FOT-UDKakugo_Large Pr6N DB.otf"

等电脑风扇响一会儿就可以在同路径下看到同名的 ttf 字体了。

3. 准备字体包

虽说大多数时候,你在 Anime字幕论坛 中找到的字幕,楼主通常都会贴心地附上字幕所需字体,但也有没有字体的时候。因此我的建议是:直接下载字体包

你可以在 这里 下载字体包种子,打不开的话也可使用以下磁力链接下载:

magnet:?xt=urn:btih:bc72daa4f58fdda082c603ce6eee1d8199359434&dn=%E8%B6%85%E7%BA%A7%E5%AD%97%E4%BD%93%E6%95%B4%E5%90%88%E5%8C%85%20XZ&tr=udp%3A%2F%2F208.67.16.113%3A8000%2Fannonuce&tr=http%3A%2F%2F208.67.16.113%3A8000%2Fannonuce&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&tr=http%3A%2F%2Ft.acg.rip%3A6699%2Fannounce&tr=http%3A%2F%2Fnyaa.tracker.wf%3A7777%2Fannounce&tr=udp%3A%2F%2Ftr.bangumi.moe%3A6969%2Fannounce&tr=http%3A%2F%2Ftr.bangumi.moe%3A6969%2Fannounce&tr=https%3A%2F%2Ftr.bangumi.moe%3A9696%2Fannounce&tr=http%3A%2F%2Fopen.acgnxtracker.com%2Fannounce&tr=https%3A%2F%2Fopen.acgnxtracker.com%2Fannounce

下载的时候,只下载其中的 精简包,2G 左右。不用全部下载。等到有缺字体的时候,再下载缺少的字体。

只下载精简包
只下载精简包

制作子集化字幕

打开 assfonts-gui.exe,虽然没有中文,但使用起来其实相当简单,总共就三步。

1. 创建字体数据库

将上面下载好的字体包整个拖入到程序的 Font directory 栏中,点击 Build Database 按钮,创建字体数据库。

字体数据库的默认保存位置是自动创建的。另外,程序会自动加载本地已安装的字体。

2. 导入字幕

接着,将需要子集化的字幕拖入 Input Ass Files 一栏中。直接点击 Start 开始制作子集化字幕,其他的选项都不用到。

你应该会注意到下方的日志闪过了一行蓝色,返回去查看具体原因。

如果是下面这些 Missing the font,则表示字体缺失。先去寻找这些缺失的字体,放入字体文件夹中,再执行一次创建字体数据库

如果是下面这种 otf 不兼容的提示,就返回上面准备工作的步骤,把这个字体转换成ttf后,将原 otf 字体移动至别处或直接删除,再执行一次创建字体数据库

然后,再创建子集化字幕。

这样,你就得到了子集化后的字幕文件,它们被重命名为 原字幕名.assfonts.ass 以区分,并生成了一堆子集化字体,存放在对应字幕名的文件夹中。

之后复制或移动这些子集化后的字幕文件即可,生成的包含子集化字体的文件夹没什么用,可以删除。

相比内嵌子集化字体前,仅仅是大了 2M 左右,完全能接受!

3. 其他功能

  • Subset only 选项,表示只做子集化,不嵌入到字幕中
  • Embed only 选项,表示不做子集化,直接把字体嵌入字幕中
  • 上面两个选项都选上,一般用于清理输入字幕中的字体,如果字幕里没找到字体,就什么也不做。
  • Subfonts rename,勾选中这个选项可以在给字体做子集化时给该字体自动更换一个随机的名字,同时修改原字幕中字体名称以匹配这个子集化后的字体。(该功能主要用于防止多个字幕同时集成进同一文件中时,相同名称字体互相冲突的问题)
  • font combined ,勾选后,当输入字幕大于一个时,子集化后会合并相同名字的字体

子集化前后对比

对比子集化前后……虽然不是很明显,但可以看得出来字体上的差异了。

另外,由于不用调用字体渲染,播放也会相对于子集化前顺畅一点。

子集化前
子集化前

子集化后
子集化后

好像选了个效果不是很明显的片段……嘛,总之快来试试吧!

参考

另可参考: