▶ Video & streaming

Subtitle formats: SRT, WebVTT, ASS and burned-in subtitles

The technical structure of SRT, WebVTT and ASS, separate versus burned-in subtitles, character encoding, and how to sync or convert subtitles with FFmpeg.

Subtitles look like the simplest part of a video: a few lines of text with a timestamp. In reality there are very different formats, each with its own capabilities and limits, and the wrong choice leads to frequent problems: unreadable accented characters, text appearing too early, styles ignored by the player, subtitles vanishing when you change container. This guide focuses on the technical side: how the files are built, how they are integrated into video and how to fix them.

Separate, embedded and burned-in subtitles

Before the formats, the main distinction needs clarifying.

  • Separate file: the subtitle is its own file, for example film.srt, read by the player alongside the video.
  • Embedded track (soft subtitle): the subtitle sits inside the container as a stream of its own that can be switched on or off. This is typical of MKV files with several languages.
  • Burned-in subtitles (hardcoded): the text is drawn into the video's pixels and can no longer be removed.

The first two are flexible and accessible; burned-in subtitles guarantee the text appears everywhere, for example on social media where many people watch without sound, but they cannot be turned off or translated.

SRT: simple and universal

SubRip (.srt) is the most widespread format. Each block has a sequence number, a time range and the text:

1
00:00:03,200 --> 00:00:06,000
Good morning, let's start with the basics.

2
00:00:06,400 --> 00:00:09,100
The first step is understanding the format.

Characteristics: - milliseconds are separated by a comma; - formatting is minimal: many players accept italics and bold with HTML-like tags, but support is not guaranteed; - there is no header declaring the character encoding.

WebVTT: the web standard

WebVTT (.vtt) is the format expected by browsers' <track> element and is also used in HLS streaming. It resembles SRT but with important differences:

WEBVTT

00:00:03.200 --> 00:00:06.000 line:85%
Good morning, let's start with the basics.
  • the file must begin with the line WEBVTT;
  • milliseconds are separated by a full stop;
  • the encoding is always UTF-8;
  • it supports positioning, alignment, CSS styling and comment notes.

Converting SRT to VTT is almost immediate, but copying an SRT file and renaming it .vtt is not enough: the header and the correct separator are missing.

ASS/SSA: styles and karaoke

Advanced SubStation Alpha (.ass) is designed for elaborate subtitles: typefaces, colours, outlines, precise positions, animation effects and karaoke. It is widely used in fan translations of animation. The file contains a styles section and an events section. The downside is compatibility: many TVs and browsers ignore it or show it without styles.

Image-based formats

On DVD and Blu-ray, subtitles are not text but images (VobSub and PGS). They can go into an MKV, but not an MP4, and cannot be edited without optical character recognition.

Container compatibility

Container Subtitles typically supported
MKV SRT, ASS, WebVTT, PGS, VobSub
MP4 mov_text (plain text), WebVTT in some cases
WebM WebVTT

When a remux from MKV to MP4 fails, the culprit is often the subtitle track itself. You can convert it to mov_text:

ffmpeg -i film.mkv -map 0 -c copy -c:s mov_text film.mp4

Character encoding

An SRT file saved in an encoding other than the expected one shows accented letters as strange symbols: «perché» instead of «perché». It is the sign of a UTF-8 file read as Latin-1, or vice versa. The practical rule is always to save in UTF-8; if a file arrives in a different encoding, convert it before use, for example with FFmpeg's -sub_charenc option or a text editor.

Syncing subtitles

Sync problems come in two kinds:

  1. Constant offset: all subtitles are early or late by the same amount. You fix it by shifting the whole file, for example with FFmpeg's -itsoffset option or the offset feature in players.
  2. Progressive drift: at the start the text is in sync, then it moves further and further away. It usually indicates a different frame rate, for example subtitles prepared for a 23.976 fps version applied to a 25 fps one. You need to rescale the timings, which subtitle editors allow by setting two reference points.

Burning in subtitles with FFmpeg

ffmpeg -i video.mp4 -vf "subtitles=text.srt" -c:v libx264 -crf 20 -c:a copy video_subtitled.mp4

Burning in always requires re-encoding the video. It is best done from the master, keeping a version without subtitles as well.

Good readability practice

  • no more than two lines per block;
  • lines of moderate length, broken at natural points in the sentence;
  • enough time on screen to read calmly, avoiding blocks that flash by;
  • a short gap between one block and the next, so the eye notices the change.

In short

  • SRT is universal, WebVTT is the web standard, ASS handles complex styling.
  • Subtitles can be separate, embedded in the container or burned into the picture.
  • MP4 accepts few subtitle formats: they often need converting to mov_text.
  • Always save in UTF-8 to avoid unreadable characters.
  • Growing drift usually points to a different frame rate.
MM
Marco Marzaduri

Marco Marzaduri works in cybersecurity, digital forensics and web development. A computer science graduate, he combines rigorous technical analysis with attention to the people who use technology.

Read also