How to add subtitles to a video

There are three ways to put subtitles on a video — external files, embedded tracks, and burned-in — and the right one depends on where you'll watch. Here's how each works, with per-player steps.

Reference · updated June 2026

“Adding subtitles” can mean three quite different things. Knowing which you want saves a lot of frustration, because a method that's perfect for your laptop may not work on your TV at all.

The three approaches

ApproachWhat it isBest for
Softsub (external)A separate .srt/.vtt file next to the videoMost cases — flexible, editable, switchable
Embedded (muxed)A subtitle track inside the video container (MKV/MP4)One self-contained file, multiple languages
Hardsub (burned-in)Subtitles drawn permanently into the pictureGuaranteed display anywhere; can't be turned off

Prefer softsubs whenever you can: nothing is re-encoded, you can fix timing or typos in seconds, and viewers can turn them off. Reach for hardsubs only when the target can't load external subtitles at all (some social platforms, some old TVs) — and keep your editable file, because burning-in is irreversible.

Softsubs: the file-next-to-the-video method

Most desktop players auto-load a subtitle file if it sits in the same folder and shares the video's name:

Movie.2021.1080p.mkv
Movie.2021.1080p.srt        ← same base name, auto-detected
Movie.2021.1080p.en.srt     ← language suffix also recognised

VLC

  • Auto-loads a same-named file. Otherwise: Subtitle → Add Subtitle File…
  • Fix timing live with G / H (nudge sync), or Tools → Track Synchronisation.
  • Reads SRT, VTT, ASS and more.

MPV

  • Auto-loads same-named files; drag a subtitle onto the window to add one.
  • Cycle tracks with j; shift timing with z / Shift+z.
  • Renders ASS faithfully via libass.

On the web: HTML5 <track>

Browsers need WebVTT — not SRT. Convert first with SRT to VTT, then attach the file with a <track> inside your <video>:

<video controls>
  <source src="movie.mp4" type="video/mp4">
  <track src="movie.en.vtt" kind="subtitles" srclang="en" label="English" default>
</video>

Two things trip people up, and neither is the subtitle file itself:

  • The server must send the file as text/vtt.
  • The file must be same-origin (or sent with CORS headers) — the <track> element is strict about this.

Players like Video.js and Plyr use the same <track> mechanism, so the same rules apply.

Media servers: Plex, Jellyfin, Emby

  • Drop a same-named SRT beside the media file and rescan the library; a language suffix (.en.srt) sets the label.
  • These servers prefer SRT. If you only have VTT, convert with VTT to SRT first.
  • Depending on the client, the server may stream the text track directly or burn it in on the fly when a device can't display it.

Smart TVs and hardware players

  • Most read a same-named SRT from a USB stick beside the video — the most reliable approach.
  • Support for VTT and ASS is patchy; SRT in UTF-8 is the safe bet. If accented or non-Latin text shows as boxes, the TV is likely assuming a different encoding — re-save as UTF-8 with the encoding fixer.
  • If a TV refuses subtitles entirely, embedding the track into an MKV or burning them in may be the only option.

Embedding and burning in

To put a switchable track inside a file, mux it with a tool like MKVToolNix (for MKV) — no re-encoding, fast, reversible. To burn in permanently you re-encode the video with a filter (for example FFmpeg's subtitles= filter), which is slow and lossy and can't be undone. Both are outside the browser, but both start from a clean subtitle file — so get the timing and encoding right here first.

Before you add them: get the file right

  1. Right format for the target? Web needs VTT; players and TVs want SRT.
  2. Text readable, not garbled? Fix the encoding to UTF-8.
  3. In sync? If not, see why subtitles drift and shift or retime them.

Tools for this