toolfree

Subtitle converter

Convert subtitles between SRT, WebVTT and ASS/SSA, and shift the whole timeline when they are out of sync. Runs in your browser; says what each format cannot carry.

Runs in your browser

Negative makes the subtitles appear earlier. Cues that would go before zero are clamped to zero rather than dropped.

Detected
0
Cues
Last cue ends

Parsed and written in your browser. The file is never uploaded.

Three formats, the same three facts

Every subtitle format in common use records the same thing — a start time, an end time and some text. They disagree about almost every detail of how to write it down:

SRTWebVTTASS / SSA
HeadernoneWEBVTT required[Script Info]
Timestamp00:01:02,50000:01:02.5000:01:02.50
Precisionmillisecondsmillisecondscentiseconds
Numberingevery cuenonenone
Line breaknewlinenewline\N
Styling<i>, <b><i>, CSSits own style engine

Paste a file above and the format is detected. Nothing is uploaded — the parsing and the writing both happen in this tab.

Fixing subtitles that are out of sync

This is the actual reason most people open a subtitle converter, and it is one number. Enter how far off the subtitles are, in seconds, and every cue moves.

Cues that would be pushed before zero are clamped to zero rather than dropped. A shift big enough to do that is usually a wrong shift, and quietly losing the first three lines hides that from you.

A constant shift only fixes a constant offset. If the subtitles drift — right at the start and progressively worse — the problem is a frame rate mismatch, typically 23.976 against 25, and no amount of shifting corrects it. That needs a rate change, which this does not do.

What each conversion loses

The page lists it for the file you actually pasted, rather than making you find out later.

ASS → SRT or WebVTT loses everything that makes ASS worth using. Fonts, colours, positioning, karaoke timing, typesetting that tracks a sign as the camera moves — all of it lives in the style engine and has no counterpart. Override tags like {\an8} and {\pos(…)} are stripped rather than left in as literal text, and \N becomes a real line break.

WebVTT → anything loses cue settings. align:start position:10% is how WebVTT positions a line; SRT has no concept of position at all. NOTE, STYLE and REGION blocks go the same way.

SRT ↔ WebVTT loses nothing except cue identifiers, which nothing else reads. <i> and <b> are spelled identically in both.

Anything → ASS rounds the timing to a centisecond, because that is the resolution ASS timestamps have. Ten milliseconds is well under a frame at any frame rate, so it is invisible — but it is real, and a round trip through ASS will not come back byte-identical.

The header WebVTT actually requires

A .vtt file that does not begin with the word WEBVTT is not a WebVTT file, and a browser will refuse it — usually silently, with a <track> element that simply never shows anything. Renaming an .srt to .vtt does not work, and this is why.

The comma is the other half: SRT writes 00:00:01,000 and WebVTT writes 00:00:01.000. Both mistakes produce a file that looks fine in a text editor and does nothing in a video player.

SRT to WebVTT for putting subtitles on an HTML <video>, and ASS to SRT for making a fansub play on hardware that has never heard of ASS.