OnlineTextLab
Esc

SRT vs VTT: Format Differences, Cue Settings and Safe Conversion

Updated 7 min read How we check our guides

Use WebVTT for anything on the web, since the HTML <track> element requires it. Use SRT when you’re uploading to a platform or editor that asks for it, or when you want the simplest possible file that nearly any software can read. Converting SRT to VTT is safe and lossless in practice. Converting VTT to SRT can lose positioning, styling, speaker tags and notes, so keep the VTT as your master if you’ve used those features.

The same captions in both formats

SRT (SubRip):

1
00:00:01,000 --> 00:00:03,500
Welcome back to the show.

2
00:00:04,000 --> 00:00:06,250
<i>Today</i> we're talking about caching.

WebVTT:

WEBVTT

00:00:01.000 --> 00:00:03.500
Welcome back to the show.

00:00:04.000 --> 00:00:06.250
<i>Today</i> we're talking about caching.

The basic differences are visible at once: VTT has a header, a dot rather than a comma before milliseconds, and no need for cue numbers. If you only have plain text captions, this is all that separates them. A converter’s whole job is often these three changes.

How they differ

FeatureSRTWebVTT
HeaderNoneRequired: WEBVTT on the first line
Time separatorComma: 00:00:01,000Dot: 00:00:01.000
Hours in timestampsRequiredOptional: 00:01.000 is valid
Cue identifiersSequential number, expectedOptional, can be any text
Formal specificationNone, a de facto formatW3C WebVTT specification
PositioningNo standard, {\an8} by conventionBuilt-in cue settings
StylingBasic tags by conventionTags, plus CSS through STYLE blocks
CommentsNoneNOTE blocks
Speaker tagsNone<v Name>
EncodingVaries, often legacyUTF-8 only
& and < in textUsually literalMust be escaped: &amp;, &lt;

The lack of a specification is the source of most SRT problems. Parsers vary in how they handle tags, encodings and blank lines, because no document says what’s correct.

What VTT can do that SRT cannot

Here’s a VTT file using these features:

WEBVTT - Episode 12

STYLE
::cue(.warning) { color: yellow; }

NOTE Reviewed by the editor on 3 March

intro
00:01.000 --> 00:03.500 line:0 position:20% size:60% align:start
<v Priya>Hello and <c.warning>welcome</c> &amp; thanks for joining.

00:04.000 --> 00:06.000
<v Tom>Thanks, it's good to be here.

Cue settings come after the timing, on the same line:

SettingValuesEffect
lineA number, or 0% to 100%Vertical position. line:0 is the top
position0% to 100%Horizontal position of the cue box
size0% to 100%Width of the cue box
alignstart, center, endText alignment within the box
verticalrl, lrVertical text, for scripts that need it

Their main practical use is moving captions out of the way when there’s on-screen text at the bottom.

Inline tags include <b>, <i>, <u>, <c.class> for CSS classes, <v Name> for voices, <lang> for language, <ruby> for ruby text, and timestamp tags such as <00:00:02.000> for word-by-word reveal.

A cue’s text can’t contain a blank line, in either format, because the blank line ends the cue. It’s a common cause of cues getting cut in half.

Which players need which

Web browsers. The HTML <track> element uses WebVTT. MDN’s documentation says that tracks “are formatted in WebVTT format”. SRT in a <track> won’t work without first being converted, and that’s the most common reason this comes up. The file must also be same-origin, or the <video> needs a crossorigin attribute, and a subtitles track must set srclang:

<video controls src="talk.mp4">
  <track kind="subtitles" src="talk.vtt" srclang="en" label="English" default>
</video>

Serve the file as text/vtt. If captions silently don’t appear, check the MIME type and any CORS headers first.

HLS streaming for Apple devices. Apple’s HLS authoring specification states that subtitles “MUST be WebVTT” or IMSC1 in fMP4, and on tvOS WebVTT only.

YouTube. Its help page accepts both. It lists SRT as a basic format, and says that no style markup is recognized in it. It lists WebVTT as an advanced format with an initial implementation, which supports positioning and limits styling to bold, italic and underline. So uploading a carefully styled VTT won’t keep everything.

Desktop players. VLC’s feature page lists SubRip among its supported subtitle formats. Support for VTT in other desktop players and editors varies, so test your own setup.

Editing software and social platforms. Requirements vary and they change over time. Check the current help page for the product you use. If a platform doesn’t say, SRT is usually the safer guess.

Converting safely

SRT to VTT

This direction usually loses nothing, because VTT does everything SRT does. Three details matter, however, and they’re the difference between a converter and a find-and-replace.

  1. Add the header, followed by a blank line.
  2. Change the comma to a dot only in timing lines. A global replace would alter commas in your dialogue. Don’t do that.
  3. Escape & and < in the text. A line such as Fish & chips or x < 5 is fine in SRT and invalid in VTT, and some parsers then drop or misread it.

Check the encoding too. SRT files from old tools are often Windows-1252 or similar, and VTT must be UTF-8. If café turns into café or caf�, the source encoding was misread. Convert it to UTF-8 first.

VTT to SRT

This direction loses things. We ran the sample above through ffmpeg and through our converter:

Feature in the VTTffmpeg outputOur VTT to SRT
STYLE and NOTE blocksDroppedDropped
<c.class> tagsRemovedRemoved
<v Priya>Removed, speaker lostBecomes Priya: by default
&amp;Decoded to &Decoded to &
Cue settingsDroppedRough position kept as an {\an7} style tag

The {\an} tags aren’t standard SRT, though many players read them. If your target ignores them, they might show up as literal text. So decide based on where the file is going, and check a cue with position settings by eye.

For a command-line conversion of many files, this is a reliable approach:

ffmpeg -i input.srt output.vtt
ffmpeg -i input.vtt output.srt

We ran both. In the SRT to VTT direction, ffmpeg removed a <font> tag and a {\an8} tag, kept <b> and left a bare & unescaped, so check its output if your text has ampersands.

After any conversion

  • Open the result in the player you’ll be using, not only in a text editor.
  • Check the first cue, the last cue and any cue with an &, a <, or an accented letter.
  • Confirm the number of cues matches. Text after a stray blank line is a usual culprit.
  • Validate that the timing hasn’t drifted. Conversion doesn’t change timing, so if it’s out of sync, the source was off.

Common faults in the wild

Overlapping cues. A cue that starts before the previous one ends. In a browser, both may display at once, stacking up. This is common in auto-generated captions.

Rolling captions. Files that repeat the previous line in every new cue, with inline timestamps, which is YouTube’s download style. Our guide on cleaning auto-generated transcripts covers how to fix that.

A BOM or missing header. A VTT with anything before WEBVTT other than a byte order mark will be rejected entirely. With no header at all, the browser ignores the file with no visible error. Check the network tab and the console.

A dot in SRT or a comma in VTT. Some players are forgiving. Others skip cues without any warning.

Our converters, and when to use something else

SRT to VTT and VTT to SRT run in your browser and handle the timing, header, tags and escaping described above. For example, ours turned Fish & chips into Fish &amp; chips going to VTT, and back again going to SRT. The SRT to Text and VTT to Text tools strip everything down to the words. They suit individual files and quick fixes. They don’t touch timing, so they can’t sync subtitles to a re-edited video, and they won’t handle formats such as ASS or TTML. For timing work, use Subtitle Edit or Aegisub. For batch jobs, use the ffmpeg commands above.