SRT to VTT & VTT to SRT Converter — Free, Client-Side
Convert .vtt to .srt or .srt to .vtt — entirely in your browser. Auto-detects direction from your filename. Shows an honest report of what got stripped.
Drop your subtitle file (or paste text), pick the direction, download the converted file. Runs 100% in your browser using JavaScript — no upload, no server, no signup, no file-size limit. Handles the WEBVTT header, timecode separator swap (period ↔ comma), cue identifier renumbering, and strips WebVTT-only features (inline styling, positioning, NOTE and STYLE blocks) that SRT can't represent. Most competing tools force a round-trip through their servers; this one doesn't.
or drag & drop, or paste text below
Which direction do I need?
Look at where the file is going. The target platform decides the format — not the file you have.
| Where the file is going | Convert to | Direction |
|---|---|---|
| YouTube Studio caption upload | SRT | VTT → SRT (if source is VTT) |
| Premiere Pro / DaVinci Resolve / Final Cut / CapCut | SRT | VTT → SRT (if source is VTT) |
| Vimeo / Wistia / broadcast tools | SRT | VTT → SRT (if source is VTT) |
HTML5 <video> + <track> | VTT | SRT → VTT (if source is SRT) |
| HLS streaming (WebVTT playlists) | VTT | SRT → VTT (if source is SRT) |
| VLC / MPC-HC / desktop players | Both work | SRT is the safe default |
Rule of thumb: Web browsers want VTT. Everything else wants SRT. The converter above auto-detects the source direction from your filename extension.
What just happened — the conversion in one paragraph
Four mechanical changes turn a WebVTT file into a valid SRT file. First, the WEBVTT header line — plus any NOTE, STYLE, and REGION blocks — get removed because SRT has no header concept. Second, every timecode's millisecond separator flips from a period (00:00:03.500) to a comma (00:00:03,500). Third, VTT cue identifiers (the optional label line above each timecode) are replaced with sequential numbers starting at 1, because SRT requires numbered cues. Fourth, inline styling like <c.className>, <v Speaker>, and cue positioning settings (line:0 position:50%) get stripped because SRT has no equivalent syntax. Text, timing precision, and cue order stay identical.
SRT → VTT is the reverse: prepend the WEBVTT header, swap commas back to periods in timecodes, drop the sequence numbers (they're optional in VTT). The rest — text and timing — is a straight passthrough.
VTT vs SRT — quick difference
Both are plain-text subtitle formats. Below is what actually differs at the file level.
| Field | VTT (WebVTT) | SRT (SubRip) |
|---|---|---|
| Timecode separator | Period — 00:00:03.500 | Comma — 00:00:03,500 |
| File header | Required WEBVTT line at top | None — starts with cue #1 |
| Cue identifier | Optional label above timecode | Sequential number (1, 2, 3…) |
| Inline styling | <c.class>, <v Speaker>, <i>, <b>, <ruby> | Text only (some players honor <i>, <b>) |
| Positioning | line:, position:, align:, size: | Not supported |
| Primary use | HTML5 <track>, HLS streaming | YouTube, Premiere, DaVinci, CapCut |
For a deeper dive on the SubRip format specifically, see What is an SRT file? — covers structure, encoding, and player compatibility in detail.
When to convert VTT → SRT
Convert to SRT whenever the destination is a video editor or a caption upload workflow that isn't a web browser. Concrete cases:
- YouTube Studio caption upload. YouTube accepts both, but SRT is the format YouTube's docs and every tutorial reference — safer and easier to troubleshoot.
- Adobe Premiere Pro, Final Cut Pro, DaVinci Resolve, Avid Media Composer. All parse SRT natively via File → Import Captions. VTT support varies by version and is buggier in older releases.
- CapCut, InShot, VN, and other mobile editors. SRT is the universal import format. Some don't accept VTT at all.
- Vimeo, Wistia, and legacy broadcast tools. SRT is the safe default when platform docs don't explicitly list VTT.
- VLC, MPC-HC, PotPlayer (desktop players). Both work, but SRT sidecar files are the de facto standard next to a video file.
When to convert SRT → VTT
Convert to VTT when the destination is a web browser rendering an HTML5 <video> element. Concrete cases:
- HTML5 <track> embedding. Browsers only parse WebVTT for the
<track kind="captions" src="...">element. An .srt attached to a track tag will silently fail. - HLS and DASH streaming. Adaptive-bitrate streaming manifests reference WebVTT sidecars for closed captions. If you have SRT masters, convert before packaging.
- Video.js, Plyr, and other JS video players. Most require VTT — some support SRT via plugins, but VTT is the safe default.
- Self-hosted educational videos with styled captions. Only VTT supports CSS-styleable cue classes, positioning, and speaker voice tags.
What gets lost in conversion
Only VTT → SRT loses information (SRT → VTT is lossless because SRT is the simpler format). Here's the full list of what the WebVTT spec supports that SRT cannot represent, and what this tool does with each:
- Inline styling tags.
<c.className>,<v Speaker>,<i>,<b>,<u>,<ruby>,<rt>— all stripped. The plain text between the tags is preserved. - Cue positioning settings.
line:,position:,align:,size:,vertical:— dropped from the timecode line. - File-level metadata. The
WEBVTTheader,NOTEblocks (comments),STYLEblocks (embedded CSS), andREGIONdefinitions all get removed. - Cue identifiers. Optional labels above the timecode in VTT (e.g.
intro-01) are replaced with sequential numbers, which SRT requires. - Chapter cues. WebVTT chapter tracks (used for jump-to-section navigation in HTML5 video) have no SRT equivalent — the tool converts them to plain cues, which most editors will treat as extra subtitles.
What's preserved: cue text, cue order, timing precision to the millisecond, blank lines between cues, and UTF-8 encoding. The conversion report above the converter tells you exactly what was stripped from your specific file.
Command-line and developer alternatives
If you're scripting bulk conversions, integrating into a pipeline, or don't trust browser tools with the file, use one of these instead. All handle the timecode separator swap and header changes correctly.
FFmpeg (one-liner, both directions)
# SRT to VTT
ffmpeg -i input.srt output.vtt
# VTT to SRT
ffmpeg -i input.vtt output.srt
# Batch: convert every .srt in a folder to .vtt
for f in *.srt; do ffmpeg -i "$f" "${f%.srt}.vtt"; doneFFmpeg swaps timecode separators and adds/removes the WEBVTT header automatically. It does NOT preserve WebVTT styling (<c.className>, positioning, NOTE blocks) — those get dropped either direction. FFmpeg treats both formats as generic subtitle streams. Install FFmpeg via ffmpeg.org, Homebrew (brew install ffmpeg), or apt (apt install ffmpeg).
Python (webvtt-py library)
# pip install webvtt-py
import webvtt
# SRT to VTT
webvtt.from_srt("input.srt").save("output.vtt")
# VTT to SRT
webvtt.read("input.vtt").save_as_srt("output.srt")webvtt-py handles both directions with round-trip fidelity for basic cues. Like FFmpeg, WebVTT-specific styling doesn't round-trip through SRT.
Node.js (node-webvtt)
// npm install node-webvtt
const webvtt = require("node-webvtt");
const fs = require("fs");
// Parse VTT, convert to SRT (manual timecode swap)
const vtt = fs.readFileSync("input.vtt", "utf8");
const parsed = webvtt.parse(vtt);
const srt = parsed.cues.map((c, i) =>
`${i + 1}\n${formatSrt(c.start)} --> ${formatSrt(c.end)}\n${c.text}\n`
).join("\n");
fs.writeFileSync("output.srt", srt);node-webvtt parses WebVTT natively; you build the SRT format manually because SRT is simpler enough that a library dependency isn't worth it.
SRT to TXT — strip timing to get plain text
Different job from SRT ↔ VTT: you have an .srt file and want plain text only — no timestamps, no cue numbers, just readable paragraphs for a blog post, a summary, or a document. The browser converter above doesn't strip to plain text (it's built for SRT ↔ VTT round-trip only). Three honest paths:
sed one-liner (macOS / Linux)
# Drop cue numbers and timecode lines; keep only the caption text sed -E '/^[0-9]+$/d; /^[0-9:.,]+ --> [0-9:.,]+$/d' input.srt > output.txt # Same idea but also collapse multiple blank lines into single blank sed -E '/^[0-9]+$/d; /^[0-9:.,]+ --> [0-9:.,]+$/d' input.srt | cat -s > output.txt
PowerShell (Windows)
(Get-Content input.srt) -notmatch '^\d+$' -notmatch '^\d+:\d+:\d+[,.]?\d* --> ' | Set-Content output.txt
Manual find-and-replace (Word / VS Code)
In VS Code with Regex mode enabled (Alt+R): find ^\d+\n and replace with empty (strips cue numbers), then find ^\d+:\d+:\d+[,.]?\d* --> .*\n and replace with empty (strips timing lines). Save as .txt. In Word, use wildcard find-replace with slightly different syntax (@ for “one or more” instead of +) — see our remove timestamps from a transcript guide for Word-specific patterns.
When to use the browser tool above vs CLI: use the browser tool when you want a visual conversion report showing exactly what got stripped, when the file is sensitive and you don't want it leaving your machine (FFmpeg also stays local but the browser tool is more auditable via DevTools), or when you're working with one SRT↔VTT file. Use FFmpeg or a library when scripting bulk conversions, integrating into CI/CD, converting alongside a video transcoding pipeline, or when you need SRT → TXT stripping (the browser tool above doesn't do that).
Adjacent formats — ASS, SBV, and SUB → SRT
The browser converter above handles SRT ↔ VTT directly. If you have a subtitle file in a different format — .ass, .ssa, .sbv, .sub — the conversion path depends on how much styling the source format carries. Honest breakdown per format:
ASS / SSA → SRT (Advanced SubStation Alpha)
.ass and .ssa are the go-to formats for anime fansubs, karaoke tracks, and any subtitle that needs custom fonts, colors, positioning, or rotation. They're much richer than SRT — which means every ASS → SRT conversion strips styling that SRT has no syntax for.
Best desktop tool: Subtitle Edit (Windows, free) or Aegisub (cross-platform, free). Both preserve dialogue text, timing, and basic italic/bold. Both strip karaoke {\k} tags, custom fonts, positioning overrides, and rotation effects because SRT has no equivalent.
Command-line (FFmpeg):
# ASS to SRT
ffmpeg -i input.ass output.srt
# Batch: every .ass in a folder
for f in *.ass; do ffmpeg -i "$f" "${f%.ass}.srt"; doneFFmpeg is stricter than Subtitle Edit — it may strip more formatting than Subtitle Edit preserves. If your ASS is a clean dialogue track (e.g., a translated show without karaoke), either tool produces a usable SRT. If it's a karaoke or heavily-styled fansub, expect a text-only SRT with all animation gone.
SBV → SRT (YouTube legacy caption format)
.sbv is YouTube's original caption format from before SRT support was universal. It's essentially SRT without cue numbers — same millisecond precision, same one-cue-per-block structure, comma-separated timecode range on one line: 00:00:03.000,00:00:05.000.
Conversion is lossless — text, timing, and cue order all preserved. The tool just needs to add sequential cue numbers, split the timecode line into two lines separated by -->, and swap periods for commas.
# SBV to SRT via FFmpeg
ffmpeg -i input.sbv output.srt
# Or Python (webvtt-py handles SBV as of 0.5.x)
import webvtt
webvtt.from_sbv("input.sbv").save_as_srt("output.srt")Google Docs and older YouTube caption downloads still hand out .sbv occasionally. Converting to .srt makes them work in every modern platform (Premiere, DaVinci, VLC, CapCut).
SUB → SRT (MicroDVD, frame-based)
MicroDVD .sub is frame-based, not time-based. Each cue looks like {24}{72}Caption text — that means cue shows on frame 24, hides on frame 72. Wrong framerate = drifting timing across the whole file.
Set the framerate before converting. Common framerates: 23.976 (NTSC film), 24 (cinema), 25 (PAL), 29.97 (NTSC video), 30, 60. Check the source video's properties (macOS: Get Info; Windows: Right-click → Properties → Details; VLC: Tools → Codec Information). If you don't know the framerate, try 25 first for European DVDs and 23.976 for anime.
Subtitle Edit path: File → Open → your .sub → set framerate in the framerate dropdown (Subtitle Edit auto-detects for most files) → File → Save as → SubRip *.srt.
FFmpeg with explicit framerate:
# SUB to SRT at 25 fps (PAL DVD) ffmpeg -i input.sub -r 25 output.srt # SUB to SRT at 23.976 fps (NTSC film / anime) ffmpeg -i input.sub -r 23.976 output.srt
SUB + IDX is different. If your .sub comes bundled with a .idx file, it's VobSub — image-based subtitles ripped from a DVD, not text. Converting VobSub → SRT requires OCR (optical character recognition), not a text conversion. Subtitle Edit has built-in OCR under Tools → OCR → Binary Image Compare or Tesseract, but expect to spot-check the output for OCR mistakes on stylized fonts.
Format cheat-sheet
| Format | Encoding basis | Styling | Best tool for → SRT |
|---|---|---|---|
| VTT (WebVTT) | Time (ms) | Rich (CSS, positioning) | Browser tool above |
| ASS / SSA | Time (ms) | Very rich (karaoke, fonts, rotation) | Subtitle Edit / Aegisub |
| SBV | Time (ms) | None | FFmpeg (lossless) |
| SUB (MicroDVD) | Frame-based | Minimal | Subtitle Edit (needs framerate) |
| SUB + IDX (VobSub) | Image-based | Visual only | Subtitle Edit OCR |
| TTML / IMSC1.1 | Time (ms) | Rich (broadcast-grade) | Subtitle Edit / ttconv |
Common errors and fixes
Mojibake — accented characters look like é or ’
Symptom: You uploaded a Windows-1252 or ISO-8859-1 file. UTF-8 characters got misread.
Fix: Re-save the file as UTF-8 (without BOM). In VS Code: bottom-right encoding label → Save with Encoding → UTF-8. Notepad++: Encoding menu → Convert to UTF-8. Then re-run the converter.
Cues merge on screen after conversion
Symptom: Two subtitles show at once, or one runs into the next.
Fix: SRT requires a single blank line between every cue. If your source VTT was hand-edited without blank lines, the parser treats it as one cue block. Fix the source, then convert.
Player rejects the .srt as broken
Symptom: VLC, YouTube Studio, or your editor won't load the file.
Fix: Check timecode format — SRT uses HH:MM:SS,mmm (comma, three-digit milliseconds). If your file has HH:MM:SS.mmm (period) it's still in VTT format. Re-download from this tool.
UTF-8 BOM breaks the first cue
Symptom: Cue #1 shows as 1 with an invisible prefix, or the player skips it.
Fix: Save without BOM. This tool exports without BOM by default; the issue is usually a source file exported by Excel or older Notepad.
Don't have a subtitle file yet?
This converter only transforms an existing .vtt or .srt file. If you have a video or audio file and no subtitles, you need transcription first, then conversion. VexaScribe generates both formats directly from source media using Whisper Large-v3 — word-level timestamps, 99 languages, and you pick the export format at the end. No conversion step needed.
Frequently Asked Questions
Which direction do I need — VTT to SRT or SRT to VTT?
Depends on your target platform. Convert VTT to SRT if you're uploading to YouTube Studio, importing into Premiere Pro / DaVinci Resolve / Final Cut Pro / CapCut, or playing in VLC. Convert SRT to VTT if you're attaching captions to an HTML5 <video> element via <track kind="captions">, delivering via HLS streaming, or using an embedded web player that expects WebVTT. The widget above auto-detects direction from the filename extension (.vtt or .srt), so you can just drop the file.
What actually changes when I convert VTT to SRT?
Four things. (1) The WEBVTT header line and any header metadata (NOTE, STYLE, REGION blocks) are removed — SRT doesn't have them. (2) Timecodes change separator: 00:00:03.500 (VTT uses a period before milliseconds) becomes 00:00:03,500 (SRT uses a comma). (3) Cue identifiers (optional labels above the timecode line in VTT) are replaced with sequential numbers starting at 1 — SRT requires numbered cues. (4) Inline styling and positioning are stripped: WebVTT <c.className>, <v Speaker>, <i>, <b>, <ruby>, cue positioning (line:0 position:50%) all disappear because SRT has no equivalent syntax. Text content, timing accuracy, and speaker order are preserved.
What actually changes when I convert SRT to VTT?
Four things. (1) A WEBVTT header line is added at the top of the file — WebVTT requires this; SRT doesn't have it. (2) Timecodes change separator: 00:00:03,500 (SRT uses a comma) becomes 00:00:03.500 (VTT uses a period). (3) Cue identifiers (the numeric labels above each timecode line in SRT) are kept — most VTT players accept them. (4) Encoding is normalized to UTF-8 (WebVTT specification requires UTF-8). Text content, timing accuracy, and cue order are preserved. SRT → VTT is essentially lossless because VTT is a superset of what SRT can express.
Does the file leave my browser?
No. This converter runs entirely in your browser — the .vtt or .srt file you upload is read and processed locally with JavaScript. No upload to any server, no request to any API. You can verify by opening browser DevTools → Network tab — you won't see a request for your subtitle file. This matters when the subtitle file contains sensitive content (customer support recordings, internal training, unreleased media).
What gets lost during conversion?
Direction-dependent. VTT → SRT strips WebVTT-specific features SRT can't represent: styling tags (<c.class>, <v Speaker>, <i>, <b>, <u>, <ruby>, <rt>), positioning (line:, position:, align:, size:), metadata (WEBVTT header, NOTE blocks, STYLE blocks, REGION definitions), and cue identifiers (replaced with sequential numbers). Text and timing are preserved. SRT → VTT is essentially lossless — VTT can express everything SRT can, plus more. The conversion report on this page shows exactly what was stripped from your file.
Why do YouTube and video editors want SRT instead of VTT?
SRT (SubRip) is older (early 2000s) and simpler — no styling, no metadata, no positioning options. That simplicity made it universal: virtually every video editor (Premiere, DaVinci Resolve, Final Cut Pro, CapCut, Avid), every subtitle player (VLC, MPC), and YouTube's caption upload workflow parse SRT natively. WebVTT (W3C-standardized 2010) is newer and richer — designed for the HTML5 <track> element with styling and positioning — but that richness isn't supported by most non-web platforms.
Why do HTML5 web players want VTT instead of SRT?
The HTML5 <track> element specifically requires WebVTT format for embedded captions and subtitles. The W3C standardized WebVTT (Web Video Text Tracks) in 2010 to support CSS-like styling, cue positioning, and metadata inline with captions — features that make sense in a browser rendering environment. Browsers won't parse an .srt file as an HTML5 track. If you have an SRT file and want to attach it to a <video> element via <track>, run it through SRT → VTT first.
Can I convert SRT to VTT using FFmpeg or the command line?
Yes. FFmpeg one-liner: ffmpeg -i input.srt output.vtt (or reverse: ffmpeg -i input.vtt output.srt). FFmpeg handles the timecode separator swap and header changes automatically but does NOT preserve WebVTT styling — it treats both formats as plain subtitle streams. For Python, the webvtt-py library reads/writes both formats. For Node.js, node-webvtt handles WebVTT parsing. Use the browser tool on this page when you want a visual conversion report showing exactly what changed; use FFmpeg or a library when scripting bulk conversions.
What about SSA / ASS / SBV / SUB / TTML formats?
The browser converter above handles SRT ↔ VTT directly. For adjacent formats, the honest breakdown: (1) ASS/SSA (Advanced SubStation Alpha — anime, karaoke, styled fansubs) → SRT: use Subtitle Edit (Windows, free) or Aegisub (macOS/Windows/Linux, free) — both preserve as much styling as SRT can absorb (italics, bold), and both export SRT cleanly. ASS-specific effects (karaoke k-tags, rotation, custom fonts) are stripped in any tool because SRT can't represent them. (2) SBV → SRT (YouTube legacy sidecar format): FFmpeg one-liner `ffmpeg -i input.sbv output.srt` — timing is identical between SBV and SRT, so conversion is lossless. (3) SUB → SRT (MicroDVD frame-based): Subtitle Edit converts SUB to SRT and lets you set the video's framerate so the frame numbers convert correctly to millisecond timecodes. Without the right framerate, timing drifts. (4) TTML/IMSC1.1 (broadcast, Netflix delivery): Subtitle Edit or the ttconv command-line tool. Round-trip SRT ↔ VTT covers ~90% of creator workflows; ASS/SBV/SUB/TTML are edge cases where a desktop tool is worth the install.
How do I convert ASS to SRT?
Advanced SubStation Alpha (.ass) → SubRip (.srt): install Subtitle Edit (free, Windows) or Aegisub (free, cross-platform). Subtitle Edit path: File → Open → your .ass file → File → Save as → SubRip (*.srt). Aegisub path: File → Export Subtitles → SubRip (SRT). Both preserve dialogue text, timing, and basic italic/bold formatting. What gets stripped either way: karaoke k-tags, custom fonts, positioning, rotation effects, color styling — SRT has no syntax for these. If your ASS file is a fansub with karaoke effects, expect the SRT to be plain lyrics without the animation. If your ASS is a straightforward dialogue track (translated anime with no karaoke), the SRT will be a clean, complete conversion. FFmpeg also works (`ffmpeg -i input.ass output.srt`) but it strips more styling than Subtitle Edit.
How do I convert SBV to SRT?
YouTube's legacy .sbv format is nearly identical to .srt — same millisecond timing, same one-cue-per-block structure — with two differences: SBV uses a period-separated timecode range on one line (00:00:03.000,00:00:05.000) and has no cue numbers. Conversion is trivial: FFmpeg (`ffmpeg -i input.sbv output.srt`) handles it in one shot, or a Python script (10 lines: split each block, parse the timecode line, emit SRT with sequential numbers). SBV → SRT is lossless — text, timing, and cue order are preserved perfectly. Google Docs and older YouTube caption downloads sometimes still hand out .sbv; converting to .srt makes them work in Premiere, DaVinci, VLC, and every modern platform.
How do I convert SUB (MicroDVD) to SRT?
MicroDVD .sub is frame-based, not time-based — each cue is `{start_frame}{end_frame}Caption text` — so the conversion requires knowing the video's framerate (24, 25, 29.97, 30, 60). Wrong framerate = drifting timing. Best tool: Subtitle Edit (Windows, free) — File → Open your .sub → set the framerate in the framerate dropdown (Subtitle Edit auto-detects for most files) → File → Save as → SubRip. FFmpeg works if you pass the framerate explicitly: `ffmpeg -i input.sub -r 25 output.srt`. For older DVDs, framerate is usually 25 (PAL) or 23.976/29.97 (NTSC) — check the source video's properties first. Note that .sub files bundled with .idx files are a different format (VobSub — image-based, requires OCR) and need a specialized tool like Subtitle Edit's built-in OCR, not a simple text conversion.
How do I know if my file is UTF-8?
Open it in a text editor. If accented characters (é, ñ, ü) or non-Latin scripts (Japanese, Arabic, Chinese) render correctly, it's UTF-8. If they show as garbage characters (é, ñ) or empty boxes, the file was saved in a different encoding (Windows-1252, ANSI, ISO-8859-1). Re-save the file as UTF-8 in VS Code, Sublime, or Notepad++ (via Encoding menu). YouTube Studio, most video editors, HTML5 <track>, and this converter all expect UTF-8. If you paste text with mangled characters into this converter's input, the output will also have mangled characters — fix the encoding at the source first.