#!/usr/bin/env perl
# vim:ts=3:sw=3:et:co=80
# Walter Doekes (2005)


### Welcome message

print "srtresync - An srt subtitle file time resync utility\n";
print "Public Domain, Walter Doekes, 2005\n";
print "\n";
print "Reads the srt supplied on the command line,\n";
print "reads a time found in the srt from stdin,\n";
print "reads a the time that should've been in the srt,\n";
print "(this for two values, so the time can be linearly stretched),\n";
print "and outputs a new srt.\n";
print "\n";

### Read arguments, open IO files

@ARGV >= 2 or die "usage: $0 <input> <output> [-f]";
open INPUT, "< $ARGV[0]" or
   die "can't open ``$ARGV[0]'' for reading: $!";
$ARGV[2] eq '-f' or open OUTPUT, "< $ARGV[1]" and
   die "output file ``$ARGV[1]'' exits: use -f to overwrite";
open OUTPUT, "> $ARGV[1]" or
   die "can't open ``$ARGV[1]'' for writing: $!";

### Read data

print "Supply two times in the srt time format (xx:xx:xx,xxx) and " .
   "their correct time:\n";
my %TIMES;
for(my $i = 0; $i < 2; ++$i) {
   print "Input file time $i: ";
   $TIMES{'file'.$i} = <STDIN>;
   $TIMES{'file'.$i} =~ /^((\d{2}:){2}\d{2},\d{3})\r?\n?$/ or
      die "incorrect time format";
   $TIMES{'file'.$i} = srt_to_time($1);
   print "Time $i ($1) should be: ";
   $TIMES{'correct'.$i} = <STDIN>;
   $TIMES{'correct'.$i} =~ /^((\d{2}:){2}\d{2},\d{3})\r?\n?$/ or
      die "incorrect time format";
   $TIMES{'correct'.$i} = srt_to_time($1);
   $TIMES{'diff'.$i} = $TIMES{'correct'.$i} - $TIMES{'file'.$i}
}

### Functions

sub srt_to_time {
   my $in = shift;
   $in =~ /^(\d{2}):(\d{2}):(\d{2}),(\d{3})$/ or die $in;
   return $1 * 3600 + $2 * 60 + $3 + $4 / 1000.0;
}
sub time_to_srt {
   my $in = shift;
   return sprintf("%02i:%02i:%02i,%03i", $in / 3600, ($in % 3600) / 60,
      ($in % 60), ($in - int($in)) * 1000);
}

### Calculate factors for file and correct

$TIMES{'file_factor'} = $TIMES{'file1'} - $TIMES{'file0'};
$TIMES{'correct_factor'} = $TIMES{'correct1'} - $TIMES{'correct0'};
# usage:
# $x = ($time - $TIMES{'file0'}) / $TIMES{'file_factor'}
# $out = ($x * $TIMES{'correct_factor'}) + $TIMES{'correct0'}

### Read the SRT and output correct values

for(<INPUT>) {
   if(/^(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})(\r?\n?)$/) {
      $x0 = (srt_to_time($1) - $TIMES{'file0'}) / $TIMES{'file_factor'};
      $x1 = (srt_to_time($2) - $TIMES{'file0'}) / $TIMES{'file_factor'};
      $out0 = $x0 * $TIMES{'correct_factor'} + $TIMES{'correct0'};
      $out1 = $x1 * $TIMES{'correct_factor'} + $TIMES{'correct0'};
      print OUTPUT time_to_srt($out0) . " --> " . time_to_srt($out1) . $3;
   } else {
      print OUTPUT $_;
   }
}
