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:
- 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
-itsoffsetoption or the offset feature in players. - 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.