Convert SRT to VTT

Converting SRT to VTT makes a subtitle file the browser will actually load: the output opens with the required WEBVTT header line and every timestamp is rewritten with a full stop before the milliseconds instead of a comma. Those two differences are the entire reason an otherwise correct SRT produces a video with an empty subtitle menu, and both are fixed here in your browser.

  • Where it runs In your browser. The file is never uploaded.
  • Lossless Nothing is discarded. The VTT holds exactly what the SRT held.
  • File size limit Up to 100 MB per file, free, without an account.

Up to 100 files at once. Mixed formats are fine.

Why a browser will not read your SRT file

HTML video takes subtitles through a track element, and the only subtitle format that element accepts is WebVTT. Hand a browser an SRT and nothing happens: no console error, no entry in the subtitle menu, just a video playing without captions. That silence is what brings most people to this conversion, because the file is correct, the markup is correct, and the format is the single thing that is wrong.

The two formats being close relatives makes the failure more confusing than it deserves to be. Structurally a WebVTT file is a SubRip file with a header line and a different decimal separator. The browser is not objecting to anything substantial; it is refusing a file that is two mechanical edits away from valid, and this converter makes both of them.

The two spelling differences between SRT and VTT

The first is the timestamp. SubRip writes 00:01:32,500 with a comma before the milliseconds; WebVTT writes 00:01:32.500 with a full stop. One character per timestamp, twice per cue, and a parser that finds the comma stops reading. Most of the world writes decimals with a comma, which is why hand-edited files acquire this fault so reliably.

The second is the header. A WebVTT file must begin with the word WEBVTT on its own first line, before anything else. It is not documentation and it is not optional — a file without it is rejected outright. The output here opens with WEBVTT followed by a blank line, and writes every timestamp as hours, minutes, seconds and milliseconds with the hours zero-padded and a full stop in front of the fraction.

Renaming an SRT to .vtt is the mistake worth naming

It is the first thing almost everyone tries, and it is understandable: the file is text, the structures look alike, and changing an extension takes a second. It also cannot work, because neither of the two differences above lives in the filename. The result is a file that claims to be WebVTT, is served as WebVTT, and is discarded by the parser at the first line.

What makes this expensive is that the failure looks like something else. Developers who have renamed the file go on to check the track element, the file path, the MIME type and the player, none of which are the problem. Converting properly removes the possibility, which is worth doing before spending an afternoon on the markup.

Cue numbers from the SRT are dropped on the way into VTT

SubRip numbers every cue, starting at one, on the line above the timestamp. This converter reads those numbers, uses them for nothing, and does not write them into the VTT. The output is a header, then a blank line, then timestamp-and-text blocks separated by blank lines.

That is a design decision rather than a loss. WebVTT treats the line before the timestamp as an optional cue identifier, not as a counter, and nothing in a browser or a player depends on it. Anything you genuinely need to attach to an individual cue — a vertical position, an alignment, a width — is a cue setting written after the end timestamp, and a numeric identifier would only be noise in front of it.

Italics and other inline tags travel across unchanged

The text of every cue is copied verbatim from the SRT into the VTT. Nothing is stripped, escaped or reinterpreted. Both formats spell italics and bold the same way, with the same angle-bracket tags, so a file that uses them for emphasis keeps that emphasis on a web page.

The consequence is worth checking before you publish. A player-specific code that some desktop software honours in an SRT — an ASS-style positioning tag in curly braces is the common one — also survives verbatim, and a browser has no idea what it means. It will render as literal characters in the middle of a caption. If your SRT came from a fansub or a media-centre workflow, read the first few cues of the output.

Wiring the finished VTT into a track element

The track element goes inside the video element, with src pointing at the .vtt file, kind set, srclang set to the language code, and a label that becomes the entry in the subtitle menu. Add the default attribute if the captions should be on when the video starts, because otherwise the viewer has to find the menu and most will not.

The kind attribute is the one worth thinking about rather than copying. Subtitles assume a viewer who can hear and translate the dialogue; captions assume a viewer who cannot hear and therefore describe the non-speech audio as well. Where captions are an accessibility obligation rather than a nicety, a track marked as captions that contains only translated dialogue satisfies the markup and not the requirement.

The VTT loads and the menu is still empty

If the header and the timestamps are correct and the captions still do not appear, the remaining causes are in the page rather than the file. The track element may be missing kind or srclang, or the viewer may never have switched subtitles on because there is no default attribute anywhere.

The one that costs the most time is cross-origin. A VTT served from a different origin than the page — a separate asset domain, a bucket, a CDN hostname — is refused unless the response carries the right cross-origin headers, and the refusal is silent. The video plays, the menu is empty, and nothing on the page suggests why. Serving the subtitle file from the same origin as the page removes the whole class of problem.

Work through the four in that order rather than changing several things at once, because they produce the same symptom and fixing two while a third is still wrong looks like neither fix worked. The quickest discriminator is to open the .vtt URL directly in a tab: if the file renders as text, the path and the server are fine and the fault is in the markup or the origin. If it downloads or 404s, nothing about the track element was ever going to matter, and the remaining work is a hosting question rather than a subtitle one.

Keep the SRT as the master and generate the VTT

Subtitle editors, transcription services and desktop tooling are better at SRT than at anything else on this site; it is the format the whole ecosystem assumes. Correcting text and timing there and converting at the point of publishing is a sound division of labour.

The failure mode to avoid is maintaining both. Two files that started identical drift apart the first time somebody fixes a typo in whichever one they happened to open, and the drift is invisible until a viewer reads a caption that the transcript does not contain. Treat the VTT as build output: regenerate it, never edit it.

Serving the .vtt so the browser will take it

The file is produced with the WebVTT media type, text/vtt, and the server that eventually hosts it needs to send the same thing. Most static hosts map the .vtt extension correctly now, but a surprising number of older configurations fall back to a generic binary type or to text/plain, and a browser handed a caption file under the wrong type is entitled to refuse it. If the header and the timestamps are right and the track still does not load, the response headers are the next place to look and the fastest to check.

Two smaller deployment details save time later. Caption files are tiny and change rarely, so they cache well, and a long cache lifetime on a file you later correct is a caption error that persists on a viewer’s machine after the fix has shipped — version the filename rather than relying on a purge. And keep the extension as .vtt even when a build pipeline wants to fingerprint it, because some players and validators still key off the extension rather than the media type when deciding whether a track is worth fetching at all.

Where this SRT to VTT conversion runs

In your browser, in JavaScript, with no upload and no queue. The file is read as text, parsed into a list of cues with millisecond timings, and written back out in WebVTT form. There is no server involved, which is why it is instant and why there is no sign-up.

The free ceiling is 100 MB and no subtitle file will ever approach it — a feature film is a few tens of kilobytes of text. The more useful guarantee is that the output is written as UTF-8. SubRip has no way to declare its own encoding, which is why accented characters go wrong so often; committing the output to UTF-8 is what a browser expects and settles the question at the point of conversion.

How to convert SRT to VTT

  1. Drop your SRT file onto this page, or click to choose one.
  2. It is parsed and rewritten as WebVTT in your browser.
  3. Download the .vtt and point a track element at it.

SRT against VTT, viewed from the track element

SRT compared with VTT
SRTVTT
Full nameSubRip SubtitleWebVTT
File extension.srt.vtt
Media typeapplication/x-subriptext/vtt
First published20002010
Published byW3C
SpecificationWebVTT
LicensingOpen standardOpen standard
Standing todayCurrentCurrent
Opens in a browserNo browserEvery browser
Considered insteadASSASS

What survives

Nothing is discarded. SRT and VTT both store their content losslessly, so the conversion is a change of packaging rather than a change of quality, and it can be repeated without accumulating damage.

Opening the result

VTT opens in every current browser. SRT has narrower browser support than that. If the file is going onto a web page or into a form, that is usually the whole reason for the conversion.

VLC and Subtitle Edit read both SRT and VTT, so there is a way to check the result against the original without a second tool.

What each format is for

VTT comes from W3C and dates from 2010, specified as WebVTT. VLC and Subtitle Edit all read it.

SRT to VTT: what web developers actually ask

Are my SRT files uploaded anywhere?

No. This conversion runs entirely inside your browser, so the file never leaves your device. You can confirm it yourself: open the network tab of your browser's developer tools and convert something. You will see the page load, plus the analytics and advertising the site is paid for with — and nothing carrying your file.

Why does my SRT file not work in a browser?

Because the track element accepts WebVTT and nothing else. A browser handed an SRT does not report an error — the video plays and the subtitle menu stays empty, which is why this looks like a markup problem when it is a format problem.

Can I just rename the file to .vtt?

No. Two things have to change inside it: the file must begin with WEBVTT on its own first line, and every timestamp must use a full stop before the milliseconds instead of a comma. A renamed SRT fails both tests and is rejected.

Are the cue numbers kept?

No. SubRip numbers every cue and the converter does not write those numbers into the VTT, because WebVTT treats the line before the timestamp as an optional identifier rather than a counter. Nothing downstream needs them.

What happens to italic tags in my SRT?

They come across unchanged. The text of each cue is copied verbatim, and both formats spell italics the same way. Player-specific codes such as an ASS-style positioning tag also survive verbatim, and a browser will render those as literal characters.

Is the file uploaded anywhere?

No. The parser and the writer are plain JavaScript running in your browser, so the subtitle file never leaves your machine. The free ceiling is 100 MB, which is orders of magnitude more than any subtitle file needs.

What character encoding does the output use?

UTF-8. An SRT carries no declaration of its own encoding, so the reading step interprets the bytes and the writing step commits to UTF-8, which is what browsers expect from a WebVTT file.

More about these formats