Skip to content

# ASS 字幕格式规范

Jump to bottom
Zhenye Wei edited this page
May 2, 2025 · 16 revisions

## 0. 前言

Sub Station Alpha 本身是一个 Windows 平台下制作 SSA 格式字幕的软件，该软件已经不再开发了，而它所创造的 SSA 格式却流行开来，并演化出了更先进的 ASS 格式。

ASS specs 文档可能比较偏向于在使用 Sub Station Alpha 软件时 SSA 格式的规范，比较局限于其软件本身和 Windows 平台。随着 Aegisub 等跨平台的字幕编辑软件出现，以及在网页上渲染字幕的需求，我们应摒弃那些局限于软件和平台的规范，专注于字幕格式本身的规范。

目前 ASS 字幕制作人员所看到的效果绝大多数都是由 xy-VSFilter 和 libass 渲染的，于是这两个渲染器就成了事实上的标准。

本文档主要是对 ASS specs 的翻译，另外增加了一些规范中没有写但实际有应用的语法说明，以及我在写 ASS.js 的过程中对其的个人理解和注释（在下文中使用斜体表示）。

## 1. 总体信息

对 ASS 字幕的基本介绍请参阅维基百科。

1. SSA v4.00 的格式与 SSA 之前版本的格式不同。
   SSA v4.00 可以识别旧版本的脚本，但旧版本不能正确地加载 v4.00 脚本。
   脚本格式中的某些改变是为了允许 SSA v4.00 及以上的所有版本可以识别所有现存的和将来的 SSA 脚本。例如，新的「Format」字段允许 SSA 只读取它所能识别的并忽略未来可能加入的新的信息。

2. 脚本是纯文本文件。
   这意味着它们可以用任何文本编辑器手工地编辑，但必须要注意：SSA 假定脚本是遵循本文档中的规则，在解析时任何错误都可能会导致无法预料的结果。

3. 脚本被划分为 ini 文件风格的多个部分。
   然而，SSA 脚本并不是真正的 Windows .ini 文件，你不能像用 ini 文件一样用它。

4. 各个部分中的绝大多数行以一个「行描述符」加上冒号开头，以指明它包含了什么信息。

5. 每行中的信息字段以逗号分隔。
   于是在角色名和样式名中使用逗号是非法的（SSA 会阻止你这么做）。这也使得将 SSA 脚本作为一个 CSV 文件把块导入到表格变得简单，同时砍掉在其他字幕节目中要用到的列信息。

6. 事件部分（`[Events]`）各行排列不分先后。
   它们可以以完全相反的顺序排列，SSA 会将它们按正确的顺序播放。即，你不能假定脚本文件中的每条对话行是按时间顺序排列的。
   如果两条对话的开始时间相同，那么会根据在脚本中的排列顺序显示到屏幕上。

7. 不正确格式的行会被忽略。
   SSA 会丢弃任何它不能识别的行，同时在解析完后给出警告指明被忽略的行数。

8. 行不能被分割。
   脚本中每个条目在单行中包含了它的完整信息。

9. 如果在脚本中使用了一个未知的样式，将会使用默认的 `*Default` 样式。
   例如，如果从另一个脚本复制了一些行而没有复制对应的样式信息，那么就会使用默认样式。

10. 当一个风格中指定了系统没有安装的字体，会用 `Arial` 字体代替。

## 2. SSA 脚本的各个部分

### `[Script Info]`

这一部分包含了脚本的头部和总体信息。`[Script Info]` 必须是 v4 版本脚本的第一行。

### `[v4 Styles]`

这一部分包含了所有样式的定义。每一个被脚本使用的样式都应该在这里定义。ASS 使用 `[v4+ Styles]`。

### `[Events]`

这一部分包含了所有脚本的事件，有字幕、注释、图片、声音、影像和命令。基本上，所有在屏幕上看到的内容都在这一部分。

### `[Fonts]`

这一部分包含了脚本中内嵌字体的信息。

### `[Graphics]`

这一部分包含了脚本中内嵌图片的信息。

## 3. `[Script Info]` 详解

`;`
分号，后面可以跟任何内容。只在脚本中用作注释。加载脚本时不可见。分号必须是该行的第一个字符。旧版本中使用 `!:` 注释。

`Title`
标题，对脚本的描述。如果未指定，自动设置为 `<untitled>`。

`Original Script`
最初创建脚本的作者。如果未指定，自动设置为 `<unknown>`。

`Original Translation`
（可选）最初翻译对话的人。如果未指定，该项不显示。

`Original Editing`
（可选）最初脚本的编辑者，通常是对翻译润色和校对的人。如果未指定，该项不显示。

`Original Timing`
（可选）最初的时间轴人员。如果未指定，该项不显示。

`Synch Point`
（可选）指明什么时候脚本应该开始播放。如果未指定，该项不显示。

`Script Updated By`
（可选）对原脚本进行更新的其他字幕团体的人。如果未指定，该项不显示。

`Update Details`
（可选）其他字幕团体对原脚本更新的细节。如果未指定，该项不显示。

`ScriptType`
SSA 脚本格式的版本。例如 `V4.00`。如果当前使用的 SSA 程序版本旧于脚本的版本，将给出警告。

`Collisions`
为了防止字幕重叠，它决定了字幕如何移动。
如果设置为 `Normal`，SSA 将尝试使用「Margins」指定的位置来定位字幕。同时，字幕会垂直地移动来防止重叠。在 `Normal` 的防重叠模式下，新字幕会出现在已存在字幕的上方，但它会寻找最低的不产生重叠的位置，来填补其他字幕产生的「空隙」。
如果设置为 `Reverse`，已存在的字幕会上移给新字幕腾出空间。这意味这字幕总是可以自上向下地阅读，但也意味着已存在的字幕可能会在新字幕出现之前出现在屏幕的中间。它会占用大量的屏幕区域。
libass 和 VSFilter 都没有支持这个属性。

`PlayResY`
渲染字幕时的渲染范围的高度。如果使用 Directdraw 播放，SSA v4 会自动选择最接近的已启用的设置。

`PlayResX`
渲染字幕时的渲染范围的宽度。如果使用 Directdraw 播放，SSA v4 会自动选择最接近的已启用的设置。

`PlayDepth`
渲染字幕时的颜色深度。如果使用 Directdraw 播放，SSA v4 会自动选择最接近的已启用的设置。

`Timer`
脚本的计时器速度，为百分数。例如，`100.0000` 代表 100%，保留四位小数。
计时器速度是应用于 SSA 时钟的时间乘数，以提供斜坡时间来扩展或压缩脚本的总时间。速度大于 100% 会减少脚本总时间，意味着字幕会逐步地越来越早地出现；速度小于 100% 会增加脚本总时间，意味着字幕会逐步地越来越晚地出现（就像一个正的斜坡时间）。
扩展和压缩只发生在脚本播放时，这个值不会改变脚本事件部分的实际时间。
阅读 SSA 用户指南来了解为什么「计时器速度」比「斜坡时间」更好，尽管他们实现了相同的结果。
我也不知道这是什么鬼，也没找到什么 SSA 用户指南，从实际的效果来看，大概是把字幕的开始时间和结束时间乘一个百分数，比如设置为 `200.0000` 时就是两倍速度播放字幕。但是 xy-VSFilter 和 libass 都选择无视它。

`WrapStyle`
定义了默认的换行方式。

- `0`：智能换行，分割比较均匀，上面的行较长。
- `1`：从行尾的词换行，只有 `\N` 能强制换行。
- `2`：不换行，`\n` 和 `\N` 强制换行。
- `3`：和 `0` 一样智能换行，下面的行较长。

`ScaledBorderAndShadow`
指定边框宽度与阴影深度是否随着视频分辨率等比例缩放，默认为 `No`。
当值为 `No` 时，边框宽度与阴影深度完全按照指定的像素数显示；当值为 `Yes` 时，边框宽度与阴影深度随着实际视频的分辨率同等比例缩放。

`YCbCr Matrix`
在 ASS 中颜色是使用 BGR 定义的，而视频中的颜色通常都是 YCbCr 形式存储的。这两者之间有不同的转换方式，该字段就是用于定义如何转换，通常应该与视频本身的配置保持一致。
它由 `<range>.<color space>` 两部分组成，前者 range 的可选值为 `TV` 和 `PC`，后者 color space 的可选值为：

- `601`: BT.601
- `709`: BT.709
- `240M`: SMPTE 240M
- `FCC`

即完整值为 `TV.601` 这样。另外 YCbCr Matrix 还有一个特殊取值 `None`，表示未定义。

## 4. `[v4 Styles]` 详解

Styles 定义了字幕的外貌和定位。
ASS 格式应当使用 `[v4+ Styles]`。

`Format`
定义了 `Style` 行中每一个字段所代表的含义。`Format` 行必须出现在所有 `Style` 行之前，因为它决定了 SSA 如何来解析 `Style` 行。`Format` 行所列出的字段必须正确拼写。字段名如下：

    Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding

`Format` 行允许未来的脚本格式中添加新的字段，也允许旧版本的软件读出它所能识别的字段，即便字段的顺序发生了变化。

`Style`
样式的定义，用于格式化脚本显示的文本。
每一个被脚本使用的样式都应该被定义为 `Style` 行。
`Style` 行中的所有设定，除了阴影和边框的类型和深度，都可以被字幕文本中的控制代码所覆写。

- 字段 1：Name
  样式的名称，区分大小写，不能包含逗号。

- 字段 2：Fontname
  使用的字体名称，区分大小写。

- 字段 3：Fontsize
  字体的字号。

- 字段 4-7：长整型 BGR（蓝绿红）值，还包含了 alpha 通道信息。该值的十六进制字节顺序为 AABBGGRR。例如，`&H00FFFFFF`。

- 字段 4：PrimaryColour
  设置字幕正常显示的填充颜色。

- 字段 5：SecondaryColour
  在某条字幕为了防止重叠而自动移动时可能会使用该颜色而不是 PrimaryColour 以区分不同的字幕。 事实上并没有这种用法，它主要是用在卡拉 OK 效果中由 SecondaryColour 变为 PrimaryColour。

- 字段 6：TertiaryColour OutlineColor
  在某条字幕为了防止重叠而自动移动时可能会使用该颜色而不是 PrimaryColour 以区分不同的字幕。 在 ASS 中名称为 OutlineColor，设置字体边框的颜色。

- 字段 7：BackColour
  设置字体阴影的颜色。

- 字段 8：Bold
  它定义了文本是否为粗体。`-1` 是粗体，`0` 不是。它与斜体属性相互独立，即你可以把文本同时设置为粗体和斜体。

- 字段 9：Italic
  它定义了文本是否为斜体。`-1` 是斜体，`0` 不是。它与粗体属性相互独立，即你可以把文本同时设置为粗体和斜体。

- 字段 9.1：Underline
  它定义了文本是否有下划线。`-1` 有，`0` 没有。

- 字段 9.2：Strikeout
  它定义了文本是否有中划线（删除线）。`-1` 有，`0` 没有。

- 字段 9.3：ScaleX
  修改字体的宽度（为百分数）。

- 字段 9.4：ScaleY
  修改字体的高度（为百分数）。

- 字段 9.5：Spacing
  字符之间额外的间隙（为像素）。

- 字段 9.6：Angle
  旋转所基于的原点由 Alignment 定义（为角度）。

- 字段 10：BorderStyle
  边框的样式。`1` 为边框 + 阴影，`3` 为不透明背景。可以被 `\r` 重置。

- 字段 11：Outline
  如果 BorderStyle 为 `1`，它定义了文字边框的像素宽度。常见的值有 `0`、`1`、`2`、`3` 或 `4`。

- 字段 12：Shadow
  如果 BorderStyle 为 `1`，它定义了文字阴影的像素深度。常见的值有 `0`、`1`、`2`、`3` 或 `4`。阴影总是基于边框使用，当边框宽度没有给定时 SSA 会强制把边框设置为 1px。
  事实上阴影和边框可以独立使用，互不影响。

- 字段 13：Alignment
  它设置文本如何在屏幕上根据左右边距对齐和垂直位置。可能的值有 `1` = 居左，`2` = 居中，`3` = 居右。上述的值加 4 出现在屏幕顶部，上述的值加 8 出现在屏幕中间。例如，`5` = 屏幕顶部居左。但是在 ASS 中是按数字键盘对应的位置（1-3 为底部，4-6 为中部，7-9 为顶部）。
  即，在 SSA 中其行为与 `\a` 一致，在 ASS 中与 `\an` 一致。

- 字段 14：MarginL
  它定义了左边距（为像素）。它是到屏幕左边缘的距离。三个屏幕边距（MarginL，MarginR，MarginV）定义了字幕可以出现的区域。

- 字段 15：MarginR
  它定义了左边距（为像素）。它是到屏幕左边缘的距离。三个屏幕边距（MarginL，MarginR，MarginV）定义了字幕可以出现的区域。

- 字段 16：MarginV
  它定义了垂直边距（为像素）。
  对于底部字幕，它是字幕和屏幕底部的距离。
  对于顶部字幕，它是字幕和屏幕顶部的距离。
  对于中部字幕，该值被忽略，字幕会垂直居中。

- 字段 17：AlphaLevel
  它定义了文本的透明度。SSA 尚未使用。ASS 中没有该字段。

- 字段 18：Encoding
  它定义了字体的字符集或编码方式。在多语种的 Windows 安装中它可以获取多种语言中的字符。通常 `0` 为英文，`134` 为简体中文，`136` 为繁体中文。当文件是 Unicode 编码时，该字段在解析对话时会起作用。

## 5. `[Events]` 详解

`Format`
`Format` 行必须出现在所有事件行之前，因为它决定了 SSA 如何来解析下面的事件行。其所列出的字段必须正确拼写。字段名如下：

    Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text

最后的字段总是 `Text`，以便其可以包含逗号。
`Format` 行允许未来的脚本格式中添加新的字段，也允许旧版本的软件读出它所能识别的字段，即便字段的顺序发生了变化。

`Dialogue`
这是一个对话事件，即显示一些文本。
这里包含了字幕文本，时间轴信息，以及字幕的显示方式。
每条 `Dialogue` 行中出现的字段由 `Format` 行定义。

- 字段 1：Marked
  `Marked=0` 表示在 SSA 中该行不显示为已标识。
  `Marked=1` 表示在 SSA 中该行显示为已标识。
  在 SSA 文件中为 Marked。

- 字段 1：Layer（任何整数）
  有不同图层数值的字幕会在重叠检测中被忽略。
  大数值的图层会覆盖在小数值的图层上面。
  在 ASS 文件中为 Layer。

- 字段 2：Start
  事件的开始时间，格式为 `0:00:00:00`（`小时:分:秒:毫秒`）。它是字幕显示在屏幕上时脚本播放经过的时间。注意小时只有一位。

- 字段 3：End
  事件的结束时间，格式为 `0:00:00:00`（`小时:分:秒:毫秒`）。它是字幕在屏幕上消失时脚本播放经过的时间。注意小时只有一位。

- 字段 4：Style
  样式名。如果为 `Default`，那么你自己的 `*Default` 样式会取代它。
  然而，如果脚本作者要使用的 `Default` 样式已存储在脚本中却被 SSA 忽略了，如果你要使用它，你可以修改样式定义行里的名称，以便它出现在脚本的样式列表里。
  在 SSA 这个软件中，有一个自带的 `*Default` 样式，如果在 `[v4+ Styles]` 里没有找到对应的样式，那么就会使用自带的 `*Default` 样式。然而，如果设置为 `Default`（无星号），即便你在 `[v4+ Styles]` 中定义了自己的 `Default` 样式，SSA 这个软件也会使用自带的 `*Default` 样式。
  以上只是 SSA 软件本身的特性，在实际的应用中，都是在 `[v4+ Styles]` 定义好 `Default` 样式，如果之后使用了未定义的样式名，那么就使用 `Default` 样式。如果 `Default` 样式也没有定义，那样才使用渲染器自带的样式。

- 字段 5：Name
  角色名。说这条对白的角色名。只为了在编辑和设定时间轴时方便辨认。

- 字段 6：MarginL
  4 位的左边距覆写值（为像素）。`0000` 表示使用在 `Style` 行中定义的值。

- 字段 7：MarginR
  4 位的右边距覆写值（为像素）。`0000` 表示使用在 `Style` 行中定义的值。

- 字段 8：MarginV
  4 位的垂直边距覆写值（为像素）。`0000` 表示使用在 `Style` 行中定义的值。

- 字段 9：Effect
  过渡效果。可以为空值，或者为在 SSA v4.x 实现的三种过渡效果之一。
  效果名称区分大小写，必须正确拼写，不加引号。

  - `Karaoke`
    表示卡拉 OK 效果，依次高亮每个字。作为一个效果类型已经废弃不用。
  - `Scroll up;y1;y2;delay[;fadeawayheight]`
    表示文本或图片会在屏幕上向上滚动。
    - `Scroll up` 之后的参数字段用分号分隔。
    - `y1` 和 `y2` 值（为像素）定义了文本在屏幕上滚动的垂直区域。两个值位置可以互换。如果两个值都是 0，文本会在整个屏幕高度向上滚动。
    - `delay` 值可取值 1 到 100 以降低滚动的速度，0 表示无延迟按原速度滚动。当 `delay` 值大于 1 时，移动 1px 需要 `(1000 / delay)` 秒。
    - `fadeawayheigh` 值可选，可以使文本滚动到其范围的边缘时呈现淡出效果。
  - `Scroll down;y1;y2;delay[;fadeawayheight]`
    同上，为向下滚动。
  - `Banner;delay[;lefttoright;fadeawaywidth]`
    表示所有文本都忽略长度到一行里，从右向左滚动经过屏幕。
    - `delay` 值同上。
    - `lefttoright` 值可选，为 0 或 1。默认为 0，表示从右向左滚动。
    - `fadeawaywidth` 值同上。

- 字段 10：Text
  字幕文本。它是作为字幕实际出现在屏幕上的文本。任何第 9 个逗号之后的文本都被当作是字幕文本，所以它可以包含逗号。文本中可以包含表示换行的 `\n` 代码，也可以包含在大括号 `{}` 之间出现的样式覆写控制代码。

`Comment`
这是一个注释事件。它包含了和 Dialogue 事件相同的信息，但在脚本播放时会被忽略。

`Picture`
这是一个图片事件，意味着 SSA 会显示指定的 .bmp、.jpg、.gif、.ico 或 .wmf 图像。
它包含了和 `Dialogue` 事件相同的信息，但是字段 10 包含了要显示的图片的完整路径和文件名，而不是字幕文本。样式定义会被忽略。`Scroll up` 和 `Scroll down` 的过渡效果可以用在图片事件上。MarginL 和 MarginV 可以指定图片左下角的位置。MarginL 或 MarginV 如果是 `0000` 意味着图片水平居中或垂直居中。

`Sound`
这是一个声音事件，意味着 SSA 可以播放指定的 .wav 文件。
它包含了和 `Dialogue` 事件相同的信息，但是字段 10 包含了要播放的声音的完整路径和文件名，而不是字幕文本。样式定义会被忽略。
`End` 字段也会被忽略，该声音会一直播放直到它结束，或者直到另一个声音开始播放。
如果在 wav 声音播放的过程中任何 avi 影片开始播放，那么任何 avi 中的声音将听不见。同理，在 avi 影片播放的过程中 wav 声音开始播放，那么 wav 声音将听不见。

`Movie`
这是一个影片事件，意味着 SSA 可以播放指定的 .avi 文件。
它包含了和 `Dialogue` 事件相同的信息，但是字段 10 包含了要播放的影片的完整路径和文件名，而不是字幕文本。样式定义会被忽略。过渡效果会被忽略。
`End` 字段指定了何时影片图像会消失，但是如果 avi 文件播放时间更长，声音依然能被听到。
MarginL 和 MarginV 可以指定影片左上角的位置（和图片事件不同）。MarginL 或 MarginV 如果是 `0000` 意味着影片水平居中或垂直居中。
如果在 wav 声音播放的过程中任何 avi 影片开始播放，那么任何 avi 中的声音将听不见。同理，在 avi 影片播放的过程中 wav 声音开始播放，那么 wav 声音将听不见。

`Command`
这是一个命令事件，意味着 SSA 可以以后台任务执行指定的程序。
它包含了和 `Dialogue` 事件相同的信息，但是字段 10 包含了要执行的程序的完整路径和文件名，而不是字幕文本。样式定义会被忽略。边距会被忽略。过渡效果会被忽略。`End` 字段也会被忽略，程序会运行到它结束为止，或者直到人为地关闭。
有一些 SSA 内部命令可以在脚本中出现：「SSA:Pause」，「SSA:Wait for trigger」命令事件，同步锁相控制命令。这些命令都以「SSA:」开头。
「SSA:Pause」命令和在脚本播放时按 `P` 键有同样的功能。它作为第二同步点（Synch Point）在光盘换面后恢复播放字幕时很有用。
「SSA:Wait for audio trigger」命令和在脚本播放时按 `P` 键有同样的功能，但如果计算机的音频输入超过指定的「trigger」等级，暂停会被自动取消。它作为第二同步点（Synch Point）在光盘换面后恢复播放字幕时很有用。音频触发可以被按 `P` 键恢复播放来覆写。如果没有接收到足够大小的音频峰值，`P` 键也没有在 10 分钟内按下，音频触发会在 10 分钟后超时，然后播放无论如何都会恢复。

## 6. `[Fonts]` 详解

如果用户选择在脚本中嵌入非标准的字体，那么这一部分包含了文本编码的字体文件。只有 TrueType 字体可以嵌入 SSA 脚本。每个嵌入的字体文件以单行如下格式开头：

    fontname: <文件名>

`fontname` 必须小写（大写可能会被认为是文本编码的一部分）。
`<文件名>` 是 SSA 在保存字体文件时所用的文件名。其命名规则如下：原 TrueType 字体名，加一个下划线，如果是粗体加一个 `B`，如果是斜体加一个 `I`，加一个表示字体编码（字符集）的数字，加 `.ttf`。例如：`fontname: chaucer_B0.ttf`，`fontname: comic_0.ttf`。
在这一行之后是一些可打印的字符组成的行，代表组成该字体文件的二进制值。每一行有 80 个字符，除了最后一行可能会短一点。
从二进制转换到可打印字符使用 Uuencoding 方式，编码的细节参见「附录 B」。

## 7. `[Graphics]` 详解

如果用户选择在脚本中嵌入图片，那么这一部分包含了文本编码的图像文件。二进制图像文件以文本编码是低效的，但这可以保证 SSA 脚本可以被任何文本编辑器处理。每个嵌入的图像文件以单行如下格式开头：

    filename: <文件名>

`filename` 必须小写（大写可能会被认为是文本编码的一部分）。
`<文件名>` 是 SSA 在保存图像文件时所用的文件名。它与 `[Events]` 事件部分中提及的图片名称一致。
SSA 会把脚本中找到的任何文件保存到 SSA 的程序目录中的「Pictures」子目录中。例如：`C:\Program Files\Sub Station Alpha v4.00\Pictures`。SSA 会试图先从脚本指定的路径去加载文件，但当没有找到时会到「Pictures」这个子目录里去找。
在这一行之后是一些可打印的字符组成的行，代表组成该图像文件的二进制值，格式和内嵌字体文件相同。

## 8. 附录 A - 样式覆写代码

如果你想学习样式覆写代码这部分将对你很有用，你可以手动地输入它们而不用使用「覆写样式」对话框。
除了 `\h`、`\n` 和 `\N`，所有覆写代码都写在大括号 `{}` 里。
所有覆写代码都以反斜杠 `\` 开头。
一个大括号 `{}` 内可以放多个覆写代码。
所有覆写代码都作用于其后的所有文字。如果要让某个覆写代码只作用于选定的文字，你要在选定文字的后面加一个「取消」用的覆写代码，来取消前面那个覆写代码。
某些覆写代码会自动作用于整行文本，目前只有「Alignment」代码，之后可能会加入更多（例如，阴影和边框深度的覆写）。
`\pos` 和 `\move` 等也会作用于整行文本，下面的具体说明中会提到。
在下面的写法中，`<>` 包围的表示参数，用 `[]` 包围的表示可选。

- `\n`
  换行（回车）。如果启用了智能换行，`\n` 会被忽略。写法举例：`这是第一行\n这是第二行`。
  `\n` 只在 `WrapStyle: 2` 或 `\q2` 时会换行，其他模式下都相当于一个空格。

- `\N`
  换行（回车）。当智能换行启用时用来代替 `\n` 实现换行。
  任何模式下都会强制换行。在 xy-VSFilter 下，`\N` 在过渡效果 Banner 中也会换行；在 libass 下，`\N` 在 Banner 中不换行，相当于空格。

- `\h`
  空格。它保证显示字幕时不会在它的这个空格上分行（保证左右两个词在同一行）。
  原文档中没有该代码的描述，根据渲染器的实际效果，猜测其作用为将其左右两边的单词连到一起，让解析器将两边的单词看作一个单词，在普通的换行中不会在单词中间换行。

- `\b<0 或 1>`
  `\b1` 把文本变为粗体，`\b0` 强制文本不是粗体。
  当它的参数大于 1，它会作为字体的重量值（400 = 普通，700 = 粗体，注意：大多数字体的粗细可以量化 2 或 3 个等级）。

- `\i<0 或 1>`
  `\i1` 把文本变为斜体，`\i0` 强制文本不是斜体。

- `\u<0 或 1>`
  `\u1` 给文本变加下划线，`\u0` 强制取消文本下划线。

- `\s<0 或 1>`
  `\s1` 给文本变加中划线（删除线），`\s0` 强制取消文本中划线。

- `\bord<宽度>`、`\xbord<宽度>`、`\ybord<宽度>`
  边框宽度，为像素，可以是小数。有 x 或 y 时可以单独设置沿 X 轴或 Y 轴的边框宽度。写法举例：`\bord1`、`\xbord2`、`\ybord3`。

- `\shad<深度>`、`\xshad<深度>`、`\yshad<深度>`
  阴影深度，为像素，可以是小数。有 x 或 y 时可以单独设置沿 X 轴或 Y 轴的阴影深度。写法举例：`\shad1`、`\xshad2`、`\yshad3`。

- `\be<强度>`
  边缘模糊。按一般模糊的倍数来模糊文字边缘。当强度过大时会导致文字消失。写法举例：`\be1`。
  这里的 `<强度>` 必须是整数，表示模糊效果叠加的次数。当文字有边框时，模糊的对象是边框；当文字没有边框时，模糊的对象是文字本身。

- `\blur<强度>`
  与 `\be` 相似，但它用的是更加高级的高斯模糊。写法举例：`\blur2.33`。
  这里的 `<强度>` 可以是小数。当文字有边框时，模糊的对象是边框；当文字没有边框时，模糊的对象是文字本身。

- `\fn<字体名>`
  指定一个系统中已安装的字体。区分大小写。如果指定的字体没有安装，那么会使用 `Arial` 字体。写法举例：`\fn微软雅黑`。

- `\fs<字体尺寸>`
  `<字体尺寸>` 是一个数字，指定了字体的点的尺寸。
  注意，这里的字体尺寸并不是字号的大小，`\fs20` 并不是字体大小（font-size）为 20px，而是指其行高（line-height）为 20px，主要归咎于 VSFilter 使用的 Windows GDI 的字体接口。

- `\fs+<数值>`、`\fs-<数值>`
  将当前文本的字体尺寸乘一定的倍数。例如，`\fs+2` 表示将当前文本的字体尺寸乘 1.2，`\fs-3` 表示将当前文本的字体尺寸乘 0.7。计算方式为`(1 ± <数值> / 10) * 当前字体尺寸`，当计算的结果小于等于 0 时结果不生效，即依然为原来的字体尺寸。

- `\fscx<百分数>`、`\fscy<百分数>`
  缩放文字大小。`\fscx<百分数>` 为水平缩放，`\fscy<百分数>` 为垂直缩放。写法举例：`\fscx233.33`、`\fscy50`。
  可适用于矢量图形。

- `\fsp<像素值>`
  它改变字符之间的距离，默认为 `0`。写法举例：`\fsp3`。

- `\fr<度数>`、`\frx<度数>`、`\fry<度数>`、`\frz<度数>`
  表示沿 X 或 Y 或 Z 轴旋转一定的度数。`\fr<度数>` 表示沿 Z 轴旋转。写法举例：`\fr30`、`\frx-30`、`\fry-233.33`、`\frz480`。
  其旋转的原点由 `\org` 决定，如果没有指定 `\org`，那么按「默认定位点」来旋转。

- `\fax<因数>`、`\fay<因数>`
  分别沿 X 轴和 Y 轴对文字行进行倾斜调整。 如 `\fax-0.5` 等同于斜体。一般情况下因数的绝对值不要超过 2。

- `\fe<字符集>`
  指定文字的字符集（字体编码）。通常 `0` 为英文，`1` 为系统默认，`134` 为简体中文，`136` 为繁体中文。
  一般字幕文件保存为 Unicode 方式编码如 UTF-8 时，可以忽略该设置。

- `\[<颜色序号>]c[&][H]<BBGGRR>[&]`
  `<BBGGRR>` 是一个十六进制的 RGB 值，但颜色顺序相反，前导的 0 可以省略。
  `<颜色序号>` 可选值为 1、2、3 和 4，分别对应单独设置 `PrimaryColour`、`SecondaryColour`、`OutlineColor` 和 `BackColour`，`<颜色序号>` 未写时相当于设置 `PrimaryColour`。写法举例：`\c&HFF0000&`、`\1c&HFF&`、`\2c&HFF00&`、`\3c&HFFFFFF`、`\4cFFFFFF`。
  其中的 `&` 和 `H` 按规范应该是要有的，但是如果没有也能正常解析。

- `\[<颜色序号>]c`
  当 `c` 后面不跟其他字符时，会设置为当前使用的 `Style` 中定义的对应的值。

- `\<颜色序号>a[&][H]<AA>[&]`
  `<AA>` 是一个十六进制的透明度数值，`00` 为全见，`FF` 为全透明。
  `<颜色序号>` 含义同上，但这里不能省略。写法举例：`\1a&H80&`、`\2a&H80`、`\3a80`、`\4a&H80&`。
  其中的 `&` 和 `H` 按规范应该是要有的，但是如果没有也能正常解析。

- `\alpha[&][H]<AA>[&]`
  `<AA>` 是一个十六进制的透明度数值，`00` 为全见，`FF` 为全透明。 它默认相当于 `\1a&H<AA>&`。 写法举例：`\alpha80`。
  猜测是原文的笔误，实际效果为一次性设置 `PrimaryColour`、`SecondaryColour`、`OutlineColor` 和 `BackColour`。

- `\a<位置>`
  `<位置>` 是一个数字，决定了字幕显示在屏幕上哪个位置。`1`、`2`、`3` 分别是底部的居左，居中、居右；`5`、`6`、`7` 分别是顶部的居左，居中、居右；`9`、`10`、`11` 分别是中部的居左，居中、居右。如果是 `0` 或者没有就设置为默认位置。如果出现了多个 `\a` 或 `\an` 则以第一个出现的为准。

- `\an<位置>`
  与小键盘布局相同。如果出现了多个 `\a` 或 `\an` 则以第一个出现的为准。

- `\k<时长>`
  `<时长>` 是一个以百分之一秒为单位的时间，表示以卡拉 OK 效果高亮它所控制的那段文本的延时。
  控制范围为 `\k<时长>` 之后，下一个 `\k<时长>` 或结尾之前，例如，`{\k100}这里受 \k100 控制{\k200}这里受 \k200 控制`。
  高亮之前文字使用 `SecondaryColour`，高亮后使用 `PrimaryColour`。
  某一代码的 `<时长>` 是相对于它之前的代码而言的，如上述例子中，字幕显示后的第 0 秒到第 1 秒是前面部分的效果，第 1 秒到第 3 秒是后面部分的效果。
  其高亮效果是把控制范围内的文字一次性全部变色。例如，`{\k10}你{\k10}要{\k10}这{\k10}样{\k10}才{\k10}能{\k10}有{\k10}正{\k10}常{\k10}的{\k10}卡{\k10}拉{\k10} OK {\k10}效{\k10}果`。

- `\kf<时长>`、`\K<时长>`
  其他部分与 `\k<时长>` 相同。其高亮效果是把控制范围内的文字从左到右流畅变色。例如，`{\K300}你这样就可以有正常的卡拉 OK 效果`。

- `\ko<时长>`
  其他部分与 `\k<时长>` 相同。高亮之前边框被去除，高亮之后再显示边框。

- `\kt<时长>`
  它重新定义之后的 `\k`、`\kf`、`\K`、`\ko` 所相对的开始时间。例如，`{\k100}壹{\kt300\k100}貳{\kt100\k100}叁`，第 0 秒到第 1 秒高亮 `壹`，第 1 秒到第 2 秒高亮 `叁`，第 3 秒到第 4 秒高亮 `貳`。

- `\q<方式>`
  `<方式>` 是一个数字，与 `WrapStyle` 相同。

  - `0`：智能换行，分割比较均匀，上面的行较长。
  - `1`：从行尾的词换行，只有 `\N` 能强制换行。
  - `2`：不换行，`\n` 和 `\N` 强制换行。
  - `3`：和 `0` 一样智能换行，下面的行较长。

- `\r[<样式名>]`
  `<样式名>` 是在 `[v4 Styles+]` 中定义的样式名，它会把这行中所有它之后的文本设置为样式名对应的样式。如果没有写 `<样式名>` 或者 `<样式名>` 没有被定义，将会设置为默认样式。
  例如，假设已定义了把字体设为蓝色的 `Blue` 样式，`{\1c&HFF&}这里是红色{\rBlue}这里是蓝色{\1c&HFF00&}这里是绿色`。

- `\t([<t1>,<t2>,][<加速度>,]<样式覆写代码>)`
  它可以将某一样式从某种效果逐渐地动态地转化到另一种效果。

  - `<t1>` 和 `<t2>` 表示相对于字幕显示时间的开始动画与结束动画的毫秒数，可选，如果没有写或者两者都是 0，则默认是在字幕的整段时间内进行动画效果。

    - 在 `<t1>` 之前，其样式为该代码之前设置的样式。
    - 在 `<t1>` 和 `<t2>` 之间，其样式由之前的样式转变为 `<样式覆写代码>` 的样式。
    - 在 `<t2>` 之后，其样式保持为 `<样式覆写代码>` 的样式。

  - `<加速度>` 可以修改变换效果的线性程度，由此式计算：`pow((t - t1) / (t2 - t1), accel)`，其中 `t` 为当前字幕已存在的时间，`accel` 为 `<加速度>`。从结果来看，`<加速度>` 等于 1 时为线性变换，大于 1 时先慢后快，大于 0 小于 1 时先快后慢。可选，默认为 1。

  - 只有以下 `<样式覆写代码>` 可以进行转化：

    - `\bord<宽度>`、`\xbord<宽度>`、`\ybord<宽度>`
    - `\shad<深度>`、`\xshad<深度>`、`\yshad<深度>`
    - `\be<强度>`
    - `\blur<强度>`
    - `\fs<字体尺寸>`
    - `\fs+<数值>`、`\fs-<数值>`
    - `\fscx<百分数>`、`\fscy<百分数>`
    - `\fsp<像素值>`
    - `\fr<度数>`、`\frx<度数>`、`\fry<度数>`、`\frz<度数>`
    - `\fax<因数>`、`\fay<因数>`
    - `\[<颜色序号>]c[&][H]<BBGGRR>[&]`
    - `\<颜色序号>a[&][H]<AA>[&]`
    - `\alpha<AA>`
    - `\[i]clip(<x1>,<y1>,<x2>,<y2>)`

    当一行中含有多个 `<样式覆写代码>` 相同但 `<t1>` 和 `<t2>` 不同的 `\t` 时，结果比较迷。
    当一行中含有 `\t` 时会忽略字幕重叠冲突的检测。

- `\move(<x1>,<y1>,<x2>,<y2>[,<t1>,<t2>])`
  提供字幕的移动效果。`<x1>,<y1>` 是开始点坐标，`<x2>,<y2>` 是结束点坐标。
  `<t1>` 和 `<t2>` 是相对于字幕显示时间的开始运动与结束运动的毫秒时间。

  - 在 `<t1>` 之前，字幕定位在 `<x1>,<y1>`。
  - 在 `<t1>` 与 `<t2>` 之间，字幕从 `<x1>,<y1>` 均速移动到 `<x2>,<y2>`。
  - 在 `<t2>` 之后，字幕定位在 `<x2>,<y2>`。

  当 `<t1>` 和 `<t2>` 没写或者都是 0 时，则在字幕的整段时间内均速移动。
  当一行中有多个 `\pos` 和 `\move` 时，以第一个为准。
  当 `\move` 和 Effect 效果同时存在时，结果比较迷。
  当一行中含有 `\move` 时会忽略字幕重叠冲突的检测。

- `\pos(<x>,<y>)`
  将字幕定位在坐标点 `<x>,<y>`。屏幕的左上角为 `0,0`。字幕的「定位点」由 `\a<位置>`、`\an<位置>` 和 `Alignment` 决定。例如：

  - `\an1` 的定位点在字幕的左下角。
  - `\an2` 的定位点在字幕底边的正中间。
  - `\an3` 的定位点在字幕的右下角。
  - `\an4` 的定位点在字幕左边线的正中间。
  - `\an5` 的定位点在字幕垂直水平的正中间。
  - `\an6` 的定位点在字幕右边线的正中间。
  - `\an7` 的定位点在字幕的左上角。
  - `\an8` 的定位点在字幕顶边的正中间。
  - `\an9` 的定位点在字幕的右上角。

  当一行中有多个 `\pos` 和 `\move` 时，以第一个为准。事实上 `\pos(<x>,<y>)` 相当于 `\move(<x>,<y>,<x>,<y>,0,0)`。
  当一行中含有 `\pos` 时会忽略字幕重叠冲突的检测。

- `\org(<x>,<y>)`
  设置字幕的原点为 `<x>,<y>`。字幕的原点会影响其旋转效果，字幕是基于原点来旋转的。当未设置时默认为字幕的定位点。
  当一行中有多个 `\org` 时，以第一个为准。
  原点就是定位点，定位点就是原点。

- `\fad(<t1>,<t2>)`
  提供简单的淡入淡出效果。`t1` 为淡入时间长度，`t2` 为淡出时间长度。单位为毫秒。
  当一行中有多个 `\fad` 或 `\fade` 时，以第一个为准。

  - 在 0 与 `<t1>` 之间，透明度从 0 变化到 1。
  - 在 `<t1>` 与 `总时长 - <t2>` 之间，透明度为 1。（当 `<t1>` 大于 `总时长 - <t2>` 时，该时间段内透明度以 0 与 `<t1>` 之间的透明度为准）
  - 在 `总时长 - <t2>` 与 `总时长` 之间，透明度由 1 变化到 0。

- `\fade(<a1>,<a2>,<a3>,<t1>,<t2>,<t3>,<t4>)`
  提供复杂的淡入淡出效果。单位为毫秒。

  - 在 `<t1>` 之前，透明度为 `<a1>`。
  - 在 `<t1>` 与 `<t2>` 之间，透明度由 `<a1>` 变化到 `<a2>`。
  - 在 `<t2>` 与 `<t3>` 之间，透明度为 `<a2>`。
  - 在 `<t3>` 与 `<t4>` 之间，透明度由 `<a2>` 变化到 `<a3>`。
  - 在 `<t4>` 之后，透明度为 `<a3>`。

  当 `\fade` 只有两个参数时，其效果与 `\fad` 一致。
  当一行中有多个 `\fad` 或 `\fade` 时，以第一个为准。

- `\[i]clip(<x1>,<y1>,<x2>,<y2>)`
  定义一个矩形，只有在该矩形范围内的内容可见或不可见。`<x1>,<y1>` 为矩形的左上角，`<x2>,<y2>` 为矩形的右下角。`\clip` 是矩形范围内可见，`\iclip` 是矩形范围内不可见。
  当一行中有多个 `\[i]clip` 时，以__最后一个__为准。

- `\[i]clip([<等级>,]<绘图命令>)`
  定义一个绘画图形，只有在该绘画图形范围内的内容可见或不可见。`<等级>` 和 `<绘图命令>` 的含义与 `\p` 相同。

- `\p<等级>`
  进入绘图模式且同时指定坐标的缩小等级。缩小等级由此式计算：`pow(2, <等级> - 1)`。例如，`\p4`，`pow(2, 4 - 1) = 8`，即将原坐标缩小至 1/8。
  当 `<等级>` 为 0 时，表示退出绘图模式，之后的文本按普通的解析。
  绘图命令是写在 `{\p<等级>}` 大括号外面的部分。例如，`{\p1}m 0 0 l 0 100 l 100 100 l 100 0 l 0 0{\p0}`。而 `\[i]clip` 代码中的绘图命令是写在 `clip` 之后的括号里的。例如，`{\clip(4, m 0 0 l 0 100 l 100 100 l 100 0 l 0 0)}绘图命令在括号里`。

  - 以下列举了所有绘图命令：

    - `m <x> <y>`
      将当前绘制点移至 `<x>,<y>`，同时闭合已有的图形，即开始绘制新图形。所有绘图都应由该命令开头。
    - `n <x> <y>`
      将当前绘制点移至 `<x>,<y>`，同时不闭合已有的图形。
    - `l <x> <y>`
      在当前绘制点和 `<x>,<y>` 之间画一条直线，并把当前绘制点设置为 `<x>,<y>`，即从这个点继续之后的绘图。
    - `b <x1> <y1> <x2> <y2> <x3> <y3>`
      在当前绘制点和 `<x3>,<y3>` 之间画一条三次贝塞尔曲线，并把当前绘制点设置为 `<x3>,<y3>`，即从这个点继续之后的绘图。其中 `<x1>,<y1>` 和 `<x2>,<y2>` 为该贝塞尔曲线的控制点。
    - `s <x1> <y1> <x2> <y2> <x3> <y3> ... <xN> <yN>`
      在当前绘制点和 `<xN>,<yN>` 之间画一条三次均匀 B样条，并把当前绘制点设置为 `<xN>,<yN>`，即从这个点继续之后的绘图。至少包含三个坐标。
    - `p <x> <y>`
      延长 B样条到 `<x>,<y>`。例如，`m 0 0 s 100 0 100 100 0 100 p 0 0` 相当于 `m 0 0 s 100 0 100 100 0 100 0 0`。
    - `c`
      闭合的 B样条曲线。例如，`m 0 0 s 100 0 100 100 0 100 c`，这里的 `c` 就相当于 `p 0 0 100 0 100 100`。

  - 以下是绘图命令的注意事项：

    - 除了在 `\[i]clip` 中，绘图命令必须被包含在 `{\p<等级>}` 和 `{\p0}` 之间。
    - 所有绘图都应由 `m <x> <y>` 命令开头。
    - 所有图形最后必须闭合。
    - 所有没闭合的图形会被自动地在起点和终点之间添加直线来闭合。
    - 如果一个对话行中的多个图形有重叠，重叠部分会进行异或运算。
    - 如果多个相同的命令连在一起，可以把之后的命令符省略，只保留坐标。例如，`l 100 100 l 200 200` 可以写成 `l 100 100 200 200`。但是 `s` 命令不能省略，省略的话会导致绘制出不同的图形。
    - 图形的坐标系是相对于当前基线位置（`\pbo`）和对齐（Alignment）模式。

- `\pbo<y>`
  设置图形的基线偏移值。默认情况下所有图形都是基于当前的基线，该命令可以将图形相对于基线上移或下移。`<y>` 小于 0 时上移，大于 0 时下移。

## 9. 附录 B - 内嵌字体/图片编码

SSA 的字体文件和图片文件的嵌入是 UUEncoding 编码形式。

它从二进制文件中，一次取 3 字节，然后把这 3 字节的 24 位转换为 4 个 6 位的数字。然后把这 4 个数字都加上 33，再把这 4 个数字所对应的 ASCII 字符写入脚本文件。

加上 33 的偏移意味着在编码后的输出中不会出现小写字符，这也是 `fontname` 行要小写的原因。

每一行有 80 个字符，除了最后一行可能会短一点。

如果被编码的文件的长度不是 3 的倍数，那么，如果文件长度是奇数，最后一个字节将乘十六进制的 100，然后得到的数字最多 12 位将按上述过程转换为 2 个字符；如果文件长度是偶数，最后一个字节将乘十六进制的 10000，然后得到的数字最多 18 位将按上述过程转换为 3 个字符。

内嵌文件中没有终止符。如果后面有新的 `[章节名]`，或者有另一个内嵌文件行，或者已经到脚本的最后了，那么该内嵌文件就被认为已经完成了。

### Clone this wiki locally

You can’t perform that action at this time.