Skip to content

Guides

How to fix embedded subtitles that are out of sync

Every subtitle repair on this site begins with the words load your file. Plenty of people cannot: the subtitles are there in the player, they are wrong by a few seconds, and there is nothing in the folder to load. They are inside the video. Getting them out is one command, and once they are out, every ordinary fix applies.

The subtitles are not a file yet

A video container like MKV or MP4 can carry subtitles as a track, alongside the video and the audio, exactly as it carries a second language of dialogue. The text is in there, with its timestamps, but not as anything you can open. Every guide to fixing subtitle timing, including the ones on this site, assumes an .srt you can drop onto a tool. If yours is embedded, that step is missing, and the rest of the instructions are useless until it is done.

There are three ways subtitles can be attached to a video, and it is worth ten seconds to know which you have. Open the player’s subtitle menu:

  • You can switch them off, or choose between languages. They are an embedded track. This guide is for you.
  • The menu names a file that sits next to the video. They are external. Skip straight to the fix — the constant-delay guide is the usual starting point.
  • There is no subtitle entry and the words are there anyway. They are burned into the picture. Nothing can move them; the only fix is a different copy, or a separate subtitle track laid on top.

Get the track out

The tool for this is ffmpeg, which is free, runs on every platform and is probably already installed if you have ever handled video on the command line. Two commands. The first lists the subtitle tracks so you know which one to take:

ffprobe -v error -select_streams s -show_entries stream=index,codec_name:stream_tags=language -of csv=p=0 film.mkv

It prints one line per track: a stream number, a codec name and a language, something like 2,subrip,eng and 3,ass,ger. The codec name matters more than it looks, because it decides the extension of the file you are about to make. The second command pulls the track out:

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

  • 0:s:0 is the first subtitle track, counted from zero in the order ffprobe listed them, not by the stream number it printed. The second track is 0:s:1.
  • Match the extension to the codec. subrip goes to .srt, ass to .ass, webvtt to .vtt. Ask ffmpeg to copy an ASS track into a .srt and it stops with Unsupported subtitles codec.
  • -c copy keeps the text byte for byte. Leave it off and ffmpeg converts instead, which is what you want for an MP4’s mov_text track, since nothing edits that format directly: ffmpeg -i film.mp4 -map 0:s:0 film.srt. Converting an ASS track to SRT the same way works too, but its positioning and styling are flattened into tags, so copy it as .ass when you can.

If ffprobe reports hdmv_pgs_subtitle or dvd_subtitle, stop here and read the last section: those tracks are pictures, and the text route does not apply.

Fix it like any other subtitle file

From this point the file is an ordinary subtitle file and the diagnosis is the ordinary one. It does not matter that it came out of a container; the timestamps inside it were wrong for your copy of the video in exactly the way an external file’s would be, and for the same reasons.

  • Measure the delay at a line near the start and a line near the end. Two readings tell you which of the next four you have.
  • Same gap everywhere: a constant delay, one number fixes the file.
  • Growing gap: the file drifts, two anchors fix it — or, if you know the rates, a framerate preset does it in one click.
  • Right for an hour, then suddenly wrong: a different cut, fixed one side at a time.

One thing that is easy to get wrong here: the extracted track was timed for this video, by whoever muxed it, so an embedded track is more often off by a constant delay from a lazy mux than by the framerate drift that plagues downloaded files. Measure before you assume. The studio detects the format from the file’s contents rather than its name, so a track ffmpeg just wrote loads as it is, and the corrected file comes back as film.fixed.srt, in the same format it went in and always as UTF-8. If the extracted track shows accented letters as pairs of symbols or question marks, that is an encoding mismatch, not a timing fault, and it has its own one-line fix.

Put it back, or do not

The simplest ending is to not remux at all. Rename the fixed file to match the video with a language code — film.mkv and film.eng.srt in the same folder — and VLC, Plex, Jellyfin, Kodi and most TVs pick it up automatically and list it alongside the embedded track. Choose the external one and you are done. This is the fix for a media server library, where re-writing a file per title is not worth anyone’s evening.

Remux when you need a single file: to send to someone, or for a player that ignores sidecar files. One command copies the video and audio untouched, drops the old subtitle tracks and adds the fixed one:

ffmpeg -i film.mkv -i film.fixed.srt -map 0 -map -0:s -map 1 -c copy -metadata:s:s:0 language=eng fixed.mkv

-map 0 takes everything from the video, -map -0:s then removes its subtitle tracks, and -map 1 adds the fixed file. Because nothing is re-encoded it finishes in seconds and the picture is bit-identical. If you would rather keep the original track as well, leave out -map -0:s. For MP4 output add -c:s mov_text, since MP4 cannot carry SRT directly.

The two cases the text route cannot reach

Image subtitles. Blu-ray rips carry PGS tracks and DVD rips carry VobSub, and both store every subtitle as a bitmap with a start and end time. There is no text to retime. If the problem is a constant delay, shift the whole track at the container level and never extract it:

ffmpeg -i film.mkv -itsoffset 2.5 -i film.mkv -map 0:v -map 0:a -map 1:s -c copy fixed.mkv

The file is opened twice; the second copy is delayed by 2.5 seconds and only its subtitles are used. Negative values pull the subtitles earlier. This cannot fix drift, because drift means each cue needs a different shift. For that, MKVToolNix’s mkvmerge --sync accepts a delay and a linear stretch factor for a track, or you OCR the bitmaps into text with a tool like Subtitle Edit and fix the resulting .srt like any other.

Burned-in subtitles. If the words are part of the picture, they are as fixed as the actors’ faces. No tool moves them. The only remedies are a clean copy of the video, or a correctly timed subtitle track laid over the top — two sets of text on screen, one of them right.

Whatever the container did, the repair is the same as for a loose file: measure, decide constant or drift, fix the file, not the player. The extraction is a detour of two commands, not a different problem.