VTT to SRT Converter

at cue what was decided what came out
3:1 00:00:01.500 --> 00:00:04.000 the full stop before the thousandths became a comma · the cue was numbered 1 1 00:00:01,500 --> 00:00:04,000
  • SubRip has no published specification and no registered media type. This converter matches the shape every player follows rather than implementing a standard, so the SubRip half of every rule here is convention.
  • The WEBVTT header line was removed. FMT-subrip-header: a SubRip file has no header line.

Going the other way? Convert SRT back to VTT

How do you convert VTT to SRT?

VTT to SRT drops the header and the cue settings, numbers the cues from 1, and turns the full stop before the thousandths back into a comma.

  1. Paste the WebVTT file above. It has to open with the string WEBVTT, followed by a blank line.
  2. Drop the header line and any NOTE, STYLE or REGION block, because a SubRip file has nowhere to put them.
  3. Number the cues from 1 in the order they appear, replacing any cue identifier that is not already that number.
  4. Turn the full stop before the thousandths back into a comma in both timestamps, and write the hours field on every cue.

This page writes the header and cue settings removed, cues numbered from 1 in order, and the full stop swapped back to a comma in both timestamps.

VTT to SRT Conversion Table

The same six parts as the other direction, read from the WebVTT side. The timestamp difference between the two subtitle formats is one character: SubRip writes a comma before the milliseconds and WebVTT writes a full stop. 00:00:01,500 in SubRip is 00:00:01.500 in WebVTT.

VTT to SRT Conversion Table
WebVTT partSubRip partWhat changes
a WEBVTT header linenonethe header line is removed
optional; where present it must be unique across the filea sequential index number on every cue, counted from 1a non-numeric identifier is replaced
[HH:]MM:SS.mmmHH:MM:SS,mmmthe full stop becomes a comma
optional; required only when the hours are not zero, and then two or more digitsalways writtenthe hours field is added where it was left out
cue settings after the end timestampnonethe settings are dropped
a NOTE blocknonethe block is dropped

A format is defined by what it can say. The rows below put the two halves of this conversion side by side, so the gap the conversion has to cross is a thing you can read rather than a thing you find out later. Every value in the table is the wording the defining document uses, not a summary of it, and a dash means the format has no answer to that row at all.

What WebVTT and SubRip Can Say
What it saysWebVTTSubRip
SpecificationW3C WebVTT: The Web Video Text Tracks Format, Candidate Recommendation Draft, 20 May 2026none published - the format is defined by the behaviour of the SubRip program and by convention
Media typetext/vttnone registered
Structurea WEBVTT header line, then region, style, comment and cue blocks separated by line terminatorscue blocks of an index line, a timing line, one or more text lines and a blank line
Header linenone
Timestamp[HH:]MM:SS.mmmHH:MM:SS,mmm
Fraction markU+002E FULL STOPa comma
Hours fieldoptional; required only when the hours are not zero, and then two or more digits
Timing linethe string --> surrounded by one or more spaces or tabs
Cue identifieroptional; where present it must be unique across the filea sequential index number on every cue, counted from 1
Line terminatorCRLF, LF or CR
Commenta NOTE blocknone
EncodingUTF-8none - the format carries no encoding declaration

Worked Example: VTT to SRT

One cue, converted here at build time by the same code the box above runs. The working under it shows the timing line that went in, the decision taken, and the numbered cue that came out.

WebVTT in
WEBVTT

00:00:01.500 --> 00:00:04.000
Hello
SubRip out
1
00:00:01,500 --> 00:00:04,000
Hello
at cue what was decided what came out
3:1 00:00:01.500 --> 00:00:04.000 the full stop before the thousandths became a comma · the cue was numbered 1 1 00:00:01,500 --> 00:00:04,000

Result: the WebVTT above is the SubRip beside it, and every decision that made it is listed below.

The payload came through untouched, which is what makes this pair a punctuation change rather than a mapping. WebVTT was built on SubRip. The W3C specification's acknowledgements name the SubRip program's SRT file format as the basis for the WebVTT text track format, which is why the two convert into each other so cleanly.

Subtitle files are timed text, not structured data. SubRip and WebVTT carry lines of prose against timestamps; they have no fields, no keys and no nesting, which is why they convert into each other and not into JSON. There is no field, no key and no type to carry across, so what is left is a header line, a number and a comma.

The one thing to watch after the conversion is how you save the file. A WebVTT file must be encoded as UTF-8 and labelled text/vtt. A SubRip file declares no encoding at all, which is why accented characters in an SRT file can arrive as the wrong characters.

Check it in reverse

Going back adds the header line and turns the comma into a full stop again, and for a file of plain cues that returns what you started from. What it cannot return is anything SubRip had nowhere to keep: the cue settings, the styling, the comment blocks, and a cue identifier that was a word rather than a number. Those are gone at this step, not the next one.

To prove nothing was lost, convert the SRT result back to VTT and compare it with the file you started from.

What This Conversion Cannot Carry

WebVTT carries more than SubRip does, so this is the lossier of the two directions and the converter names every part it dropped. A WebVTT timestamp is two-digit minutes, two-digit seconds, a full stop and three digits of thousandths, with the hours field optional and required only when the hours are not zero. Both 01:30.000 and 00:01:30.000 are valid WebVTT.

The SubRip side of every rule here
SubRip has no published specification and no registered media type. This converter matches the shape every player follows rather than implementing a standard, so the SubRip half of every rule here is convention.
The WEBVTT header line
The WEBVTT header line was removed. FMT-subrip-header: a SubRip file has no header line.
A NOTE block
A NOTE block was dropped. FMT-webvtt-comment gives WebVTT a comment block; FMT-subrip-comment gives SubRip none.
Cue settings
Cue settings ("align:start") were dropped. WebVTT writes position, alignment and size after the end timestamp and SubRip has nowhere to put them.
A cue identifier that is not a number
The WebVTT cue identifier "intro" was replaced by the sequential number 1. FMT-subrip-cue-identifier: the SubRip convention is a sequential index number on every cue, counted from 1, so a non-numeric identifier cannot survive.
A cue span such as a voice tag
A WebVTT cue span such as <v Speaker> was left in the payload unchanged. SubRip has no equivalent, so a player that does not know the tag will show it as text.
A STYLE or REGION block
A STYLE block was dropped. WebVTT carries styling and region definitions and SubRip carries neither.
A byte order mark
A byte order mark stood at the front of the file. It was removed rather than read as part of the header line.

Each line above is written by the converter itself, and it appears under your own result whenever your document raises it. Nothing is dropped without one.

The sample above reverses exactly - read the same cues back in as WebVTT .

What Does SubRip Not Carry?

Where the cue numbers come from

From the position of the cue, not from the file. WebVTT cue identifiers are optional, and where they appear the specification requires each one to be unique. SubRip numbers its cues in order by convention, so a VTT to SRT conversion adds the numbers and an SRT to VTT conversion can drop them.

What happens when the hours are left out

They are written in, because SubRip requires them. A SubRip timestamp is written HH:MM:SS,mmm - two digits each for hours, minutes and seconds, then a comma and three digits of milliseconds. SubRip has no published specification and no registered media type, so this is the shape every player follows rather than a rule anyone wrote down.

What SubRip has no place for

The header line, the cue settings, the styling and the comments. Every WebVTT file opens with the string WEBVTT, and the W3C specification requires two or more line terminators between that line and the rest of the file. A SubRip file has no header line, so converting to WebVTT means adding one.

VTT to SRT in Code

The same conversion in two lines, one per language. Both strip the header and renumber; neither drops the cue settings for you. Neither line reports what the conversion could not carry; the converter above does.

Python: open("out.srt","w").write(re.sub(r"(\d\d:\d\d:\d\d)\.", r"\1,", body))
JavaScript: body.replace(/(\d\d:\d\d:\d\d)\.(\d\d\d)/g, "$1,$2")

Common Mistakes

Frequently Asked Questions

Is VTT the same as SRT?

No. They carry the same cues and differ in one timestamp character, a header line, and everything WebVTT adds on top: cue settings, styling, regions and comments.

Is converting VTT to SRT free?

Yes, and the file stays in your browser. The conversion runs on this page, so nothing is uploaded and nothing is stored.

What happens to WebVTT cue settings and styling?

They are dropped, and the converter lists each one it dropped. SubRip has nowhere to put position, alignment or size, and no styling of its own at all.

What happens when the VTT timestamp has no hours field?

The hours are written in as 00. WebVTT makes the field optional and SubRip does not, so a timestamp of 01:30.000 becomes 00:01:30,000.

Where do the SRT cue numbers come from?

From the position of each cue in the file, counted from 1. A WebVTT identifier that is already that number survives; anything else is replaced and reported.

Yes. The same file converts straight back in the SRT to VTT direction .

The rest of the family sits on the subtitle and data format index.