JSON to SRT
Or paste subtitle text
What this conversion changes
3 things are dropped or need a decision
- Styling
all styling (bold, italic, colour, outline, shadow)
- Positioning
on-screen positioning (every cue returns to the default position)
- Karaoke
karaoke timing (per-syllable highlighting)
This list comes from the capability matrix for these two formats, not from the particular file you loaded. A specific file may lose more if it uses features the format allows but the matrix does not model.
This page reads a JSON document describing subtitles and writes an SRT file from it. The shapes it accepts are the schema this site writes — a version number, then a cues array — and the plain form where the document is simply a list of cues. Either way, what it needs from each cue is a start, an end and some text; the times are milliseconds and go straight into SRT timecodes, which is the same resolution, so nothing is rounded on the way.
Anything in the document that SRT cannot hold is reported rather than quietly discarded: a title, a frame rate and a style table have no home in a subtitle file that is nothing but numbered cues. Where a cue uses formatting — italics, bold, a colour — it is written out as the corresponding tag, and what the tag cannot express is listed above.
A file that is damaged does not stop the conversion. The parser reads what it can and repairs a cue whose end is not after its start, because a subtitle file you can load and fix is worth more than an error message. A whole set of JSON files converts in one pass, in your browser, and comes back as a ZIP.
Examples
A typical JSON file, converted to SRT
Input
{
"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"
}
]
}
Output
1
00:00:00,000 --> 00:00:02,000
Hello world.
Second line.
2
00:00:02,500 --> 00:00:04,000
Plain line.
<i>Styled</i> line.
3
00:00:04,500 --> 00:00:06,000
Roger: I am here.
Dropped in this output: styling, positioning and karaoke. Everything else matches line for line.
The same conversion on an awkward input
Input
[
{ "start": 0, "end": 1000, "lines": ["First."] },
{ "start": 1000, "end": 2000, "text": "Second." },
"not an object",
{ "start": 2000, "end": 3000, "lines": ["Third."], "class": "top" }
]
Output
1
00:00:00,000 --> 00:00:01,000
First.
2
00:00:01,000 --> 00:00:02,000
Second.
3
00:00:02,000 --> 00:00:03,000
Third.
This is the kind of damage real files have — mixed line endings, stray whitespace, fields left empty. Compare it with the tidy example above to see what the parser forgives.
Frequently asked questions
Which JSON shapes are accepted?
The document this site writes — a version number and a cues array — and the equivalent array form, where the file is just the list of cues. What matters is that each cue has a start, an end and some text in one of the recognised shapes.
What happens to the title, styles and frame rate in my JSON?
They are read and then reported as dropped, because SRT has no field for them. A frame rate in particular has nowhere to go — SRT stores clock time, not frames — so it is listed above rather than used silently.
Are the milliseconds rounded on the way out?
No. SRT stores milliseconds and the JSON file is written in milliseconds, so every start and end is transferred exactly and the timeline does not drift.
What if a cue's start is after its end?
The converter repairs it rather than refusing the file, so a document that has been edited by hand still produces a loadable subtitle file. Check the timings of that cue against the video, since the file was telling you something was wrong.
Can I convert back and forth without losing anything?
Converting to JSON and back reproduces your timeline exactly, and reproduces the formatting that JSON can describe: italics, bold and colours become tags and come back as tags. What does not survive a round trip is anything SRT itself cannot store, which is exactly what is listed above.