Fix Out-of-Sync Subtitles: Constant Offset vs Framerate Drift
← 博客
🎬 字幕与隐藏字幕7 min read

Fix Out-of-Sync Subtitles: Constant Offset vs Framerate Drift

💡 If your subtitles are uniformly early or late, fix them with Subtitle Edit's Adjust all times in under a minute. If the gap grows as the file progresses, you have a framerate mismatch: use Change frame rate with the correct scale factor. For example, 1.04271 stretches timestamps from 23.976 fps to 25 fps, and 0.95904 compresses them back.

Key takeaways

  • Diagnose first: check the offset at 10% and 90% of the file length. Equal gaps = constant offset. Growing gap = framerate drift. Each needs a different fix.
  • Constant offset: Subtitle Edit Synchronization > Adjust all times; positive ms delays all subtitles, negative ms advances them.
  • Framerate drift: Subtitle Edit Synchronization > Change frame rate. 23.976 to 25 fps: multiply timestamps by 1.04271. 25 to 23.976 fps: multiply by 0.95904.
  • ffmpeg soft track: -itsoffset [seconds] before the subtitle input delays the track at mux time. Positive values only: for advancing subs, fix in Subtitle Edit first.
  • Two-point sync: for irregular drift, use Subtitle Edit Synchronization > Visual sync with two reference anchors to apply both a scale and an offset at once.

How do I know if it is a constant offset or a drift?

The test takes about a minute. I find two reference points in the file, one near the start and one near the end, and compare how far off the subtitles are at each point.

If both gaps are roughly equal, every subtitle is off by the same fixed amount. That is a constant offset, and the fix is quick. If the gap near the end is significantly larger than near the start, the subtitles were timed against a different frame rate and the error compounds over time. Applying a fixed offset to a drifting file only fixes the middle of the video while leaving both ends wrong.

In practice: jump to around the 5-minute mark and note the offset, then jump to around the 45-minute mark and note it again. Equal at both points, use Adjust all times. One is 2 seconds and the other is 12 seconds, use Change frame rate.

Fixing a constant offset: Subtitle Edit and the SeConv batch option

Open the file in Subtitle Edit and go to Synchronization > Adjust all times. Enter the offset in milliseconds:

  • Subtitles appear too early (before the speech): enter a positive value to delay all lines. For example, +2500 delays every event by 2.5 seconds.
  • Subtitles appear too late (after the speech): enter a negative value to advance all lines. For example, -1800 moves every event 1.8 seconds earlier.

The change applies to every event in the file in one step. Save in the original format when done.

For batch work from the command line, Subtitle Edit's SeConv converter supports a time offset flag:

seconv subs.srt SubRip --offset:0:0:2:500 --output-folder out/ --overwrite

The offset format is hh:mm:ss:ms. The command above adds 2 seconds and 500 ms to every timestamp. The --overwrite flag replaces any existing output file.

Fixing framerate drift: what scale factor do I need?

A framerate mismatch means every timestamp is off by a slightly different amount. The error at minute 1 is small; at minute 50 it has grown large. A single offset cannot fix this because the correct shift is different for every line.

In Subtitle Edit, go to Synchronization > Change frame rate. Enter the frame rate the subtitles were authored for in the From field, and the frame rate the video actually plays at in the To field. Subtitle Edit multiplies every timestamp by the ratio (To / From).

The most common mismatch is between 23.976 fps (NTSC, US streaming, Blu-ray) and 25 fps (PAL, European broadcast). The table below lists the scale factors I look up first:

Subtitles authored forVideo runs atScale factorCommon scenario
23.976 fps25 fps1.04271US streaming SRT used on a PAL rip
25 fps23.976 fps0.95904PAL SRT used on a US streaming or Blu-ray file
24 fps25 fps1.04167Cinema export used on PAL broadcast
25 fps24 fps0.96000PAL SRT used on a cinema DCP or 24 fps stream
23.976 fps24 fps1.00100Subtle drift, easy to miss in a short file

Each scale factor is target fps divided by source fps. You can verify any value on a calculator. To confirm the video's actual frame rate, run:

ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1 video.mp4

If your scale does not match any standard fps pair, the video was likely edited after captioning. In that case, try Subtitle Edit Synchronization > Visual sync: set one reference anchor near the start and one near the end, and the tool calculates the combined scale and offset for the whole file automatically.

How do I delay a soft subtitle track with ffmpeg -itsoffset?

When a subtitle is already embedded as a soft track in an MKV or MP4, I can add a constant delay at mux time without pulling the SRT out first. The -itsoffset option in ffmpeg adds a time offset to an input's timestamps before muxing. A positive value delays the stream. Use it when subtitles appear too early:

# Delay the subtitle track by 3.5 seconds when muxing into MKV
ffmpeg -i video.mkv \
  -itsoffset 3.5 -i subs.srt \
  -map 0:v -map 0:a -map 1:s \
  -c:v copy -c:a copy -c:s srt \
  output.mkv

# For MP4 output, replace -c:s srt with -c:s mov_text
ffmpeg -i video.mp4 \
  -itsoffset 3.5 -i subs.srt \
  -map 0:v -map 0:a -map 1:s \
  -c:v copy -c:a copy -c:s mov_text \
  output.mp4

What each flag does:

  • -itsoffset 3.5: add 3.5 seconds to the timestamps of the next -i input. This option must appear directly before the -i it applies to.
  • -map 0:v -map 0:a: take video and audio from the first input (the video file), no re-encode.
  • -map 1:s: take subtitles from the second input (the SRT, now delayed by 3.5 s).
  • -c:s srt: write the subtitle track as SubRip in MKV. Use mov_text for MP4.

One important limit: -itsoffset works reliably only for positive (delaying) shifts. A negative value subtracts from timestamps, and events near the start of the file can go negative, which many containers and players reject. For advancing subtitles (making them appear earlier), fix the SRT in Subtitle Edit first, then remux with ffmpeg.

When is it worth handing the sync job to a professional?

For a clean constant offset or a standard framerate mismatch, the tools above are enough and the fix takes a few minutes. I run these same checks before I deliver any file.

There are three situations where I hand it off or recommend a specialist:

  • Broadcast or streaming deliverable with QC sign-off required: a sync error in a professional delivery can fail a technical review. The correction needs a follow-up QC pass, not just a visual check on a laptop.
  • Irregular drift from post-production edits: if the video was cut after captioning and segments were added or removed, the drift is not uniform. You need to re-time sections individually, not apply a single global scale.
  • SCC, MCC or SMPTE-TT broadcast formats: SCC encodes CEA-608 data with timecode embedded in the broadcast stream. Shifting SCC sync requires a tool that understands drop-frame timecode and the caption channel structure, not a plain subtitle text editor.

If you need Vietnamese subtitles re-timed and verified for a streaming or broadcast delivery, that is part of my subtitle translation and sync service.

FAQ

My subtitles start in sync but are several minutes late by the end. What is wrong?

This is almost always a framerate mismatch. The subtitle was timed against a version of the video running at a different frame rate than the one you are playing. Use Subtitle Edit Synchronization > Change frame rate. If the video is 25 fps and the SRT was written for 23.976 fps, set 23.976 as the source and 25 as the target. The scale factor 1.04271 will stretch all timestamps to match.

Can I use ffmpeg -itsoffset to advance subtitles and make them appear earlier?

Not reliably. -itsoffset adds to timestamps, so a positive value delays the stream. A negative value subtracts from timestamps, but events near the start of the file can go negative, and many containers and players reject negative subtitle timestamps. For advancing subtitles, use Subtitle Edit's Adjust all times with a negative millisecond value, save the corrected SRT, then remux with ffmpeg if needed.

Does SeConv's --offset flag work on SCC files?

SeConv can process SCC files for format conversion, but SCC encodes CEA-608 data with timecode tied to broadcast drop-frame 29.97 timing. Applying a plain millisecond offset via a general subtitle tool may not produce the correct result for a broadcast SCC file. For SCC timecode adjustments, I use a broadcast caption tool that understands drop-frame timecode and the 608 channel structure.

What causes the 23.976 fps vs 25 fps mismatch?

A common path: someone receives a PAL 25 fps screener from a European distributor and times the subtitles against that version. The final delivery is the US streaming master at 23.976 fps. Since 23.976 fps runs slightly slower than 25 fps, the video finishes later, and subtitles written for the faster version will be progressively late on the slower one. The ratio between the two rates gives the exact scale factor to fix it.

Official Sources

  • FFmpeg documentation: -itsoffset option - confirms that -itsoffset is an input option and a positive value delays the stream. Verified October 2026.
  • Subtitle Edit (Nikse.dk) - Adjust all times, Change frame rate, and Visual sync features; SeConv --offset flag verified from installed version 5.0. Verified October 2026.

Written by Dao Huy (Lucas), Vietnamese translator & localization specialist (EN · ZH · FR → Vietnamese). See translation services →

报价WhatsApp