Synchronize SRT - Offset subtitle files

Here is a simple Java code for synchronizing (offset forward or backward) any .SRT subtitles file.

/**
* (c) 2009 by SCC
* 
* FREE-version. Anybody can do anything with this code.
* Enjoy it!
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* The class SyncSRTSubtitles reads a subtitles .SRT file and offsets all the
* timestamps with the same specific value in msec.
* 
* The format of the .SRT file is like this:
* 
* 123
* 00:11:23,456 --> 00:11:25,234
* subtitle #123 text here
* 
* 
* @author Sorinel CRISTESCU
*/
public class SyncSRTSubtitles {

/**
* Entry point in the program.
* 
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {

/* INPUT: offset value: negative = less (-) ... positive = more (+). */
long delta = (22 * 1000L + 000); /* msec */


/* INPUT: source & destination files */
String srcFileNm = "L:/DivX/Movies/TheMask.en.srt";
String destFileNm = "L:/DivX/Movies/TheMask.srt";


/* offset algorithm: START */
File outFile = new File(destFileNm);
outFile.createNewFile();
FileWriter ofstream = new FileWriter(outFile);
BufferedWriter out = new BufferedWriter(ofstream);

/* Open the file that is the first command line parameter */
FileInputStream fstream = new FileInputStream(srcFileNm);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;

/* Read File Line By Line */
while ((strLine = br.readLine()) != null) {
   String[] atoms = strLine.split(" --> ");
   if (atoms.length == 1)
      out.write(strLine + "\n");
   else {
      String startTS = atoms[0];
      String endTS = atoms[1];
      out.write(offsetTime(startTS, delta) + " --> "
                + offsetTime(endTS, delta) + "\n");
   }
}

/* Close the input streams */
in.close();
out.close();

/* offset algorithm: END */
System.out.println("DONE! Check the rsult oin the file: " + destFileNm);
}

/**
* Computes the timestamp offset.
* 
* @param ts
*            String value of the timestamp in format: "hh:MM:ss,mmm"
* @param delta
*            long value of the offset in msec (positive or negative).
* @return String with the new timestamp representation.
*/
private static String offsetTime(String ts, long delta) {
  long tsMsec = 0;
  String atoms[] = ts.split("\\,");
  if (atoms.length == 2) {
    tsMsec += Integer.parseInt(atoms[1]);
  }
  atoms = atoms[0].split(":");
  tsMsec += Integer.parseInt(atoms[2]) * 1000L; /* seconds */
  tsMsec += Integer.parseInt(atoms[1]) * 60000L; /* minutes */
  tsMsec += Integer.parseInt(atoms[0]) * 3600000L; /* hours */
  tsMsec += delta; /* here we do the offset. */

  long h = tsMsec / 3600000L;
  String result = get2digit(h, 2) + ":";

  long r = tsMsec % 3600000L;
  long m = r / 60000L;
  result += get2digit(m, 2) + ":";

  r = r % 60000L;
  long s = r / 1000L;
  result += get2digit(s, 2) + ",";

  result += get2digit(r % 1000L, 3);

  return result;
}

/**
* Gets the string representation of the number, adding the prefix '0' to
* have the required length.
* 
* @param n
*            long number to convert to string.
* @param digits
*            int number of digits required.
* @return String with the required length string (3 for digits = 3 -->
*         "003")
*/
private static String get2digit(long n, int digits) {
  String result = "" + n;
  while (result.length() < digits) {
     result = "0" + result;
  }
  return result;
}

}
Cheers!
 
 
PS: Thanks to RMBS Rock's request, I built an executable JAR file to easily use this algorithm. You can download it HERE. To execute it you need to have Java JRE installed on your computer.
 
 
 
 

4 comments:

  1. Hi man. Why don´t you do it with JFrame (GUI) for people Synchronize SRT any *.srt?

    ReplyDelete
  2. yes, i can ... but i am lazy to make it executable app ... i can just make it an auto-executable jar, so you need java jre installed on your machine to be able to start it.
    - is this ok for you?

    ReplyDelete
  3. Yes. No problem for me. My blog about Java too https://isjavado.wordpress.com/contents/

    ReplyDelete
    Replies
    1. Hello, there you go, you have your executable JAR to use it.

      Cheers!

      PS: send me some feedback, if you get any issue, please.

      Delete