Alex 'AdUser' Z
10 years ago
1 changed files with 141 additions and 0 deletions
@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env perl |
||||
|
||||
use strict; |
||||
use warnings; |
||||
use feature qw(switch); |
||||
use lib 'lib'; |
||||
use utf8; |
||||
|
||||
use Getopt::Long; |
||||
use File::Slurp; |
||||
use Subtitle::SSA; |
||||
|
||||
sub usage { |
||||
my ($msg) = @_; |
||||
print $msg, "\n" if $msg; |
||||
print <<USAGE; |
||||
Usage: ssa-retime <mode> [<options>] -i <file> [ -o <file>] |
||||
|
||||
Modes are: |
||||
* framerate Retime whole file from one fps to another. |
||||
* points Retime file specifying point(s) & time shift for it. |
||||
* shift Shift whole file or it's part for given time. |
||||
|
||||
Common options: |
||||
-h This help. |
||||
-i <file> Input file. (mandatory). |
||||
-o <file> Output file. Default: write to stdout. |
||||
-v Be verbose. |
||||
|
||||
Specific options for 'shift' mode: |
||||
-S <string> Retime only events with specified style. |
||||
This option may be given more than once. |
||||
-s <time> Start time of period, that will be changed. |
||||
Default: first event. |
||||
-e <time> End time of period, that will be changed. |
||||
Default: the latest time found in file. |
||||
-l <time> Duration of period above. This option require '-s' |
||||
You may select either '-o' or '-e' at the same time. |
||||
-t <time> Change time for this value. |
||||
|
||||
Specific options for 'framerate' mode: |
||||
-f <float> Source framerate. Default: 25.0 fps. |
||||
-F <float> Target framerate. |
||||
|
||||
Specific options for 'points' mode: |
||||
-p <time>/<time> Point of fixup & time shift in it. Option can be |
||||
specified more than once. (see man for details) |
||||
Both args must be in form of [-][[h:]m:]s[.ms]. |
||||
USAGE |
||||
exit 1; |
||||
} |
||||
|
||||
########### init ################### |
||||
$| = 1; |
||||
|
||||
my $mode = shift @ARGV; |
||||
|
||||
my @points; |
||||
my %opts = ( loglevel => 0, inrate => 25.0 ); |
||||
#GetOptions("qvhi:o:S:f:F:p:t:s:e:l:", \%opts) |
||||
GetOptions( |
||||
'h|help' => \&usage, |
||||
'v|verbose+' => \$opts{loglevel}, |
||||
'i|infile=s' => \$opts{infile}, |
||||
'o|outfile=s' => \$opts{outfile}, |
||||
|
||||
'S|style=s' => \$opts{style}, |
||||
's|shiftstart=s'=> \$opts{shiftstart}, |
||||
'e|shiftend=s' => \$opts{shiftend}, |
||||
'l|shiftlen=f' => \$opts{shiftlen}, |
||||
|
||||
't|shifttime=f' => \$opts{shifttime}, |
||||
|
||||
'f|inrate=f' => \$opts{inrate}, |
||||
'F|outrate=f' => \$opts{outrate}, |
||||
|
||||
'p|point' => \@points, |
||||
); |
||||
|
||||
($opts{infile} and -f $opts{infile}) |
||||
or usage("Input file not exists"); |
||||
|
||||
given ($mode) { |
||||
when ('framerate') { |
||||
$opts{outrate} |
||||
or usage("You should set at least '-F' option in this mode"); |
||||
($opts{inrate} != 0.0 and $opts{outrate} != 0.0) |
||||
or usage("Framerate can't be zero"); |
||||
} |
||||
when ('shift') { |
||||
$opts{shifttime} |
||||
or usage("You should set '-t' option in this mode"); |
||||
(not $opts{shiftstart} or $opts{shiftstart} > 0.0) |
||||
or usage("Shift start must be positive time"); |
||||
(not $opts{shiftend} or $opts{shiftend} > 0.0) |
||||
or usage("Shift end must be positive time"); |
||||
(not $opts{shiftlen} or $opts{shiftlen} > 0.0) |
||||
or usage("Shift length must be positive time"); |
||||
} |
||||
when ('points') { |
||||
scalar(@points) |
||||
or usage("You should specify at least one shift point"); |
||||
foreach my $point (@points) { |
||||
... |
||||
} |
||||
} |
||||
default { |
||||
usage("Incorrect mode: $mode (see help below)"); |
||||
} |
||||
} |
||||
|
||||
my @lines = read_file($ARGV[0]); |
||||
my $ssa = Subtitle::SSA->new(debug => !!$opts{loglevel}); |
||||
$ssa->parse(\@lines); |
||||
|
||||
given ($mode) { |
||||
when ('framerate') { |
||||
my $mod = $opts{inrate} / $opts{outrate}; |
||||
foreach my $event ($ssa->events) { |
||||
$event->{start} *= $mod; |
||||
$event->{end} *= $mod; |
||||
} |
||||
} |
||||
when ('shift') { |
||||
my $style = $opts{style}; |
||||
my $start = $opts{shiftstart} // 0.0; |
||||
my $end = $opts{shiftend} // (($opts{shiftlen}) ? $start + $opts{shiftend} : undef); |
||||
my $mod = $opts{shifttime}; |
||||
foreach my $event ($ssa->events) { |
||||
next if ($style and $event->{style} ne $style); |
||||
next if ($start and $event->{start} < $start); |
||||
next if ($end and $event->{end} > $end); |
||||
$event->{start} += $mod; |
||||
$event->{end} += $mod; |
||||
} |
||||
} |
||||
when ('points') { |
||||
} |
||||
} |
||||
|
||||
exit 0; |
Loading…
Reference in new issue