跳到主要内容

字幕滤镜基础知识

待办事项(面向维护者)
  • 添加图片;
  • 替换更合适的 ASS 脚本样本。
本节学习目标

掌握滤镜基础知识,知晓应如何选择合适滤镜。

字幕滤镜基本原理

基本原理

本小节仅介绍字幕滤镜最基本的工作模式。如果你想更详细地了解字幕的渲染过程,可自行查阅相应滤镜的源代码。

字幕组和压制组在制作过程中,一部最终成品的形成通常会经历以下步骤:

步骤制作字幕
(字幕组)
内嵌字幕
(字幕组)
BDRip / WebRip
(压制组 / 字幕组)
说明
获取片源抓取光碟、WebDL、TVRip 等
导入片源
瑕疵修复如降噪、去(抗)色带、抗锯齿等
视频缩放制作与片源不同分辨率的版本
通常不会制作超分辨率版本
渲染字幕到视频
播放器挂载字幕✅(观众)包括使用字幕编辑器观看
压制组通常不自行制作字幕

【图例】✅:通常包含此操作。❓:有时包含此操作。空白:通常不含此步骤。

滤镜是字幕组和压制组处理视频工具链的基本工具之一。上表中每一步的操作均是通过一个或多个滤镜的组合使用完成的,字幕也不例外。
字幕滤镜的基本原理是根据字幕脚本所定义的信息,将指定的文字(或图形)在视频的指定时间以指定的样式绘制到指定的位置上。
libass 绘制 ASS 格式字幕脚本为例,其基本流程如下:

  • 读取字幕脚本文件(即 .ass 文件)【源代码】
  • 对于指定的时刻(时间戳)【源代码】
    • 将该时刻所包含的所有事件([Events])中的行分别绘制成位图【源代码】
    • 根据事件层次(Layer),由低到高叠加绘制出的位图【源代码】

常用字幕滤镜与选择

目前主流字幕滤镜可简单分为两个大类:基于 VSFilter 和基于 libass 的字幕滤镜。
基于 VSFilter 的字幕滤镜是目前播放器的主流字幕滤镜,其中 xy-VSFilter 被广泛使用,兼顾性能和正确性。最大的缺点是只能在 Windows 平台使用
libass 是以跨平台为目标的后起之秀,虽然中间经历过一段时间的沉寂,但目前在积极维护中。
libass 的设计目标是尽可能保持和 VSFilter 一致的渲染结果,目前已成为字幕组和跨平台播放器的首选滤镜。
没有特别说明时,均默认讨论基于 libass 的字幕滤镜。

不同视频分辨率下显示错误 Bug

滤镜的选择和字幕脚本文件的推荐属性设置涉及一个影响非常深远的不同视频分辨率下显示错误 bug(后文简称「显示 bug」)。
由于关于该 bug 的讨论非常繁杂,若有兴趣可参考以下讨论:

简单来说,显示 bug 的前因后果可以总结为以下几个要点(不理解也没有关系,照做设置就行):

  • 技术背景:ASS 脚本的部分特效标签(注 1)的渲染依赖视频的存储分辨率(video’s storage resolution,注 2)计算图形的变形拉伸(anamorphic stretching),因此可以认为 ASS 脚本是为某一特定分辨率的视频文件制作的,传统的 ASS 脚本中以脚本分辨率(PlayRes)记录对应视频的显示分辨率;
  • 现实情况:跳出日本动画片的范畴来看,有的外国电视剧等可能是纯电视播出的,通常片源的分辨率较低(假设制作时的字幕分辨率为 1280 x 720),而后日发售的光碟上获取到的片源则通常拥有更高的分辨率(假设光碟的分辨率为 1920 x 1080);
  • 出现问题:我们希望将该 ASS 脚本复用于更高分辨率的片源(即用一个 ASS 脚本生产不同分辨率的成片),此时便出现了同一个 ASS 脚本挂载到两种不同分辨率的视频上的情况,进而这些依赖视频分辨率的特效标签的渲染效果出现了异常;
  • 临时解决:一个简单的解决方法是尽量避免使用受影响的标签(实际上也是这样做的),用其他不受影响的标签代替(例如用 \fax\frz 模拟 \frx\fry\fay),但这样做非常麻烦,也不是长久之计;
  • 根本解决:为 ASS 脚本增加布局分辨率(LayoutResX / LayoutResY)的属性,LayoutRes 的值设置为使用这些标签制作字幕时使用的视频分辨率,那么新版本的字幕滤镜将始终以该布局分辨率为基准计算这些曾经受影响的特效标签的渲染效果,从而避免制作分辨率和视频分辨率不一致带来的显示差异。

注:

  1. 这部分标签包括:\frx\fry\fay 这种 3D 透视的标签,ScaledBorderAndShadow 未设置为 yes 时的 \bord\shad\be
  2. 视频的存储分辨率乘以像素宽高比 PAR(如 1:14:3 等)后可以得到最终 Aegisub 中帧的显示分辨率,因此存储分辨率不一定等于显示分辨率(例如以 1440 x 1080 采样或存储的、PAR 为 4:3 的视频,其显示分辨率可计算得到 1920 x 1080),但我们实际上只考虑 PAR 为 1:1 的情况(即视频的存储分辨率和显示分辨率都为 1920 x 1080 或都为 1280 x 720)。

显示 Bug 与 Aegisub 的接口调用 Bug

刚刚我们提到,libass 的设计目标是还原 VSFilter 的效果。
因此,libass 在处理上述显示 bug 时也选择了寻求还原 VSFilter 的效果,以取得和 VSFilter 的效果一致性,即使该效果是错误的。 然而,libass 社区却有人惊奇地发现 Aegisub 在使用 libass 时反而得到的是正确的渲染效果
即:libass 理应和 VSFilter 同时输出错误的效果,前者却输出了正确的效果。这不符合 libass 应与 VSFilter 效果一致的理念。

经过排查,发现问题(指 Aegisub 下 libass 意外输出正确效果)是 Aegisub 并没有如 libass 开发者所愿,调用 ass_set_storage_size 接口设置滤镜的视频存储分辨率造成的。
正是因为没有调用该接口设置滤镜的存储分辨率,此时 Aegisub 认为存储分辨率等于显示分辨率,进而因没有正确为 libass 传入存储分辨率导致不一致的产生,而恰巧该不一致得到的效果是正确的。

正常来说,滤镜的问题应该在滤镜内部得到修复,而不应该是不按滤镜的规范调用滤镜。
因此,没有按 libass 的规范正确调用接口是 Aegisub 的 bug,即使该 bug 阴差阳错地得到了正确的效果。
该接口调用 bug 在 wangqr fork 上于 2022 年 5 月得到了修复修复后,Aegisub 中使用 libass 时将得到与 VSFilter 相同的错误渲染效果,但现在可以正确设置 LayoutResX / LayoutResY 解决

Aegisub 滤镜选择

打开 Aegisub,从菜单栏依次进入 查看 - 选项 - 高级 - 视频,点击字幕来自的下拉栏,可能会看到以下几种滤镜可供选择,我们推荐使用其中的 CSRI/assrender_ob_textsub 滤镜:

  • CSRI/assrender_textsub:娱乐部基于 libass 字幕滤镜开发维护的 Assrender,该滤镜自 0.37.1 版本起添加了 CSRI 接口,支持用于 Aegisub;
  • CSRI/assrender_ob_textsub(推荐使用)娱乐部维护的 Assrender 的旧行为模式;
    • obold behavior 的简称,意味着其行为将模拟 Aegisub 的接口调用 bug 修复前的效果(即同一脚本在不同视频分辨率下渲染效果正确)
    • 通过使用该滤镜,我们不再关心分辨率不同时 PlayResLayoutRes 的对应关系,只需简单将二者设置为相等即可;
  • CSRI/vsfilter_textsub:基于 VSFilter 和 xy-VSFilter 的字幕滤镜;
  • CSRI/vsfiltermod_textsub:简称 mod 滤镜,是特效专用的字幕滤镜;
    • 支持一些额外的特效标签(不讨论),可以丰富特效效果(如支持插入图片),并简化一部分特效的代码实现(如遮罩的移动和变形);
    • 由于字幕组通常要发布外挂或内封版本成片,而观众的播放器一般不含此滤镜,因此若使用了该滤镜特有的特效标签,观众将无法正常观看特效;
    • 除非后期事先明确同意使用,否则一般禁止基于该滤镜制作任何特效;使用时可以在制作好一个不含特效的版本用于发布内封或外挂字幕的基础上,使用 mod 滤镜额外制作一版内嵌版本成片;
  • CSRI/pf-xy-vsfilter_textsub:最新版本的 xy-VSFilter 的字幕滤镜,由 pinterf 负责维护;
  • libass:libass 字幕滤镜。

如果你的列表中缺少以上几种中的一种或几种,可以从下列链接中获取。
我们通常使用的是 assrender,兼容性最好、渲染效果最安全。

为 Aegisub 安装字幕滤镜(展开查看)

以安装 Assrender 滤镜为例。

  • 打开上述链接,找到 Releases 并点击;
  • Releases 的列表中,找到第一个最新版本 assrender v0.xx.x(有绿色 Latest 字样标注);
  • Assets 中下载 assrender_win-x64_v0.xx.x.zip 并解压;
  • 解压后会得到一个 assrender.dll 文件;
  • 将上述文件放入你的 Aegisub 存放路径下的 csri 文件夹;
  • 重新启动 Aegisub,CSRI/assrender_textsubCSRI/assrender_ob_textsub 应该已出现在字幕滤镜选择的下拉列表中。

其他字幕滤镜的安装方法与 Assrender 大同小异,不再赘述。

不同版本 Aegisub 下选择不同滤镜时 LayoutResX / LayoutResY 应该设置的值(展开查看)

本部分中,制作字幕时挂载的视频的分辨率简称为视频分辨率(不讨论 PAR 不为 1:1 的视频),讨论的 libass 版本 >= 0.15.0
一般情况下使用与视频分辨率相同的值,例如使用 1920 x 1080 的视频,则二者均设置为 1920 x 1080
如果 PlayResX / PlayResY 与视频分辨率不同(例如视频为 1920 x 1080PlayRes1280 x 720),则需要先判断 Aegisub 是否已修复接口调用 bug
因为版本混乱,可以粗暴界定 2022 年 5 月之后的版本都修复了此 bug。

Aegisub 是否修复 bug使用的字幕滤镜LayoutRes应等于
未修复VSFilter视频分辨率
未修复libassPlayRes
已修复VSFilter视频分辨率
已修复libass视频分辨率
已修复assrender_obPlayRes

字幕脚本文件规范

可以使用 libass 的 Github 仓库 Wiki 中的《ASS File Format Guide》(英文,后文简称规范)作为 ASS 格式字幕脚本的规范。
规范中部分比较重要的内容已在《开始之前》篇章中介绍过,希望你能点击这里再回头温习一次。
作为前文的补充,本小节将总结一些实践中应特别注意的点。

奶茶屋限定要求

对该规范加强后,部分规范中的条款被我们禁用,同时我们也推荐开启部分规范中认为不必要的内容。
如您并非奶茶屋成员,该文本块中的内容仅供您参考。
格式:【类别 @ 出现小节】说明

  1. 【禁止 @ ScriptType】禁止在 [Script Info] 节加入注释行,由 Aegisub 或其他工具(如繁化姬、Mocha)造成的注释行也应全部删去;
  2. 【强调 @ Section: Script Info】目前已经完成了 SSA (v4.00) 到 ASS (v4.00+) 的过渡,但没有人使用 ASS2 (v4.00++),ScriptType 请务必使用 v4.00+,规范也应以 v4.00+ 为准;
  3. 【强调 @ LayoutResX and LayoutResY】应主动加入 LayoutResXLayoutResY 属性,并设置为正确的值
  4. 【冲突 @ WrapStyle】我们推荐使用 2(从不自动换行)作为全局设定的换行方式,且禁止在任何对话行(Dialogue:)中使用 \q 标签设定换行方式,还要求必须使用 \N 作为换行符;
  5. 【强调 @ v4+ (ASS) Style】颜色值和透明度值必须使用十六进制,所有十六进制字母必须使用大写,且必须以 &H 开头,如 &H445566&HC0&HC0445566
  6. 【建议 @ v4+ (ASS) Style】字体名称 Fontname 推荐使用字体的英文 family name 以确保平台兼容性(因为可能有观众或其他成员使用繁体中文、英文或日文系统),中文字体不推荐使用中文名称,日文字体禁止使用日文名称;
  7. 【强调 @ v4+ (ASS) Style】 Encoding 必须设置为 1
  8. 【补充】必须定义 Default 样式,不论是否使用;不能使用 *Default 或大小写不同的如 default;不使用时,可将该样式字体名设置为其他任意本字幕使用过的字体名,其余属性可任意设置;
  9. 【禁止 @ Section: Fonts】禁止使用该功能,禁止将字体和图片等二进制文件内嵌到 ASS 脚本中;
  10. 【强调 @ v4+ (ASS) Dialogue】每个对话行和注释行都必须设置一个样式名,禁止留空,且该样式名必须存在且大小写正确;
  11. 【禁止 @ v4+ (ASS) Dialogue】禁止在成品字幕中保留无意义的说话人(Name)和特效属性(Effect);合并特效时,除自动化生成的用于被渲染的对话行外,还应保留特效的 template 行,其余的代码(code)行都应删除;保留下的行应清空说话人(Name)和特效(Effect)属性;
  12. 【补充】如需保留持续时间为 0 的行,必须设置为注释行(Comment:);除文件内用于间隔分组的注释行外,无用的注释行尽量不要保留在脚本中;
  13. 【禁止 @ Override Tags】禁止在 \fs 标签中使用 + / - 设置相对字号,应直接使用绝对字号(如 \fs65);
  14. 【建议 @ Override Tags】建议不要直接使用 \k 标签及该标签的几个子形式,该标签仅限做特效时分割音节(Syllable)用于自动化;
  15. 【建议 @ Override Tags】建议不要使用 \a 这种传统定位标签,而应该使用 \an
  16. 【禁止 @ Effects】禁止直接使用事件内置的几种特效行,因为它们的可控性非常差;如需使用,应使用其他方法制作(如结合 \clip\move,必要时通过自动化制作);
  17. 【禁止 @ Appendix: Editors】禁止在最终成品字幕中保留 [Aegisub Project Garbage][Aegisub Extradata] 等无用额外信息。
  18. 【补充】禁止使用非标准 ass 标签,如仅 VSFilterMod 字幕滤镜支持的标签;
  • fsc 待商榷
  1. 【补充】禁止使用 \h 作为空格,若单个空格无法达到期望宽度或需要在行首使用空格时,可以使用正文使用的 CJK 字体的全角空格( )配合 \fscx 标签调整空格宽度,例如:
    长空格前的文字{\fscx550} {\fscx100}长空格后的文字
     句首有个全角空格
  2. 【补充】行末一般不需要保留空格,即使保留也无法保证不同滤镜渲染的渲染一致性;若需要在行末保留全角空格调整位置,应在最后追加一对花括号 {};通常只有在分层制作特效时可能会用到本条;
    行末有空格需保留 {}

注意:

  1. 此处只是对 ASS 脚本的规范加以补充和限定,具体到标签和制作的规范还会在对应篇章中介绍;
  2. 此处的对话行泛指脚本中 [Events] 节下以 Dialogue: 开头的行,这些行都会被字幕滤镜渲染,和注释行(Comment:)相对;注意与内容上的人物对话的行区分,需要渲染的人物对话行和屏幕字行都属于对话行;

规范的附录中还提供了一个 ASS 脚本样本,根据我们的实际情况加以修改后,提供一个新的参考样本:

[Script Info]









[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,FZLanTingHei-DB-GBK,65,&H007F67D0,&H00187DC1,&H00000000,&H00D4AA86,-1,0,0,0,100,100,0,0,1,0.4,0,7,10,10,10,1
Style: Screen,FZLanTingHei-DB-GBK,65,&H007F67D0,&H00187DC1,&H00000000,&H00D4AA86,-1,0,0,0,100,100,0,0,1,0.4,0,7,10,10,10,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,,Screen
Dialogue: 1,0:00:00.00,0:00:03.50,Screen,,0,0,0,,{\pos(52,72)\an7\c&HB3B3B3&\p1}m 2 34 l 8 60 112 37 107 24{\p0}
Dialogue: 0,0:00:00.00,0:00:03.50,Screen,,0,0,0,,{\shad0\bord2\fs36\org(126.31,107.61)\pos(128.85,116.69)\fax-0.068131\fscx207.70\fscy50.43\frz4.2185\frx25.9522\fry63.2018}Bakery
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,,Dialogue
Dialogue: 0,0:00:00.00,0:00:02.44,Default,,0,0,0,,Some text
Dialogue: 0,0:00:02.44,0:00:07.20,Default,,0,0,0,,Some text with{\fscx200} {\fscx100}widespace

作业

安装并选择正确的字幕滤镜。