Convert, retime and clean SRT and VTT subtitle files in your browser.
SubRip (.srt) came from a DVD-ripping program in the early 2000s and became the default subtitle format almost by accident. WebVTT (.vtt) was designed later, specifically for HTML5 video, and is what a browser expects when you attach a track element to a video.
They look so similar that people assume renaming the file is enough. It is not, and the failure is silent: a browser handed an SRT file renamed to .vtt will usually display nothing at all, with no error explaining why.
First, the header. A WebVTT file must begin with the literal word WEBVTT on its first line. An SRT file has no header and begins directly with the first cue. This single missing line is the most common reason a converted file silently fails in a browser.
Second, the millisecond separator. SRT writes 00:00:01,500 with a comma. WebVTT writes 00:00:01.500 with a period. A player expecting one and given the other will usually reject the cue.
Third, cue numbering. SRT cues are conventionally numbered with a line containing just an integer before each timestamp. In WebVTT that identifier is optional and, if present, may be any string rather than a number.
There are smaller differences too: WebVTT allows the hours component to be omitted, so 01:30.000 means ninety seconds, and it supports positioning settings after the timestamp such as line:90% align:center. This tool reads all of these and preserves cue settings when converting to VTT.
Load your file — the format is detected automatically from the WEBVTT header — then download in whichever format you need. Timings are held internally as integer milliseconds, so a conversion is exact and converting back and forth does not accumulate drift.
Cue numbers are renumbered contiguously from 1 on export. If your source file had gaps or duplicates in its numbering, which is common in files that have been hand-edited, the output is clean.
Every file is checked on load and the results appear above the preview. Each message names the specific cue number, because "this file is invalid" is useless when the file has nine hundred cues.
Errors are genuine breakages: a cue that ends before it starts, a cue that begins before the previous one, or a timestamp that could not be read at all. Warnings are things that are technically valid but usually unintended: a zero-duration cue that will never appear on screen, or two cues overlapping so that both are displayed at once.
A malformed cue does not abort the whole file. The bad block is reported and the remaining cues still load, so you can see the scale of the problem in one pass instead of fixing errors one crash at a time.
Subtitle files often carry markup: HTML-like tags such as <i> and <b>, WebVTT class and voice tags like <c.loud> and <v Speaker>, and SubStation override blocks like {\an8} that control positioning.
The "Remove formatting tags" button strips all of these while preserving the line breaks inside each cue, which matter for readability. Character entities such as & are deliberately left alone, because they are content rather than formatting.
Out-of-sync subtitles come in two distinct varieties, and applying the wrong fix makes things worse. Spend thirty seconds diagnosing before you touch anything.
A CONSTANT OFFSET means the subtitles are wrong by the same amount everywhere. Check a line near the start and a line near the end. If both are late by about two seconds, you need a shift.
DRIFT means the error grows as the video plays. If the first line is nearly right but the last line is forty seconds out, a shift will not help — you need to scale. Drift almost always comes from a frame-rate mismatch: the subtitles were timed against a 23.976 fps release and your video runs at 25 fps, or vice versa.
Enter the offset in milliseconds. A positive number delays the subtitles, which is what you want when they appear too early. A negative number moves them earlier, for subtitles that lag behind the dialogue.
Measure the error rather than guessing. Note the timestamp where a line is actually spoken and the timestamp where it currently appears, then use the difference. Two seconds is 2000 ms.
Timestamps are clamped at zero. Neither SRT nor WebVTT can represent a negative time, and a player handed one will typically reject the cue or behave unpredictably. So if you shift a file backwards by more than the first cue's start time, the affected cues are pinned to 00:00:00 rather than going negative — and the tool tells you exactly how many cues that happened to. If you see that warning, your offset is probably too large.
Scaling multiplies every timestamp by a constant factor, which is the correct fix for drift.
The factor is the ratio of the frame rates. Converting subtitles timed for 23.976 fps to a 25 fps video means multiplying by 25 ÷ 23.976, approximately 1.0427. Going the other way, use 23.976 ÷ 25, approximately 0.959.
If you do not know the frame rates, you can derive the factor from the drift itself: divide the correct time of the last line by its current time. Apply it, then check both ends again.
Merging is for material that was subtitled in parts — the two halves of a film released as separate files, for example.
Load your main file first, then choose the second file in the merge panel and give it an offset. The offset is where the second part begins in the combined timeline: if part one runs for 58 minutes and 20 seconds, the offset is 3,500,000 ms.
Cues from both files are combined and re-sorted by start time, so the result is always in valid order even if the offset overlaps the two sets slightly. Everything is renumbered from 1.
Splitting does the reverse, dividing a single file at a timestamp you choose.
By default the second part is rebased so it starts from zero, which is what you want when it will be played against a separate video file that also starts at zero. Cues are assigned to the part containing their start time, so a cue that straddles the split point goes with the part it began in rather than being cut in half.
Both parts download at once, named -part1 and -part2. If your chosen split point would leave one part empty, the tool tells you instead of silently producing an empty file.