JSON 字幕格式
这种格式能表达什么
- 文本样式
- 字体、颜色、描边、阴影
- 屏幕定位
- 是
- 卡拉 OK 计时
- 是
- 字幕条内换行
- 是
- 时间轴
- 每条字幕都有开始与结束时间
- 时间精度
- 1 毫秒
- 时间以帧号存储
- 否
- 从右到左的文字
- 是
示例
一份典型的 JSON 文件,以及从它读出了什么
文件
{
"version": 1,
"title": "Fixture: typical",
"fps": 25,
"styles": {
"Default": {
"name": "Default",
"fontFamily": "Arial",
"fontSize": 20,
"primaryColor": "#FFFFFF",
"bold": false,
"italic": false
}
},
"generator": "subtitlematrix fixtures",
"cues": [
{
"id": "1",
"start": 0,
"end": 2000,
"lines": [
"Hello world.",
"Second line."
],
"style": "Default",
"position": {
"x": 100,
"y": 200,
"align": "center"
}
},
{
"id": "2",
"start": 2500,
"end": 4000,
"lines": [
"Plain line.",
{
"text": "Styled line.",
"tags": [
{
"kind": "italic",
"start": 0,
"end": 6
}
]
}
]
},
{
"id": "3",
"start": 4500,
"end": 6000,
"lines": [
"Roger: I am here."
],
"speaker": "Roger"
}
]
}
从中读出了什么
3 cues, 5 lines of text
0 ms → 2000 ms
Hello world.
Second line.
[Default; position 100,200 (center)]
2500 ms → 4000 ms
Plain line.
Styled line. [italic ×1]
4500 ms → 6000 ms
Roger: I am here.
[speaker Roger]
Outside the cues:
styles Default
other keys version, title, fps, generator — carried through untouched右栏不是转换产物,而是本站从左边这份文件里读出的内容,也是它每一种转换的起点。
一份结构松散的 JSON 文件,以及仍能读出什么
文件
{
"cues": [
{ "start": "0:00:01,5", "end": "0:00:03,0", "text": "Unpadded timecode." },
{ "start": 4000.5, "end": 5000, "lines": ["Fractional start.", { "text": "Second.", "tags": [] }] },
{ "start": 9000, "end": 8000, "lines": ["End before start."] },
{ "start": "nope", "end": 12000, "lines": ["No readable start."] },
{ "start": 13000, "lines": ["No end at all."] }
],
"generator": "subtitlematrix boundary",
"styles": {},
"title": "Fixture: boundary"
}
从中读出了什么
3 cues, 4 lines of text
1500 ms → 3000 ms
Unpadded timecode.
4001 ms → 5000 ms
Fractional start.
Second.
9000 ms → 9001 ms
End before start.
Outside the cues:
other keys generator, title — carried through untouched
Reported while reading — repaired or skipped, never silently:
2 × entries with no readable start and end time (they are not cues, so they were skipped)
1 × cue times that were not whole milliseconds (they were rounded to the nearest millisecond)
1 × cues whose end time was not after their start time (they were given a 1ms duration)真实文件会带 BOM、Windows 换行、小数毫秒、结束早于开始的 cue,甚至读不出起止的条目。这些都不会抛错:能修的在读入时修好,读不出的跳过并计数。
把 SubtitleMatrix JSON 转成其他格式
每一个都完全在你的浏览器里运行。标签标明了那个方向要付出什么代价,打开之前就能看到。
转换为此格式
- SubRip (SRT) → SubtitleMatrix JSON
- WebVTT (VTT) → SubtitleMatrix JSON
- Advanced SubStation Alpha (ASS) → SubtitleMatrix JSON
- SubStation Alpha (SSA) → SubtitleMatrix JSON
- YouTube SBV → SubtitleMatrix JSON
- SAMI (SMI) → SubtitleMatrix JSON
- LRC Lyrics → SubtitleMatrix JSON
- MicroDVD → SubtitleMatrix JSON
- TTML (Timed Text) → SubtitleMatrix JSON
- Plain Text (TXT) → SubtitleMatrix JSON
- CSV Spreadsheet → SubtitleMatrix JSON
JSON 是本站的完整字幕表示,也是所有格式转换的中间基准:一份文档包含版本号、可选的样式表、可选的帧率与标题,以及一个 cues 数组。每条 cue 的 start 与 end 是整数毫秒,正文按行拆开,行内斜体、粗体、颜色与卡拉OK用区间标注,屏幕坐标另行保存。
它刻意比播放器格式装得更多:样式、定位、卡拉OK都保留,读进来时修好的东西与跳过的条目都会计数。它面向脚本与流水线,而不是直接给播放器用——要交给播放器时,选一个目标格式,那一页会列出会丢什么。
示例左栏是一份 JSON 原文,右栏不是转换产物,而是本站从这份文件里读出了什么:每条 cue 的时间与文本、样式与定位、cue 之外的键,以及读的时候修好或跳过了什么。
下面每个链接都有独立的转换页与独立的有损说明;所有转换都在浏览器内完成,不上传、不需要账号。
常见问题
SubtitleMatrix 的 JSON 字幕文件长什么样?
一个 `version` 字段、一个可选的 `styles` 对象、一个可选的 `fps` 与 `title`,以及由 cue 对象组成的 `cues` 数组。每条 cue 的 `start` 与 `end` 是整数毫秒,文本放在 `lines` 数组里。
JSON 格式会保存样式和卡拉OK吗?
会,而且比播放器格式更完整。样式表按键名保存字体、字号、颜色、描边与边距;行内样式放在每行的 `tags` 数组里;卡拉OK用区间标注记录到音节。
JSON 里的一毫秒是怎么表示的?
用整数毫秒表示,例如 1.25 秒写成 `"start": 1250`。文件里没有时间码字符串,解析时不需要区分逗号与点号,读进来就是精确的数字。
把 JSON 转成别的格式时,哪个方向是无损的?
没有免费的午餐:本站没有任何播放器格式能装下 JSON 的全部字段,每个转换页都会列出自己那一份损失。选目标时看哪份损失你能接受,而不是看哪个格式最常见。
JSON 文件可以直接用文本编辑器改吗?
可以,只要保持逗号与引号正确。时间是纯数字的毫秒,改一条 cue 的起点就是在 `start` 上换一个整数;改完仍能被解析器读入。
读 JSON 时遇到坏时间码会怎样?
不会抛错。读不出起止的条目不当作 cue,直接跳过并计数;小数毫秒会舍入到最近的整数毫秒;结束早于开始的 cue 会被修复成可加载的一条。
JSON 的 cue 里,每一行的样式存在哪?
存在该行的 `tags` 数组里,用相对正文的区间标注粗体、斜体、颜色或卡拉OK,而不是把控制码塞进文本。这样正文不需要转义,读写两端也不会互相污染。