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;