diff --git a/lib/Subtitle/MSub.pm b/lib/Subtitle/MSub.pm new file mode 100644 index 0000000..2582050 --- /dev/null +++ b/lib/Subtitle/MSub.pm @@ -0,0 +1,81 @@ +package Subtitle::MSub; + +use strict; +use warnings; +use feature qw(switch); +use utf8; + +use base 'Subtitle::BASE'; + +sub new { + my ($class, %args) = @_; + my $self = { + debug => 0, + eol => "\n", + fps => undef, + default_fps => 25.0, + convert_timing => 1, + %args, + events => [], + log => [], + }; + + return bless($self, $class); +} + +sub new_event { return +{ timing => undef, text => undef }; } + +sub parse { + my ($self, $lines) = @_; + my $linenum = 0; + my $event; + + foreach my $line (@$lines) { + $linenum++; + $line = $self->chomp($line); + $line = $self->trim($line); + next unless ($line); + my ($start, $end, $rest) = ($line =~ m/{(\d+)}\s*{(\d+)}\s*(.+)/o); + # expected: garbage + unless ($start and $end and $rest) { + $self->log(warn => "Unrecognized line at $linenum: $line"); + next; + } + # expected: valid line + # special case - set fps + if ($start == 1 and $end == 1) { + my ($fps) = ($rest =~ m/(\d+(?:\.\d+))/o); + unless ($fps) { + $self->log(error => "Expected fps at line $linenum, but found: $rest"); + next; + } + if ($fps and $self->{fps}) { + $self->log(warn => "Found fps line at $linenum, but fps already set before"); + next; + } + $self->log(debug => "Set fps to $fps and line $linenum"); + $self->{fps} = $fps; + next; + } + $rest =~ s/\|/$self->{eol}/og; + my $event = $self->new_event; + $event->{timing} = [$start, $end]; + $event->{text} = $self->trim($rest); + push @{ $self->{events} }, $event; + undef $event; + } + # set fps if none and recalc timing + $self->{fps} //= $self->{default_fps}; + return scalar @{ $self->{events} } + unless $self->{convert_timing}; + + $self->log(debug => "Converting frame numbers to time with fps $self->{fps}"); + foreach my $event (@{ $self->{events} }) { + $event->{timing}->[0] /= $self->{fps}; + $event->{timing}->[1] /= $self->{fps}; + } + + return scalar @{ $self->{events} }; +} + +1;