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

0 chars · 0 cues
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)

  1. Add WEBVTT header on the first line followed by a blank line — required by the W3C spec.
  2. Convert timestamps. Change the millisecond separator from comma to period: 00:00:01,20000:00:01.200. This is the only format-mechanics change.
  3. 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:

FeatureHow to addExample
CSS styling via ::cueAdd to your HTML page’s <style> or an inline VTT STYLE block::cue { color: yellow; }
Positioning cuesAdd cue settings after the timestamp line00: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 groupsWrap with <c.classname>...</c> + CSS rule<c.speaker-a>Hi</c>
Chapter cuesSeparate <track kind="chapters">Navigation markers for long videos
NOTE commentsAdd anywhere between cuesNOTE This cue is placeholder
REGION blocksDefine regions at the top of the fileAdvanced 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/vtt as the Content-Type, not text/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-Origin headers. The <track> element also needs crossorigin="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:

  1. Add WEBVTT as the first line (nothing else on that line)
  2. Leave a blank line after WEBVTT
  3. Find , in timestamps → replace with . (careful: only inside HH:MM:SS,mmm patterns — use a regex like (\d{2}):(\d{2}):(\d{2}),(\d{3}) $1:$2:$3.$4)
  4. Cue numbers can stay (VTT allows them but doesn’t require them — most players ignore them)
  5. 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.

Upload audio for accurate SRT + VTT

  • 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).

Frequently Asked Questions

Why do I need VTT instead of SRT for web video?

HTML5 <video> with <track> requires WebVTT — it's the only format the W3C spec supports. Browsers will silently reject SRT files served to the <track> element. If you're embedding video on a website with captions, you need VTT.

Can HTML5 <video> play SRT files directly?

No. Even though SRT is universally supported by video editors and standalone players (VLC, MPV), it's not spec-compliant for HTML5 <track>. Browsers may load an SRT file without error but won't display the captions. Convert to VTT first — it's a trivial format change (add WEBVTT header, change comma to period in timestamps).

How do I convert SRT to VTT with FFmpeg?

Simple one-liner: ffmpeg -i input.srt output.vtt. FFmpeg handles the format conversion cleanly. Our browser tool does the same thing without needing FFmpeg installed, plus it shows you what's happening in the conversion.

How do I convert SRT to VTT with Python?

The webvtt-py library: pip install webvtt-py, then in Python: import webvtt; webvtt.from_srt('input.srt').save('output.vtt'). For one-off conversions the browser tool above is faster. For batch conversions in a build pipeline, webvtt-py is the right choice.

How do I convert SRT to VTT for Adobe Premiere?

Premiere Pro accepts both SRT and VTT for its Captions panel — you don't strictly need VTT unless you're exporting for HTML5 web delivery or a platform that specifically requires WebVTT. If you do need VTT: use the tool above, then in Premiere: Window → Captions → drag the .vtt onto the timeline. Convert to a caption track and export as WebVTT via the Captions export settings.

Can I add styling to my VTT after conversion?

Yes. WebVTT supports CSS via the ::cue pseudo-element in your HTML page's <style> block, or via inline STYLE blocks within the VTT file itself. You can also add positioning cues (align, line, position), voice tags (<v Speaker>), and class tags (<c.className>). See the CSS starter snippet in the styling section below — copy it, adjust colors/fonts, drop it into your page.

How do I batch convert multiple SRT files to VTT?

Handful of files: use the tool above one at a time. Batch (many files): FFmpeg shell loop — for f in *.srt; do ffmpeg -i "$f" "${f%.srt}.vtt"; done. Or webvtt-py in a Python script for programmatic control. Our browser tool handles one file at a time by design.

What Content-Type should my server send for VTT files?

text/vtt. Most web servers (Nginx, Apache, Vercel, Cloudflare Pages) send text/plain by default for .vtt files, which will cause browsers to refuse the file. For Nginx: add `types { text/vtt vtt; }` to your mime.types. For Vercel: set the Content-Type header in vercel.json. For Cloudflare: use Transform Rules or a Worker. Serving the wrong Content-Type is the #1 reason HTML5 <track> silently fails to load VTT files.