SkillAgentSearch skills...

Subsync

synchronize .srt or .ssa subtitles with the video timeline

Install / Use

/learn @xuminic/Subsync
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Adjust Subtitle Timing with Subsync

Subsync is a command-line tool used to adjust the timeline of subtitle files so that audio and subtitles stay synchronized. It can:

  • Shift subtitle display times forward or backward by a specified offset
  • Scale subtitle timing proportionally to adjust drift
  • Adjust subtitles only within a specified time range
  • Support .srt, .ass, and .ssa subtitle formats
  • A filtering program written in C — simple and fast
  • Rely only on the standard C runtime library, making it portable to all operating systems
  • A command-line tool, making it easy to integrate into scripts

Why Subsync Is Needed

I have some old TV series and .srt subtitle files found online, but many of them are out of sync. Since the structure of .srt is very simple, in theory you only need to extract the timestamps, adjust them slightly, and write them back.

Surprisingly, all I could find were large GUI programs, not the lightweight command-line tool I wanted. Even worse, I couldn’t find any tool that could scale the subtitle timeline. Some videos run at 30 fps, while the matching subtitles were created for 25 fps. At the beginning, the video and subtitles are in sync, but the further you go, the larger the drift becomes. A simple time offset won’t fix this. So I wrote this small program to fill that gap.

Build and Install

You can fetch the source code from GitHub and compile it:

git clone https://github.com/xuminic/subsync.git
cd subsync
make

If everything goes well, it should produce the subsync executable. You can move it anywhere on your system path.

To build the Windows version, you can compile directly on Windows using MinGW64 or Cygwin, or cross-compile on Linux using MinGW, for example:

apt install mingw-w64

Then, inside the subsync directory:

make allwin

make will automatically download libiconv-1.18.tar.gz, compile it, and generate both Win32 and Win64 versions of the subsync executable.

  • You can place libiconv-1.18.tar.gz in the subsync directory in advance to allow offline compilation
  • The Windows executables are named as: subsync_i686.exe and subsync_x86_64.exe
  • Prebuilt Windows binaries are available directly in the GitHub Releases section
  • There is no installer for Windows — simply copy and use the program

Command Line Options

  • If no filename is specified, subsync reads from stdin and writes to stdout, for example:

    subsync +12000 < source.ass > target.ass
    
  • Any argument that is not a command-line option is treated as an input filename. You mau use the -w option to specify the output filename. For example:

    subsync +12000 -w target.ass source.ass
    

    This command is equivalent to the previous one.

  • You may specify multiple filenames in a single command, for example:

    subsync +12000 source1.ass source2.ass source3.ass
    

    However, all output will be combined and written to stdout. The same applies when using -w:

    subsync +12000 -w target.ass source1.ass source2.ass source3.ass
    

    All output will be combined into target.ass.

  • To overwrite files directly, use the -o or --overwrite option:

    subsync +12000 -o source1.ass source2.ass source3.ass
    

    The output files will therefore be source1.ass, source2.ass, and source3.ass.

  • There is a slight difference between --overwrite and -o: --overwrite creates a backup file:

    subsync +12000 --overwrite source1.ass source2.ass source3.ass
    

    The modified content overwrites source1.ass, source2.ass, and source3.ass, while backup files source1.ass.bak, source2.ass.bak, and source3.ass.bak are created. If something goes wrong, you can restore them.

  • Time-offset option: -/+OFFSET is used to shift subtitle timing forward or backward.

    • + increases timestamps, meaning subtitles appear later.
    • - decreases timestamps, meaning subtitles appear earlier.
    • OFFSET is the amount of shift applied to subtitle timestamps. Supported formats include:
      • Milliseconds, e.g. 19700
      • .srt format timestamps, e.g. 0:0:10,190
      • .ass/.ssa format timestamps, e.g. 0:0:10.19
      • Timestamp arithmetic, e.g. 01:44:31,660-01:44:36,290
      • See the HOWTO: Time Offset section below.
  • Time-scaling option: -SCALE scales subtitle timestamps by a factor. It may be:

    • A floating-point number, such as 1.1988
    • Predefined constant N-P (equals 1.1988)
    • Predefined constant P-N (equals 0.83417)
    • Predefined constant N-C (equals 1.25)
    • Predefined constant C-N (equals 0.8)
    • Predefined constant P-C (equals 1.04271)
    • Predefined constant C-P (equals 0.95904)

    This option cannot be confused with -OFFSET, since scaling must be a floating-point value. See the HOWTO: Time Scale section below.

  • To delete subtitles within a specific range, use -c N:M or --chop N:M.

    N:M refers to subtitle sequence numbers for .srt files.

  • To reorder .srt sequence numbers, use -r [NUM] or --reorder [NUM].

    This is used to tidy up subtitle numbering, especially after splitting or merging subtitles, which often results in messy numbering.

    Although this does not affect playback, it looks untidy. The -r option will renumber subtitles starting from 1. If NUM is provided, numbering will start from NUM.

  • To specify a timestamp range, use -s TIME or --span TIME.

    If you only want to modify subtitle timestamps within a certain range rather than the whole file, use this option. A range looks like this: -s 00:00:52,570 0:11:00,140. If only the start time is given, e.g. -s 00:00:52,570, the default end time is the end of the file.

  • Specify an output filename using -w FILENAME or --write FILENAME.

    If no output filename is provided, output goes to stdout, unless -o or --overwrite is used to modify files directly.

Time Formats

subsync supports the following time formats:

  • Integer value, in milliseconds, e.g. 19700

  • .srt timestamp format, e.g. 0:0:10,190

    • The fields separated by colons represent hours, minutes, and seconds.
    • They may be omitted from the left, e.g. 1:20 means 1 minute 20 seconds.
    • The part after the comma is milliseconds: 190 means 190 ms.
  • .ass/.ssa timestamp format, e.g. 0:0:10.19

    • The fields separated by colons represent hours, minutes, and seconds, and may also be shortened the same way.
    • The part after the dot represents centiseconds: .19 means 19 centiseconds = 190 ms.
  • Timestamp arithmetic, used for offsetting timestamps, e.g. 01:44:31,660-01:44:36,290. subsync converts both timestamps to milliseconds and subtracts them. The result may be positive or negative:

    • A negative result shifts subtitles earlier
    • A positive result shifts subtitles later
    • Formats may be mixed, e.g. 01:44:31,660-12700
    • This helps compute differences between timestamps from subtitles in different languages
  • Timestamp ratio, used for scaling timestamps, e.g. 01:44:30,290/01:44:31,660. subsync converts both timestamps to milliseconds and divides them, producing a floating-point scaling factor:

    • If the result is less than 1, subtitle intervals become shorter
    • If the result is greater than 1, subtitle intervals become longer
    • Formats may be mixed, e.g. 01:44:31,660/12700
    • Dividing the last subtitle’s time by the corresponding audio time is a quick way to obtain a scale factor
  • Note: When omitting hour/minute fields, be careful with seconds vs. milliseconds.

    For example, 20 means 20 milliseconds, not 20 seconds. 20,0 or 20.0 means 20 seconds.

  • Note: The value 20.0 is ambiguous and matches a scaling ratio, not a timestamp. Scaling has higher priority than offset. For example:

    subsync -20.0 -w target.ass source.ass
    

    This will enlarge the subtitle timing by 20×, not shift it earlier by 20 seconds.

    To shift by 20 seconds, use any of the following:

    subsync -20,0 -w target.ass source.ass
    subsync -20000 -w target.ass source.ass
    subsync -0:20 -w target.ass source.ass
    subsync -0:20.0 -w target.ass source.ass
    

HOWTO: Time Offset

Shifting timestamps is the most common operation: adding or subtracting a fixed value from subtitle timestamps causes the subtitles to appear later or earlier. Most subtitle misalignment issues occur because some content was added to or removed from the opening of the video. A simple timestamp offset can effectively correct this problem.

For example:

subsync +12000 < source.ass > target.ass

This increases all subtitle timestamps in source.ass by 12,000 milliseconds, causing every subtitle to appear 12 seconds later. In the parameter +12000, the + indicates an increase. Conversely, - indicates a decrease:

subsync -12000 < source.ass > target.ass

This decreases all timestamps by 12,000 milliseconds, causing every subtitle to appear 12 seconds earlier.

The time format may be an integer (milliseconds), or a standard HH:MM:SS format. Note that milliseconds in HH:MM:SS format appear in two different formats:

  • .srt: HH:MM:SS,mmm
  • .ass/.ssa: HH:MM:SS.nn See the earlier Time Formats section for details.

To simplify calculations, subsync supports timestamp arithmetic as the offset parameter. For example, you can pick any misaligned subtitle in the subtitle file, then find the correct line’s start time in the video, and subtract the subtitle timestamp from the correct video timestamp:

subsync +00:00:52,570-0:11:00,140 source.ass > target.ass

In this offset parameter +00:00:52,570-0:11:00,140:

  • The leading + is ignored; using - makes no difference
  • 00:00:52,570 is the correct start time of the dialogue in the video
View on GitHub
GitHub Stars46
CategoryContent
Updated19d ago
Forks5

Languages

SRecode Template

Security Score

90/100

Audited on Mar 10, 2026

No findings