annotate TOOLS/subedit.pl @ 35270:5816c9e25d29

Error out if an invalid channel list name was specified instead of continuing and reading outside array bounds all over the place.
author reimar
date Tue, 06 Nov 2012 21:48:43 +0000
parents 92a795af2600
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12686
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
1 #!/usr/bin/perl -w
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
2
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
3 # A script for pipelined editing of subtitle files.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
4 # Copyright (C) 2004 Michael Klepikov <mike72@mail.ru>
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
5 #
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
6 # Version 1.0 initial release 28-Mar-04
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
7 #
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
8 # Comments, suggestions -- send me an mail, but the recommended way is
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
9 # to enhance/fix on your own and submit to the distribution;)
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
10 # If you like, I can review the fixes.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
11 #
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
12 # This script is free software; you can redistribute it and/or
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
13 # modify it under the terms of the GNU Lesser General Public
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
14 # License as published by the Free Software Foundation; either
25542
92a795af2600 Fix license header to read Lesser General Public License 2.1,
diego
parents: 17367
diff changeset
15 # version 2.1 of the License, or (at your option) any later version.
12686
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
16 # Retain original credits when modifying.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
17 #
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
18 # This script is distributed in the hope that it will be useful,
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
21 # Lesser General Public License for more details.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
22 #
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
23 # You should have received a copy of the GNU Lesser General Public
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
24 # License along with this library; if not, write to the Free Software
17367
401b440a6d76 Update licensing information: The FSF changed postal address.
diego
parents: 12686
diff changeset
25 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12686
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
26 #
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
27
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
28 use Math::BigInt;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
29
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
30 # Constants
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
31 my $FMT_UNKNOWN = 0;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
32 my $FMT_SRT = 1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
33
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
34 # Argument values
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
35 my $DEBUG = 0;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
36 my $inFormat;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
37 my $outFormat;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
38 my $shiftMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
39 my $scaleMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
40 my $splitFromMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
41 my $splitToMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
42
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
43 ## Process command line
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
44 while (defined ($argVal = shift)) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
45 if ($argVal eq "-d" || $argVal eq "--debug") {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
46 $DEBUG = 1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
47 } elsif ($argVal eq "-if" || $argVal eq "--input-format") {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
48 $inFormat = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
49 usage ("Must specify input format") if ! $inFormat;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
50 if ($inFormat =~ /^srt/i) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
51 $inFormat = $FMT_SRT;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
52 } else {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
53 usage ("Invalid input format");
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
54 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
55 } elsif ($argVal eq "-of" || $argVal eq "--output-format") {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
56 $outFormat = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
57 usage ("Must specify input format") if ! $outFormat;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
58 if ($outFormat =~ /^srt/i) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
59 $outFormat = $FMT_SRT;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
60 } else {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
61 usage ("Invalid output format");
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
62 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
63 } elsif ($argVal eq "-s" || $argVal eq "--shift") {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
64 my $argTime = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
65 if (! defined $argTime ||
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
66 ! defined ($shiftMilli = getTimeMillis ($argTime))) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
67 usage ("Invalid shift time value");
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
68 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
69 } elsif ($argVal eq "-c" || $argVal eq "--scale") {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
70 my $argTime = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
71 if (! defined $argTime ||
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
72 ! defined ($scaleMilli = getTimeMillis ($argTime))) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
73 usage ("Invalid scale time value");
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
74 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
75 } elsif ($argVal eq "-f" || $argVal eq "--split-from") {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
76 my $argTime = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
77 if (! defined $argTime ||
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
78 ! defined ($splitFromMilli = getTimeMillis ($argTime))) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
79 usage ("Invalid split start time value");
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
80 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
81 } elsif ($argVal eq "-t" || $argVal eq "--split-to") {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
82 my $argTime = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
83 if (! defined $argTime ||
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
84 ! defined ($splitToMilli = getTimeMillis ($argTime))) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
85 usage ("Invalid split end time value");
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
86 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
87 } elsif ($argVal eq "-h" || $argVal eq "--help") {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
88 usage ();
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
89 } else {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
90 usage ("Unrecognized argument $argVal");
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
91 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
92 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
93
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
94 # Input format defaults to SRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
95 $inFormat = $FMT_SRT if (! defined $inFormat);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
96 # Output format defaults to the same as input
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
97 $outFormat = $inFormat if (! defined $outFormat);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
98
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
99 ## Read
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
100
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
101 my $subs;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
102 if ($inFormat == $FMT_SRT) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
103 $subs = readSRT (*STDIN);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
104 printf STDERR ("Read %d SRT subs\n", scalar @{$subs}) if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
105 # Sort by start time
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
106 @{$subs} = sort {$a -> {srtStartTime} <=> $b -> {srtEndTime}} @{$subs};
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
107 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
108
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
109 ## Transform
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
110
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
111 if (defined $shiftMilli && 0 != $shiftMilli) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
112 printf STDERR ("Shift: %d milliseconds\n", $shiftMilli) if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
113 shiftSRT ($subs, $shiftMilli);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
114 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
115
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
116 if (defined $splitFromMilli || defined $splitToMilli) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
117 if ($DEBUG) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
118 my $printFrom = (defined $splitFromMilli) ? $splitFromMilli : "-";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
119 my $printTo = (defined $splitToMilli) ? $splitToMilli : "-";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
120 printf STDERR ("Split: from $printFrom to $printTo\n");
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
121 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
122 splitSRT ($subs, $splitFromMilli, $splitToMilli);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
123 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
124
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
125 if (defined $scaleMilli && 0 != $scaleMilli) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
126 my $lastSubIdx = scalar @{$subs} - 1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
127 if ($lastSubIdx >= 0) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
128 my $lastTimeOrig = $subs -> [$lastSubIdx] -> {srtEndTime};
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
129 if ($lastTimeOrig == 0) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
130 die "Cannot scale when last subtitle ends at 00:00:00,000";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
131 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
132 my $lastTimeScaled = $lastTimeOrig + $scaleMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
133 printf STDERR ("Scale: %d/%d\n", $lastTimeScaled, $lastTimeOrig) if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
134 scaleSRT ($subs, $lastTimeScaled, $lastTimeOrig);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
135 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
136 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
137
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
138 ## Write
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
139 if ($outFormat == $FMT_SRT) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
140 writeSRT (*STDOUT, $subs);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
141 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
142
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
143 # Close STDOUT, as recommended by Perl manual
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
144 # (allows diagnostics on disc overflow, etc.)
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
145 close (STDOUT) || die "Cannot close output stream: $!";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
146
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
147 exit 0;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
148
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
149 ## Subroutines
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
150
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
151 # Convert string time format to milliseconds
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
152 # SRT style: "01:20:03.251", and "," is allowed instead of "."
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
153 # Return undef in case of format error
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
154 sub getTimeMillis
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
155 {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
156 $_ = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
157 my $millis = 0;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
158
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
159 if (/\s*(.*)[\.,]([0-9]+)?\s*$/) { # Fraction; strip surrounding spaces
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
160 #print STDERR "frac: \$1=$1 \$2=$2\n" if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
161 $_ = $1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
162 $millis += ("0." . $2) * 1000 if $2;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
163 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
164 if (/(.*?)([0-9]+)$/) { # Seconds
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
165 #print STDERR "secs: \$1=$1 \$2=$2\n" if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
166 $_ = $1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
167 $millis += $2 * 1000 if $2;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
168 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
169 if (/(.*?)([0-9]+):$/) { # Minutes
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
170 #print STDERR "mins: \$1=$1 \$2=$2\n" if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
171 $_ = $1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
172 $millis += $2 * 60000 if $2;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
173 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
174 if (/(.*?)([0-9]+):$/) { # Hours
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
175 #print STDERR "mins: \$1=$1 \$2=$2\n" if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
176 $_ = $1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
177 $millis += $2 * 3600000 if $2;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
178 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
179 if (/(.*?)\-$/) { # Minus sign
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
180 $_ = $1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
181 $millis *= -1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
182 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
183 $millis = undef if (! /^$/); # Make sure we ate everything up
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
184 if ($DEBUG) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
185 if (defined $millis) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
186 #print STDERR "time value match: $millis ms\n";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
187 } else {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
188 #print STDERR "time mismatch\n";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
189 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
190 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
191 return $millis;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
192 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
193
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
194 # Convert milliseconds to SRT formatted string
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
195 sub getTimeSRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
196 {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
197 my $t = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
198 my $tMinus = "";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
199 if ($t < 0) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
200 $t = -$t;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
201 $tMinus = "-";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
202 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
203 my $tMilli = $t % 1000;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
204 $t /= 1000;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
205 my $tSec = $t % 60;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
206 $t /= 60;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
207 my $tMin = $t % 60;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
208 $t /= 60;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
209 my $tHr = $t;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
210 return sprintf ("%s%02d:%02d:%02d,%03d",
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
211 $tMinus, $tHr, $tMin, $tSec, $tMilli);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
212 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
213
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
214 # Read SRT subtitles
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
215 sub readSRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
216 {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
217 local *IN = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
218 my $subs = [];
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
219
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
220 $_ = <IN>;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
221 print STDERR "Undefined first line\n" if ! defined $_ && $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
222 my $lineNo = 1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
223 READ_SUBS:
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
224 while (defined $_) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
225 # Each loop iteration reads one subtitle from <IN>
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
226 my $sub = {};
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
227
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
228 # print STDERR "Reading line $lineNo\n" if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
229
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
230 # Skip empty lines
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
231 while (/^\s*$/) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
232 last READ_SUBS if ! ($_ = <IN>);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
233 ++$lineNo;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
234 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
235
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
236 # Subtitle number
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
237 if (/^\s*([0-9]+)\s*$/) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
238 $sub -> {srtNumber} = $1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
239 # print "SRT num: $1\n" if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
240 } else {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
241 die "Invalid SRT format at line $lineNo";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
242 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
243
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
244 # Timing
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
245 if ($_ = <IN>) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
246 ++$lineNo;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
247 } else {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
248 die "Unexpected end of SRT stream at line $lineNo";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
249 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
250 # print STDERR "LINE: $_\n" if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
251 if (/^\s*(\S+)\s*--\>\s*(\S+)\s*$/) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
252 my $startMillis = getTimeMillis ($1);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
253 my $endMillis = getTimeMillis ($2);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
254 die "Invalid SRT timing format at line $lineNo: $_"
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
255 if ! defined $startMillis || ! defined $endMillis;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
256 $sub -> {srtStartTime} = $startMillis;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
257 $sub -> {srtEndTime} = $endMillis;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
258 } else {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
259 die "Invalid SRT timing format at line $lineNo: $_";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
260 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
261
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
262 # Text lines
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
263 my $subLines = [];
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
264 while (1) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
265 last if ! ($_ = <IN>); # EOF ends subtitle
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
266 ++$lineNo;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
267 last if /^\s*$/; # Empty line ends subtitle
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
268 ($_ = $_) =~ s/\s+$//; # Strip trailing spaces
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
269 push @{$subLines}, $_;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
270 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
271 die "No text in SRT subtitle at line $lineNo" if 0 == scalar @{$subLines};
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
272 $sub -> {lines} = $subLines;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
273
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
274 # Append subtitle to the list
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
275 push @{$subs}, $sub;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
276 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
277 print STDERR "SRT read ok, $lineNo lines\n" if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
278
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
279 return $subs;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
280 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
281
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
282 # Write SRT subtitles
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
283 sub writeSRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
284 {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
285 use integer; # For integer division
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
286 local *OUT = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
287 my $subs = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
288
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
289 my $subNum = 0;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
290 foreach (@{$subs}) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
291 ++$subNum;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
292
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
293 my $sub = $_;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
294 my $sTimeSRT = getTimeSRT ($sub -> {srtStartTime});
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
295 my $eTimeSRT = getTimeSRT ($sub -> {srtEndTime});
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
296 printf OUT ("%d\n%s --> %s\n", $subNum, $sTimeSRT, $eTimeSRT);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
297 foreach (@{$sub -> {lines}}) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
298 printf OUT ("%s\n", $_);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
299 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
300 printf OUT "\n";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
301 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
302 printf STDERR ("Wrote %d SRT subs\n", $subNum) if $DEBUG;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
303 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
304
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
305 # Shift SRT subtitles by a given number of seconds.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
306 # The number may be negative and fractional.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
307 sub shiftSRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
308 {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
309 use integer; # $shiftMilli could be passed as float
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
310 my $subs = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
311 my $shiftMilli = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
312
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
313 foreach (@{$subs}) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
314 $_ -> {srtStartTime} += $shiftMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
315 $_ -> {srtEndTime} += $shiftMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
316 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
317 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
318
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
319 # Multiply each subtitle timing by a divident and divide by divisor.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
320 # The idea is that the divident is usually the new total number of
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
321 # milliseconds in the subtitle file, and the divisor is the old
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
322 # total number of milliseconds in the subtitle file.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
323 # We could simply use a double precision real coefficient instead of
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
324 # integer divident and divisor, and that could be good enough, but
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
325 # using integer arithmetics *guarantees* precision up to the last
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
326 # digit, so why settle for good enough when we can have a guarantee.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
327 #
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
328 # Uses Math::BigInt arithmetics, because it works with numbers
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
329 # up to (total number of milliseconds for a subtitle timing)^2,
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
330 # which could be on the order of approximately 1e+13, which is
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
331 # larger than maximum 32-bit integer.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
332 # There is a performance loss when using BigInt vs. regular floating
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
333 # point arithmetics, but the actual performance is quite acceptable
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
334 # on files with a few thousand subtitles.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
335 sub scaleSRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
336 {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
337 use integer; # Divident and divisor could be passed as floats, truncate
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
338 my $subs = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
339 my $scaleDividend = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
340 my $scaleDivisor = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
341
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
342 foreach (@{$subs}) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
343 my $ss = Math::BigInt -> new ($_ -> {srtStartTime});
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
344 $ss = $ss -> bmul ($scaleDividend);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
345 $_ -> {srtStartTime} = $ss -> bdiv ($scaleDivisor) -> bsstr ();
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
346 my $se = Math::BigInt -> new ($_ -> {srtEndTime});
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
347 $se = $se -> bmul ($scaleDividend);
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
348 $_ -> {srtEndTime} = $se -> bdiv ($scaleDivisor) -> bsstr ();
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
349 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
350 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
351
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
352 # Extract a fragment within a given time interval
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
353 # Either "from" or "to" may be undefined
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
354 sub splitSRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
355 {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
356 use integer; # fromMilli and toMilli could be passed as floats, truncate
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
357 my $subs = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
358 my $fromMilli = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
359 my $toMilli = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
360
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
361 my $iSub = 0;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
362 while ($iSub < scalar @{$subs}) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
363 $_ = $subs -> [$iSub];
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
364 my $keep = 0;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
365 if (! defined $fromMilli || $_ -> {srtEndTime} >= $fromMilli) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
366 # The subtitle ends later than the start boundary
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
367
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
368 # Fix overlapping start timing,
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
369 # but only of the start boundary is not infinite (undef)
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
370 if (defined $fromMilli && $_ -> {srtStartTime} < $fromMilli) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
371 $_ -> {srtStartTime} = $fromMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
372 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
373 if (! defined $toMilli || $_ -> {srtStartTime} <= $toMilli) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
374 # The subtitle begins earlier than the end boundary
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
375
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
376 # Fix overlapping end timing,
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
377 # but only of the end boundary is not infinite (undef)
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
378 if (defined $toMilli && $_ -> {srtEndTime} > $toMilli) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
379 $_ -> {srtEndTime} = $toMilli;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
380 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
381
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
382 # All conditions met, all fixes done
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
383 $keep = 1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
384 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
385 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
386 if ($keep) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
387 ++$iSub;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
388 } else {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
389 splice @{$subs}, $iSub, 1;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
390 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
391 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
392 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
393
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
394 # Print brief usage help
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
395 # Accepts an optional error message, e.g. for errors parsing command line
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
396 sub usage
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
397 {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
398 my $msg = shift;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
399 my $exitCode = 0;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
400
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
401 if (defined $msg) {
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
402 $exitCode = 2;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
403 print STDERR "$msg\n";
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
404 }
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
405
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
406 print STDERR <<USAGE;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
407 Usage: $0 [switches]
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
408 -if,--input-format <fmt> input format; supported: SRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
409 default is SRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
410 -of,--output-format <fmt> output format; supported: SRT
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
411 default is same as input format
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
412 -s,--shift <time> shift all subtitles by <time>
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
413 (format: [-]hh:mm:ss,fraction)
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
414 -c,--scale <time> scale by adding <time> to overall duration
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
415 -f,--split-from <time> Drop subtitles that end before <time>
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
416 -t,--split-to <time> Drop subtitles that start after <time>
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
417 (will truncate timing if it overlaps a boundary)
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
418 -r,--renumber renumber SRT subtitles in output
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
419 -d,--debug enable debug output
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
420 -h,--help this help message
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
421
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
422 All times could be negative. Input/output may also contain negative timings,
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
423 which is sometimes useful for intermediate results.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
424 SRT subtitles are always renumbered on output.
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
425
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
426 EXAMPLES
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
427
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
428 Split subtitle file into two disks at a boundary of one hour 15 minutes:
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
429
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
430 subedit.pl --split-to 1:15:0 < all.srt > p1.srt
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
431 subedit.pl -f 1:15:0 < all.srt | subedit.pl --shift -1:15:0 > p2.srt
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
432
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
433 Join the previous two disks back into one file:
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
434
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
435 subedit.pl -s 1:15:00 < p2.srt | cat p1.srt - | subedit.pl > all.srt
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
436
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
437 Correct a situation where the first subtitle starts in sync with the video,
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
438 but the last one starts 3.5 seconds earlier than the speech in the video,
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
439 assuming the first subtitle timing is 00:01:05.030:
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
440
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
441 subedit.pl -s -1:5.03 | subedit.pl -c 3.5 | subedit.pl -s 1:5.03
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
442 USAGE
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
443
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
444 exit $exitCode;
cc5aa27a50ff simple subtitle editor by Michael Klepikov
alex
parents:
diff changeset
445 }