Blog

Subtitles out of sync? How to find the cause and fix it

By the Auto Captions team · Published

An audio waveform above two rows of blocks: yellow speech blocks and blue subtitle blocks that sit slightly to the right of them, showing subtitles running late.
Short answer

Subtitles go out of sync in one of three ways: the same gap on every line (an offset), a gap that grows through the video (drift, usually a frame rate mismatch), or a sudden jump where the video was cut differently. An offset needs one shift, drift needs every timestamp scaled, and a jump needs a shift from that point on.

Most sync advice starts with the delay key in your player. That fixes one kind of problem and leaves you pressing it every five minutes for the other two. Work out which problem you have first. The fix follows from that.

Work out which sync problem you have

Play a line of dialogue in the first few minutes and note how far the subtitle is from the voice. Then jump to somewhere near the end and do the same. Two numbers are enough to tell the three cases apart:

Early in the videoNear the endWhat it is
1.5 s late1.5 s lateConstant offset
0.2 s late2 minutes lateDrift, usually a frame rate mismatch
In sync12 s late, from one scene onwardA different cut of the video
Three timelines of speech and subtitle blocks. Constant offset: every subtitle starts 1.5 seconds after the speech, fixed by shifting every time. Drift: the gap grows from 0.2 to 3.1 seconds, fixed by scaling every time. Wrong cut: the first subtitles are in sync, then after a missing scene every subtitle is 2.3 seconds late, fixed by shifting from the jump on.
Measure the gap twice, once early and once late. Whether it stays the same, grows or jumps tells you the fix.

Subtitles that appear before anyone speaks are the same problems in the other direction. The file is timed to a version of the video that runs faster than yours, or has less footage before that point.

Why subtitles drift: frame rates

An SRT file doesn't store frames. It stores clock times, like 00:45:30,500. So the frame rate of your video only matters when the file was timed against a release that runs at a different speed from yours. The classic case is a film shot at 24 fps (23.976 fps on NTSC-era video, really 24000/1001) that was released in Europe at 25 fps. PAL transfers play every frame faster, so the film runs about 4% short. Steinberg's notes on film transfers to PAL video explain the speed-up.

The ratio between the two speeds is 25 ÷ 23.976 = 1.0427. A 2-hour film at 23.976 fps runs 1:55:05 at 25 fps. Play subtitles timed for the 23.976 release against the 25 fps video and each line shows up late by 4.27% of how far into the video it is: 2.6 seconds late after one minute, and 2 minutes 34 seconds late after an hour. That's why it feels fine at the start and useless by the middle.

Other pairs drift more slowly. 24 against 25 fps is 4.17%. 29.97 against 30 fps is 0.1%, about 3.6 seconds per hour, which you might not notice until the last reel.

Wrong cut: when the gap jumps

If the subtitles are perfect for twenty minutes and then suddenly late, you have a different edit of the video: an extended cut, a TV version with a scene removed, a recording that includes an ad break, or a release with extra studio logos at the start. Logos at the start just add an offset. A missing or added scene in the middle adds a jump, and every line after it is off by the length of that scene. There may be several jumps, and each one needs its own fix.

Quick fix while you watch: the player's delay keys

For a constant offset, the player can fix it on the spot. In VLC on Windows and Linux, press G to show subtitles 50 ms earlier and H to show them 50 ms later (see VideoLAN's hotkeys page). On a Mac the default keys are H (earlier) and J (later). For a big offset, type the value into Tools, then Track Synchronization (Window, then Track Synchronization on a Mac) instead of pressing a key forty times.

The delay isn't saved to the subtitle file, and it can't fix drift or a jump: you'd be chasing the gap all film. Our full guide to loading and syncing subtitles in VLC covers the menus on each platform.

How to fix subtitle timing in the file for good

An SRT is plain text, so you can rewrite every timestamp and save a corrected copy (keep the original). If the format is new to you, our guide to SRT files goes through it line by line.

Constant offset: shift every timestamp

Say the subtitles are 1.5 seconds late all the way through. Subtract 1.5 seconds from every start and end time. Here are two cues before the fix:

47
00:03:12,400 --> 00:03:15,050
You said the train left at nine.

48
00:03:15,300 --> 00:03:17,900
It did. I wasn't on it.

And after. 3:12.400 minus 1.500 is 3:10.900, and so on for every time in the file:

47
00:03:10,900 --> 00:03:13,550
You said the train left at nine.

48
00:03:13,800 --> 00:03:16,400
It did. I wasn't on it.

Doing that by hand across 1,500 cues is miserable, so use a tool. In Subtitle Edit (free and open source, for Windows, macOS and Linux), open the file and choose Synchronization, then Adjust all times, enter 1.5 seconds and click Show earlier.

Drift: scale every timestamp

Drift needs a multiplication, not a shift. Pick two lines far apart, ideally one near the start and one near the end. For each, write down the time in the subtitle file and the time the line is actually spoken in your video. Pause the player to read it. In this example:

  • Line A is at 00:01:10.000 in the file and spoken at 00:01:07.133 (67.133 s).
  • Line B is at 01:40:02.000 in the file (6002 s) and spoken at 01:35:56.164 (5756.164 s).

The ratio is the distance between the two spoken times divided by the distance between the two file times: k = (5756.164 − 67.133) ÷ (6002 − 70) = 0.95904. Then work out what's left over as a plain shift: b = 67.133 − 0.95904 × 70, which comes to almost exactly 0. Every new time is old time × k + b.

A graph of subtitle file time against spoken time. A dashed diagonal marks perfect sync and the file's line runs below it, with point A near the start and point B near the end, where the drift is largest. Beside it, four steps: note both lines, k equals 5756.164 minus 67.133 divided by 6002 minus 70, which is 0.95904, b is about 0 seconds, then new equals old times k plus b for every timestamp.
Two measured lines give you both numbers. k fixes the speed, b fixes any leftover offset.

Look at k: 0.95904 is 23.976 ÷ 25. The numbers just told you the cause. The file was timed to a 23.976 fps release, you have a 25 fps one, and b ≈ 0 means there's no extra offset on top. A line from the middle of the file now lands where it should:

612
00:45:30,500 --> 00:45:33,900
I told you. I was at the station.

becomes

612
00:43:38,661 --> 00:43:41,922
I told you. I was at the station.

If k comes out as 1.0427, it's the same mismatch the other way round. If k is close to 1 and b isn't, you had an offset, not drift. A k that matches no common frame rate usually means a sloppy measurement or a cut in between, so check a third line in the middle.

In Subtitle Edit, Change frame rate does the frame-rate case directly (From frame rate 23.976, To frame rate 25). Visual sync does the two-point method with the video in front of you, so you don't have to calculate anything. If you'd rather script it, this Python does the same math on an SRT. Set K and B, then run python3 retime.py in.srt out.srt:

import re, sys

K = 0.959041   # speed ratio (use 1 for a plain shift)
B = 0.0        # shift in seconds (negative = earlier)

def fix(m):
    h, mi, s, ms = map(int, m.groups())
    t = max(0.0, K * (h * 3600 + mi * 60 + s + ms / 1000) + B)
    ms = round(t * 1000)
    return f"{ms // 3600000:02}:{ms // 60000 % 60:02}:{ms // 1000 % 60:02},{ms % 1000:03}"

text = open(sys.argv[1], encoding="utf-8-sig").read()
text = re.sub(r"(\d{2}):(\d{2}):(\d{2}),(\d{3})", fix, text)
open(sys.argv[2], "w", encoding="utf-8").write(text)

Wrong cut: fix one section at a time

Find the first line where the gap jumps. Select it and every line after it, and shift only those. Subtitle Edit's Adjust all times window has an option for exactly that, selected lines and forward. Repeat at each jump. With many jumps, Point sync lets you set the correct time on several lines and recalculates the ones between them.

Or skip the math: time captions from your own audio

All of the above assumes the file was right for some version of the video. If the video is yours (a talk, a lesson, an interview), it's often faster to make fresh captions timed to its actual audio. Our SRT generator sends only a compressed audio track to a Whisper speech model, gets a timestamp for every word (how that works is in our look at Whisper transcription accuracy), and builds the cues from those, so there's no offset or drift to fix. It's the same engine as our auto captions tool. You proofread the words and download an SRT or VTT.

It handles videos up to 30 minutes, and visitors get 20 minutes of transcription a day, so this is for your own shorter videos, not a feature film. It doesn't translate either. If you already have a nearly right SRT, load it with the video into the burn-in tool: click a line to nudge its start and end against the picture, then download the corrected file or a video with the subtitles burned in. Once the timing is right, our subtitle guidelines cover how long each line should stay on screen.

Stop it from happening again

  • Keep subtitles with the exact release they were made for, and put the frame rate or edition in the file name.
  • If you trim the start of a video after making captions, everything shifts by the amount you trimmed. Make captions last, or shift them by that amount.
Try it now

Try it on your own video

Time captions from the actual audio of your video, fix any line, and download an SRT or VTT. No sign-up.

FAQ

Questions, answered

01

Why are my subtitles out of sync when the file name matches the video?

A matching name only tells the player to load the file. It says nothing about which release the subtitles were timed against. A 25 fps release, a version with an extra logo at the start or a different cut will all put the same file out of sync.
02

How do I know if it is a frame rate problem?

Check the gap early in the video and again near the end. If it grows steadily, it is drift. If the ratio k from the two-point method lands near 0.959 or 1.043, the file was timed for a 23.976 fps release and you have a 25 fps one, or the other way round.
03

Does the VLC subtitle delay change the SRT file?

No. It only changes playback in that session. To fix the timing for good, shift the timestamps in the file itself with a subtitle editor or a script and save it.
04

My subtitles are exactly one hour late. What happened?

Usually an editing timeline that starts at 01:00:00:00 instead of zero, and the captions were exported with that start time. Shift every timestamp one hour earlier, or reset the timeline start and export again.

Still have a question? Contact us