SRT to VTT Converter
Paste, drop, or upload your .srt. Get a valid .vtt for HTML5 <video>, Podcasting 2.0, and modern web players. Lossless conversion — runs in your browser, no signup, no server upload.
Need the other direction? VTT to SRT Converter →
SRT → VTT Converter
Paste SRT content on the left to see the converted output here.
Runs entirely in your browser — no signup, no upload to servers, no file limits. If you want subtitles generated from audio (not just converted between formats), upload audio here for accurate transcription in both .srt and .vtt formats.
Last verified July 13, 2026
How the conversion works (3 steps, transparent)
- Add
WEBVTTheader on the first line followed by a blank line — required by the W3C spec. - Convert timestamps. Change the millisecond separator from comma to period:
00:00:01,200→00:00:01.200. This is the only format-mechanics change. - Preserve everything else. Cue numbers, cue text, line breaks, blank lines between cues — all copied as-is. SRT is essentially a subset of WebVTT.
SRT → VTT is lossless. Nothing is stripped or lost. What you gain is access to VTT-only features (CSS styling, positioning, voice tags) that you can add manually after conversion — see below.
What you gain by moving to VTT
SRT is minimal — plain-text timed captions and nothing else. WebVTT unlocks features SRT doesn’t support:
| Feature | How to add | Example |
|---|---|---|
CSS styling via ::cue | Add to your HTML page’s <style> or an inline VTT STYLE block | ::cue { color: yellow; } |
| Positioning cues | Add cue settings after the timestamp line | 00:00:01.000 --> 00:00:03.000 align:center line:80% |
| Voice tags (speaker ID) | Wrap cue text with <v Speaker>...</v> | <v Alice>Hello there</v> |
| Class tags for styling groups | Wrap with <c.classname>...</c> + CSS rule | <c.speaker-a>Hi</c> |
| Chapter cues | Separate <track kind="chapters"> | Navigation markers for long videos |
NOTE comments | Add anywhere between cues | NOTE This cue is placeholder |
REGION blocks | Define regions at the top of the file | Advanced positioning zones |
Using your VTT in HTML5 video
The whole point of converting SRT to VTT: the HTML5 <track>element requires WebVTT. Here’s a complete working example:
<video controls>
<source src="video.mp4" type="video/mp4">
<track
kind="captions"
src="captions.vtt"
srclang="en"
label="English"
default>
</video>Two gotchas that catch everyone:
- Content-Type header. The server must send
text/vttas the Content-Type, nottext/plain. Browsers refuse to load VTT with the wrong MIME type and fail silently. See the FAQ below for how to configure this on common servers. - CORS. If the VTT file is on a different origin than the video, the server must send
Access-Control-Allow-Originheaders. The<track>element also needscrossorigin="anonymous"attribute on the parent<video>.
Adding CSS styling to your VTT (the real payoff)
Once you have VTT, style the captions with CSS. Here’s a starter you can copy into your page’s <style> block:
::cue {
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
font-family: 'Inter', sans-serif;
font-size: 20px;
line-height: 1.4;
padding: 0.2em 0.4em;
}
/* Class-specific styling — target <c.speaker-a>...</c> */
::cue(.speaker-a) {
color: #4ade80; /* green */
}
::cue(.speaker-b) {
color: #60a5fa; /* blue */
}
/* Style bold/italic inside cues */
::cue(b) {
font-weight: 700;
}
::cue(i) {
font-style: italic;
}Wrap cue text with class tags to trigger the styling:
WEBVTT 1 00:00:01.000 --> 00:00:03.000 <c.speaker-a>Alice: Hello there.</c> 2 00:00:03.500 --> 00:00:05.500 <c.speaker-b>Bob: Hi, Alice.</c>
Browser support is uneven for advanced styling. Chrome and Firefox handle ::cue well; Safari has gaps (positioning cues in particular are inconsistent). Test your captions in the browsers your audience actually uses.
Publishing VTT via Podcasting 2.0
The Podcasting 2.0 spec recommends WebVTT as the default transcript format via the <podcast:transcript> RSS tag:
<item>
<title>Episode 42 — On Transcripts</title>
<enclosure url="https://example.com/audio/ep42.mp3" length="42000000" type="audio/mpeg"/>
<podcast:transcript
url="https://example.com/transcripts/ep42.vtt"
type="text/vtt"
language="en"
rel="captions"/>
</item>Independent podcast apps — Podverse, Fountain, Podcast Guru, CurioCaster — read the tag and render the transcript natively. Apple Podcasts and Spotify use their own systems and don’t consume the tag, but the open standard covers the rest of the ecosystem. See Podcast Transcription for the full RSS + show-notes workflow.
Adobe / Premiere Pro workflow
Premiere Pro accepts both SRT and VTT for captions — you don’t strictly need VTT unless you’re exporting for HTML5 web delivery or a platform that specifically requires WebVTT.
When VTT specifically matters in Premiere:
- Exporting captions for HTML5 web video (upload the VTT alongside the video, reference from
<track>) - Streaming platforms that require WebVTT (some CDN-based players)
- Advanced styling via CSS that Premiere’s caption tools can’t produce natively
Premiere caption workflow: Window → Captions → drag your .vtt or .srt onto the timeline. Adjust in the Captions panel. Export as WebVTT via the Captions section of the Export Settings dialog.
How to convert SRT to VTT manually (no tool)
Because SRT → VTT is trivial, doing it by hand takes about 30 seconds:
- Add
WEBVTTas the first line (nothing else on that line) - Leave a blank line after
WEBVTT - Find
,in timestamps → replace with.(careful: only insideHH:MM:SS,mmmpatterns — use a regex like(\d{2}):(\d{2}):(\d{2}),(\d{3})→$1:$2:$3.$4) - Cue numbers can stay (VTT allows them but doesn’t require them — most players ignore them)
- Save as UTF-8 without BOM
FFmpeg one-liner
ffmpeg -i input.srt output.vtt
Python (webvtt-py library)
pip install webvtt-py
python -c "import webvtt; webvtt.from_srt('input.srt').save('output.vtt')"Common issues + fixes
“HTML5 <track> won’t load my VTT”
99% of the time: server sending wrong Content-Type. Configure your server to send text/vtt for .vtt files. Test with curl -I your-file.vtt and look for Content-Type: text/vtt. If you see text/plain, that’s the issue.
The other 1%: CORS. If the VTT is cross-origin, add Access-Control-Allow-Origin headers server-side and crossorigin="anonymous" on the <video> element.
“Browser shows raw VTT text on the page”
Your <track> element is missing the kind attribute (should be kind="captions" or kind="subtitles") — or the entire <track> tag is inside the page body instead of inside <video>.
“Timing is off by fractions of a second”
The comma-to-period conversion failed for some cues (usually a stray whitespace or extra character in the timestamp). Our tool handles this correctly; if you converted manually with a loose regex, re-check the timestamps.
“Non-Latin characters garbled”
Save as UTF-8 without BOM. Open in VS Code, click the encoding indicator in the bottom-right, choose Save with Encoding → UTF-8.
“Positioning cues not working in Safari”
Safari’s WebVTT implementation has known gaps around cue settings and CSS ::cue. Test in the browsers your audience uses. Fall back to burned-in captions if you need consistent styling across all browsers — see Caption Generator for the FFmpeg force_style workflow.
Have the audio? Get transcripts + subtitles together
If your goal isn’t just “convert one format to another” but “get accurate captions for a video I have”, upload the audio instead. Our audio-to-SRT flow produces both .srt AND .vtt from the same transcription pass — word-level timestamps, accurate to the millisecond, with speaker labels ready as VTT voice tags.
Processing takes roughly ~1 minute per hour of audio. Free tier: 60 minutes, no credit card.
Related tools
- VTT to SRT Converter — The other direction — convert .vtt to .srt for video editors, VLC, and standalone players.
- SRT Generator + Guide — Full SRT format explainer — anatomy, timing rules (BBC/Netflix), encoding gotchas, and 4 ways to generate.
- Text to SRT (free tool) — Have plain text (translated dialogue, script)? Convert to .srt with reading-speed-appropriate timings.
- Audio to SRT (real alignment) — Upload audio, get both .srt AND .vtt from the same pass with word-level timestamps.
- Podcast Transcription — Publish transcripts via Podcasting 2.0 <podcast:transcript> RSS tag (VTT recommended).