Subtitle guide Format comparisons

Best subtitle format for Video.js

Updated

TL;DR — Discover why WebVTT is the best format for Video.js. Learn when to convert SRT and how to fix common caption issues. Free tools and troubleshooting guide.

Related tool

SRT to VTT Converter

Open SRT to VTT

For most Video.js subtitle workflows, WebVTT (VTT) is the safest default format. Video.js runs in the browser, so caption delivery should follow browser-friendly subtitle rules. SRT can be a good source format, but WebVTT is the safer final file for player integration.

Quick answer

If your source subtitles are in SRT, convert them to VTT before attaching them to Video.js. That keeps your caption workflow aligned with the format most commonly expected in web playback.

Use the Video.js Subtitle Converter to create VTT output from SRT or ASS input.

Why VTT fits Video.js better

Video.js sits in a browser-first environment, so it benefits from the subtitle format designed for that environment. WebVTT is a good match because it:

  • Built for web playback: WebVTT is the W3C standard for HTML5 video captions
  • Browser-native parsing: Browsers have built-in WebVTT parsers, so rendering is faster and more reliable
  • WEBVTT header: The WEBVTT header signals to the browser that the file is a valid caption track
  • Dot-based timestamps: 00:00:01.000 (dots) match JavaScript time formats, unlike SRT’s comma-based 00:00:01,000
  • Advanced features: WebVTT supports cue settings (alignment, position, size), styling, and metadata that SRT doesn’t

It also gives developers a cleaner debugging path. If the VTT file is valid, caption issues are more likely to come from the player setup, track configuration, or how the file is served - not the subtitle format itself.

Video.js subtitle support by format

FormatVideo.js SupportBrowser SupportNotes
VTT✅ Native✅ All browsersRecommended, best compatibility
SRT⚠️ Plugin required❌ Not nativeNeeds conversion or plugin
ASS/SSA❌ Not supported❌ Not nativeConvert to VTT first

Key takeaway: Video.js works best with VTT. SRT requires a plugin or conversion. ASS is not supported at all. For the complete conversion workflow, see how to convert subtitles for Video.js.

When SRT still appears

SRT still shows up because it’s common in:

  • Exports from transcription tools: Many transcription services (Rev, Otter, Descript) export SRT by default
  • Old subtitle archives: Legacy subtitle files from DVD rips, fansubs, or older projects
  • Handoffs from collaborators: Translators, editors, or clients may send SRT files

That doesn’t make it the best final delivery format for a browser player.

Use SRT for: Review, translation, editing, or archive. Convert to VTT before wiring it into Video.js.

Video.js caption checklist

Before adding captions to Video.js, check:

  • Format: Use a .vtt file for browser playback
  • Header: File begins with WEBVTT (uppercase, first line)
  • Timestamps: Use dots (00:00:01.000), not commas (00:00:01,000)
  • Encoding: Use UTF-8 encoding to avoid character corruption
  • URL: Serve the caption file from a URL the page can request (not a local file path)
  • CORS: If the VTT file is on a different domain, the server must send Access-Control-Allow-Origin headers
  • MIME type: Server must send Content-Type: text/vtt (not text/plain or application/octet-stream)
  • Testing: Test with the same Video.js setup that will be used in production

Practical workflow

Scenario 1: You have SRT subtitles

  1. Keep the source SRT file if you may need to edit it later
  2. Convert to VTT using the SRT to VTT Converter
  3. Validate the VTT file with the WebVTT Validator
  4. Upload the VTT file to your web server or CDN
  5. Add the VTT file to Video.js:
<video id="my-video" class="video-js" controls preload="auto">
  <source src="video.mp4" type="video/mp4" />
  <track kind="subtitles" src="captions.en.vtt" srclang="en" label="English" default />
</video>
  1. Test playback in the browser and verify captions appear

What changes: Timestamp format (commas → dots), file header added (WEBVTT). Text content stays the same.

Scenario 2: You have ASS subtitles (anime, fansubs, styled captions)

  1. Convert ASS to VTT using the ASS to VTT Converter
  2. Validate the VTT file
  3. Upload and test

What you lose: Advanced styling (colors, fonts, positioning, karaoke effects). WebVTT supports basic cue settings (alignment, position) but not ASS-level styling.

What you gain: Browser compatibility, faster rendering, easier debugging.

Scenario 3: You have multiple subtitle languages

Add multiple <track> elements with different srclang and label attributes:

<video id="my-video" class="video-js" controls preload="auto">
  <source src="video.mp4" type="video/mp4" />
  <track kind="subtitles" src="captions.en.vtt" srclang="en" label="English" default />
  <track kind="subtitles" src="captions.es.vtt" srclang="es" label="Español" />
  <track kind="subtitles" src="captions.fr.vtt" srclang="fr" label="Français" />
</video>

Video.js automatically detects all tracks and displays them in the captions menu.

Scenario 4: You need to serve VTT from a CDN

If your VTT file is on a different domain than the video page, configure CORS:

Server-side (CDN or origin server):

Access-Control-Allow-Origin: https://yourdomain.com
Content-Type: text/vtt; charset=utf-8

Client-side (HTML):

<video crossorigin="anonymous">
  <track src="https://cdn.example.com/captions.en.vtt" />
</video>

Without both, the browser blocks the VTT request and captions fail silently.

Common mistakes

Treating every subtitle file as interchangeable

Two files can contain the same lines and timing but still behave differently in browser playback because their formats differ. SRT and VTT are not interchangeable - browsers expect VTT.

Fix: Always convert SRT to VTT before using it in Video.js. See how to convert SRT to VTT for HTML5 video for step-by-step instructions.

Renaming SRT to VTT without converting

Renaming captions.srt to captions.vtt does not convert the file. The browser sees SRT-style timestamps (commas) and no WEBVTT header, so it rejects the file.

Fix: Use the SRT to VTT Converter to properly convert the file.

Testing only in a text editor

A subtitle file that looks fine in a text editor can still fail in the player due to:

  • Wrong MIME type from the server
  • CORS issues (cross-origin requests blocked)
  • Encoding problems (non-UTF-8 characters)
  • Malformed timestamps or cue structure

Fix: Always test the final file in the real playback environment (Video.js in a browser).

Shipping the source file instead of the delivery file

Keep the SRT or ASS source if it helps the workflow, but ship the VTT file to Video.js unless your implementation has a specific reason to do otherwise.

Fix: Use SRT for editing and translation, but convert to VTT for browser delivery.

Forgetting CORS headers for cross-origin VTT files

If your video page is at example.com and the VTT file is at cdn.example.com, the browser blocks the request unless the server sends Access-Control-Allow-Origin headers.

Fix: Configure CORS on the CDN or origin server, and add crossorigin="anonymous" to the <video> element.

Using the wrong MIME type

If the server sends Content-Type: text/plain or application/octet-stream, the browser refuses to parse the file as WebVTT.

Fix: Configure the server to send Content-Type: text/vtt for .vtt files. See How to fix VTT MIME type for HTML5 video for server-specific instructions.

Troubleshooting scenarios

Scenario 1: Captions don’t appear in Video.js

Possible causes:

  • VTT file is malformed (missing WEBVTT header, wrong timestamp format)
  • Server sends wrong MIME type (text/plain instead of text/vtt)
  • CORS headers missing (cross-origin request blocked)
  • Track element has wrong src URL (404 error)

Fix:

  1. Validate the VTT file with the WebVTT Validator
  2. Check the browser console for errors (F12 → Console tab)
  3. Check the Network tab for the VTT request - verify it returns 200 OK and Content-Type: text/vtt
  4. If cross-origin, verify CORS headers and crossorigin="anonymous" attribute

For Video.js-specific issues, see why Video.js captions are not showing. For a broader troubleshooting walkthrough, see Why subtitles do not show in HTML5 video.

Scenario 2: Captions appear but text is garbled

Cause: Wrong text encoding (e.g., Windows-1252 instead of UTF-8).

Fix: Re-save the VTT file as UTF-8 in a text editor before uploading.

Scenario 3: Captions work in Chrome but not Firefox or Safari

Cause: Firefox and Safari are stricter about MIME types and CORS than Chrome.

Fix:

  1. Confirm Content-Type: text/vtt (not text/plain)
  2. If cross-origin, ensure Access-Control-Allow-Origin is set
  3. Check the browser console for specific error messages

Scenario 4: Captions are out of sync

Cause: The subtitle file was created for a different video cut, or timestamps are wrong.

Fix: Use the Subtitle Time Shifter to adjust timing, or re-sync the subtitles to match your video.

Scenario 5: Captions show briefly then disappear

Cause: Track loads but the cue parser fails partway through the file due to malformed cues.

Fix: Re-validate the VTT file. Look for malformed cues in the middle of the file - a single bad timestamp can break everything that follows.

Frequently asked questions

Does Video.js support SRT natively?

No. Video.js relies on the browser’s native <track> element, which only supports WebVTT. To use SRT, you need a plugin or conversion.

Can I use SRT with a Video.js plugin?

Yes, but it’s not recommended. Plugins add complexity, increase bundle size, and may have compatibility issues. Converting SRT to VTT is simpler and more reliable.

What’s the difference between VTT and SRT?

DifferenceSRTVTT
HeaderNoneWEBVTT required
Timestamps00:00:01,000 (comma)00:00:01.000 (dot)
Browser support❌ Not native✅ Native
Cue settings❌ Not supported✅ Alignment, position, size
StylingLimited HTML tagsCSS-like cue settings

Can I style VTT captions in Video.js?

Yes. WebVTT supports cue settings (alignment, position, size) and CSS styling via ::cue pseudo-elements. Video.js also provides its own caption styling API.

How do I add chapters or thumbnails with VTT?

Use kind="chapters" or kind="metadata" in the <track> element:

<track kind="chapters" src="chapters.vtt" srclang="en" />
<track kind="metadata" src="thumbnails.vtt" />

What if my VTT file has a BOM (Byte Order Mark)?

Some text editors (Notepad on Windows) save UTF-8 files with a BOM - 3 invisible bytes at the start. The WebVTT parser sees this as garbage before WEBVTT and rejects the file.

Fix: Re-save the file as “UTF-8 without BOM” in your editor.

Can I use VTT for live streaming?

Yes. WebVTT supports live streaming via HLS (HTTP Live Streaming) or DASH (Dynamic Adaptive Streaming over HTTP). Video.js handles live VTT captions automatically when using HLS or DASH sources.

Use the SRT to VTT Converter

Convert SRT subtitles to WebVTT online for HTML5 video, browser players, and track elements. No signup, no upload, and everything runs locally in the browser.

Open SRT to VTT