跳到主要内容
SubtitleMatrix

SSA 转 JSON

格式转换SubStation Alpha(SSA)
或者粘贴字幕文本

这次转换会改变什么

有 1 项会被丢弃或需要你决定

  • 格式专有内容

    源格式保留在字幕条之外的内容(非字幕块、文件头文字、单条字幕的设置、被注释掉的事件)——目标格式没有地方存放它们

这份清单来自这两种格式的能力矩阵,而不是你加载的这份具体文件。如果具体文件用到了格式允许、但矩阵没有建模的特性,可能会丢得更多。

这一页把 SSA 脚本转成 JSON。产物是一个对象:version 为 1,带 title、styles 与 cues;每条字幕有 start、end(整数毫秒)、lines 数组和 style 名。转换在浏览器里完成,不上传。

这个方向丢得比你想的少。标题会保留,整张 SSA 样式表也会保留——每一列都在,包括本站没有专门建模的列,另外还有解析出来的 fontFamily、fontSize、primaryColor、bold、italic。真正没有落点的是 [Script Info] 的其余键(PlayResX、WrapStyle、Collisions 之类)、非 Dialogue: 的事件行(Comment:、Picture:、Sound:),以及 [Fonts] 和 [Graphics] 里内嵌的字体与图形。

时间轴精确。SSA 的 0:00:04.13 在 JSON 里是 4130 毫秒,不四舍五入也不平移;2.9 秒的字幕仍然是 2.9 秒。一条两行的字幕是 lines 数组里的两个元素,仍然属于同一条。

产物按起始时间升序,UTF-8、Unix 换行、无 BOM。整季可以一次拖入,串行转换后打包下载。

示例

一份典型的 SSA 文件转成 JSON

输入

[Script Info]
Title: Example SSA
ScriptType: v4.00
Collisions: Normal

[V4 Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding
Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,1,2,2,2,10,10,10,0,1

[Events]
Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: Marked=0,0:00:01.00,0:00:04.00,Default,,0,0,0,,Hello there.
Dialogue: Marked=0,0:00:05.00,0:00:08.00,Default,,0,0,0,,{\i1}Italic{\i0} line.
Dialogue: Marked=0,0:00:09.00,0:00:12.00,Default,,0,0,0,,Two\Nlines

输出

{
  "version": 1,
  "title": "Example SSA",
  "styles": {
    "Default": {
      "name": "Default",
      "Name": "Default",
      "Fontname": "Arial",
      "Fontsize": "20",
      "PrimaryColour": "&H00FFFFFF",
      "SecondaryColour": "&H000000FF",
      "TertiaryColour": "&H00000000",
      "BackColour": "&H00000000",
      "Bold": "0",
      "Italic": "0",
      "BorderStyle": "1",
      "Outline": "2",
      "Shadow": "2",
      "Alignment": "2",
      "MarginL": "10",
      "MarginR": "10",
      "MarginV": "10",
      "AlphaLevel": "0",
      "Encoding": "1",
      "fontFamily": "Arial",
      "fontSize": 20,
      "primaryColor": "#ffffff",
      "bold": false,
      "italic": false
    }
  },
  "cues": [
    {
      "start": 1000,
      "end": 4000,
      "lines": [
        "Hello there."
      ],
      "style": "Default"
    },
    {
      "start": 5000,
      "end": 8000,
      "lines": [
        {
          "text": "Italic line.",
          "tags": [
            {
              "kind": "italic",
              "start": 0,
              "end": 6
            }
          ]
        }
      ],
      "style": "Default"
    },
    {
      "start": 9000,
      "end": 12000,
      "lines": [
        "Two",
        "lines"
      ],
      "style": "Default"
    }
  ]
}

这份产物丢掉了格式私有内容与脚本里不建模的部分;时间轴、正文与样式表都在。

同一转换遇到一份脏文件

输入

[Script Info]
Title: Dirty SSA
ScriptType: v4.00

[V4 Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding
Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,1,2,2,2,10,10,10,0,1

[Events]
Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Comment: Marked=0,0:00:00.00,0:00:01.00,Default,,0,0,0,,not a subtitle
Dialogue: Marked=0,0:00:01.00,0:00:04.00,Default,,0,0,0,,{\b1}Bold{\b0} and {\u1}underlined{\u0}.
Dialogue: Marked=0,0:00:05.00,0:00:08.00,Default,,0,0,0,,A soft\nbreak and a {\p1}mystery{\p0} code.

输出

{
  "version": 1,
  "title": "Dirty SSA",
  "styles": {
    "Default": {
      "name": "Default",
      "Name": "Default",
      "Fontname": "Arial",
      "Fontsize": "20",
      "PrimaryColour": "&H00FFFFFF",
      "SecondaryColour": "&H000000FF",
      "TertiaryColour": "&H00000000",
      "BackColour": "&H00000000",
      "Bold": "0",
      "Italic": "0",
      "BorderStyle": "1",
      "Outline": "2",
      "Shadow": "2",
      "Alignment": "2",
      "MarginL": "10",
      "MarginR": "10",
      "MarginV": "10",
      "AlphaLevel": "0",
      "Encoding": "1",
      "fontFamily": "Arial",
      "fontSize": 20,
      "primaryColor": "#ffffff",
      "bold": false,
      "italic": false
    }
  },
  "cues": [
    {
      "start": 1000,
      "end": 4000,
      "lines": [
        {
          "text": "Bold and underlined.",
          "tags": [
            {
              "kind": "bold",
              "start": 0,
              "end": 4
            },
            {
              "kind": "underline",
              "start": 9,
              "end": 19
            }
          ]
        }
      ],
      "style": "Default"
    },
    {
      "start": 5000,
      "end": 8000,
      "lines": [
        "A soft",
        "break and a {\\p1}mystery{\\p0} code."
      ],
      "style": "Default"
    }
  ]
}

真实文件里常见的损坏:混合换行、散落的空白、留空的字段。可以对照上面那份干净样例,看看解析器能容忍到什么程度。

常见问题

SSA 转 JSON 后,[V4 Styles] 样式表还在吗?

在,而且是整张留下:每个样式的每一列都写进 styles,包括 Fontname、Fontsize、TertiaryColour、AlphaLevel 这些;另外还有解析出来的 fontFamily、fontSize、primaryColor、bold、italic。

SSA 转 JSON 后,标题和 [Script Info] 的其他设置呢?

标题保留成顶层 title。其余全局键(PlayResX、WrapStyle、Collisions 等)没有对应字段,会被丢掉并计入有损清单。

SSA 转 JSON 的时间是精确的吗?

是。SSA 的 0:00:04.13 写成 4130 毫秒,单位是整数毫秒,不四舍五入也不平移;一条 2.9 秒的字幕仍然是 2.9 秒。

SSA 转 JSON 后,一条两行字幕怎么放?

放在同一个 cue 的 lines 数组里,两个元素。两行仍然属于同一条字幕;带格式的片段会在该元素下带 tags,例如斜体的起止位置。

SSA 转 JSON 后,Comment: 行和内嵌字体会怎样?

都会丢。只有 Dialogue: 行变成 cue;Comment:、Picture:、Sound: 这些非对话事件,以及 [Fonts] 与 [Graphics] 里内嵌的内容,JSON 没有地方放,会被报告为格式私有内容的损失。

SSA 转 JSON 之后,再转回 SSA 会丢什么?

会丢精度:JSON 到毫秒,SSA 只到百分秒,回程会四舍五入到最近的 10 毫秒。那份清单和去程这一份不同,因为两个方向保留的东西不一样。

相关工具