#!/usr/local/bin/perl -w # This is subtitle-offset-modificator version 0.1, a simple script # that allows to change the timestamp of a Subtitle file. # # Web : http://thomas.enix.org/wakka.php?wiki=SubtitleOffsetModificator # # Copyright (C) 2004 Thomas Petazzoni # thomas.petazzoni@enix.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. if (($#ARGV+1) != 3) { die "Usage : subtitle-offset-modificator.pl infile outfile offset\n"; } open SUBTITLEIN, $ARGV[0] or die $ARGV[0] . " : " . $!; open SUBTITLEOUT, ">$ARGV[1]" or die $ARGV[1] . " : " . $!; my ($offset_direction, $offset_hour, $offset_min, $offset_sec, $offset_frame); if($ARGV[2] =~ m/^([\+\-]{0,1})([0-9]{2}):([0-9]{2}):([0-9]{2}),([0-9]{3})$/) { if($1 eq "+" || $1 eq "") { $offset_direction = 0; } else { $offset_direction = 1; } $offset_hour = $2; $offset_min = $3; $offset_sec = $4; $offset_frame = $5; } else { die "offset must be in the format hh:mm:ss,fff eventually with a minus sign before\n"; } if($offset_direction == 0) { print "Incrementing"; } else { print "Decrementing"; } print " from " . $offset_hour . "h " . $offset_min . "m " . $offset_sec . "s " . $offset_frame . " frames\n"; sub compute { my $initial_val = $_[0]; my $added_val = $_[1]; my $carry = $_[2]; my $max_val = $_[3]; my $decrement = $_[4]; my $ret_val; my $ret_carry; if($decrement == 0) { $ret_val = $initial_val + $added_val + $carry; $ret_carry = 0; if($ret_val > $max_val) { $ret_val -= ($max_val + 1); $ret_carry = 1; } } else { $ret_val = $initial_val - $added_val - $carry; $ret_carry = 0; if($ret_val < 0) { $ret_val += ($max_val + 1); $ret_carry = 1; } } return ($ret_val, $ret_carry); } while() { chomp; if(m/^([0-9]{2}):([0-9]{2}):([0-9]{2}),([0-9]{3}) --> ([0-9]{2}):([0-9]{2}):([0-9]{2}),([0-9]{3})$/) { ($frame_s, $carry) = compute($4, $offset_frame, 0, 999, $offset_direction); ($second_s, $carry) = compute($3, $offset_sec, $carry, 59, $offset_direction); ($minute_s, $carry) = compute($2, $offset_min, $carry, 59, $offset_direction); ($hour_s, $carry) = compute($1, $offset_hour, $carry, 23, $offset_direction); if($carry != 0) { die "Overflow !\n"; } ($frame_e, $carry) = compute($8, $offset_frame, 0, 999, $offset_direction); ($second_e, $carry) = compute($7, $offset_sec, $carry, 59, $offset_direction); ($minute_e, $carry) = compute($6, $offset_min, $carry, 59, $offset_direction); ($hour_e, $carry) = compute($5, $offset_hour, $carry, 23, $offset_direction); if($carry != 0) { die "Overflow !\n"; } printf(SUBTITLEOUT "%.2d:%.2d:%.2d,%.3d --> %.2d:%.2d:%.2d,%.3d\n", $hour_s, $minute_s, $second_s, $frame_s, $hour_e, $minute_e, $second_e, $frame_e); } else { print SUBTITLEOUT $_ . "\n"; } }