Browse Source

* Subtitle::Format::SRT : use generic events

master
Alex 'AdUser' Z 6 years ago
parent
commit
d68f329886
  1. 44
      lib/Subtitle/Format/SRT.pm
  2. 2
      lib/Subtitle/Format/SSA/Event.pm
  3. 14
      t/format-srt.t

44
lib/Subtitle/Format/SRT.pm

@ -4,6 +4,7 @@ use strict;
use warnings;
use utf8;
use Subtitle::Event;
use Subtitle::Utils qw(:string :timing);
use base 'Subtitle::Format';
@ -11,9 +12,8 @@ use base 'Subtitle::Format';
sub new {
my ($class, %args) = @_;
my $self = {
debug => 0,
eol => "\n",
%args,
debug => $args{debug} || 0,
eol => $args{eol} || "\n",
events => [],
log => [],
timing_fmt => "%02d:%02d:%02d,%03d",
@ -22,7 +22,7 @@ sub new {
return bless($self, $class);
}
sub new_event { return +{ id => undef, timing => undef, text => undef }; }
sub new_event { return Subtitle::Event->new; }
sub parse {
my ($self, $lines) = @_;
@ -41,25 +41,26 @@ sub parse {
next;
}
# expected: timing
if ($line and $event and not $event->{timing}) {
if ($line and $event and not ($event->t_start or $event->t_end)) {
$self->log(debug => "Expecting timing line at $linenum");
my $timing = [];
my @t;
my ($start, $end, $rest) = ($line =~ m/(\S+)\s*-->\s*(\S+)(.*)/o);
unless ($start and $end) {
$self->log(warn => "Expected timing but found `$line` at $linenum, skipped");
next;
}
$timing->[0] = parse_timing($start);
unless ($timing->[0] >= 0) {
$t[0] = parse_timing($start);
unless ($t[0] >= 0) {
$self->log(warn => "Can't parse timing at line $linenum: $start");
next;
}
$timing->[1] = parse_timing($end);
unless ($timing->[1] >= 0) {
$t[1] = parse_timing($end);
unless ($t[1] >= 0) {
$self->log(warn => "Can't parse timing at line $linenum: $end");
next;
}
$event->{timing} = $timing;
$event->t_start($t[0]);
$event->t_end ($t[1]);
trim($rest);
next unless $rest;
# extension: timing
@ -102,17 +103,18 @@ sub parse {
next;
}
# expected: event text
if ($line and $event and $event->{timing}) {
if ($line and $event and ($event->t_start or $event->t_end)) {
trim($line);
$self->log(debug => "Text line at $linenum -> append");
$event->{text} //= '';
$event->{text} .= $self->{eol} if $event->{text};
$event->{text} .= $line;
my $text = $event->text;
$text .= $self->{eol} if $text;
$text .= $line;
$event->text($text);
next;
}
} # foreach @lines
# finalize last event
if ($event and $event->{timing} and $event->{text}) {
if ($event and $event->text and ($event->t_start or $event->t_end)) {
push @{ $self->{events} }, $event;
}
@ -125,12 +127,10 @@ sub build {
foreach my $e (@{ $self->{events} }) {
push @lines, $e->{id};
my $start = sprintf $self->{timing_fmt},
make_timing($e->{timing}->[0]);
my $end = sprintf $self->{timing_fmt},
make_timing($e->{timing}->[1]);
push @lines, sprintf("%s --> %s", $start, $end);
push @lines, $e->{text};
my $start = sprintf $self->{timing_fmt}, make_timing($e->t_start);
my $end = sprintf $self->{timing_fmt}, make_timing($e->t_end);
push @lines, sprintf "%s --> %s", $start, $end;
push @lines, $e->text;
push @lines, "";
}

2
lib/Subtitle/Format/SSA/Event.pm

@ -4,7 +4,7 @@ use strict;
use warnings;
use utf8;
use base 'Subtitle::Format::SSA::Record';
use base qw(Subtitle::Event Subtitle::Format::SSA::Record);
my @FIELDS_SSA = qw(marked start end style name marginl marginr marginv effect text);
my @FIELDS_ASS = qw(layer start end style name marginl marginr marginv effect text);

14
t/format-srt.t

@ -7,7 +7,7 @@ use Subtitle::Format::SRT;
my $srt = Subtitle::Format::SRT->new(debug => 1);
is(ref $srt, 'Subtitle::Format::SRT');
can_ok($srt, qw(new parse));
can_ok($srt, qw(new parse build));
my $sample = <<"EOF";
1
@ -25,11 +25,11 @@ my $cnt = $srt->from_string($sample);
is($cnt, 2);
my @events = @{ $srt->{events} };
is($events[0]->{timing}->[0], 0.1);
is($events[0]->{timing}->[1], 8.0);
is($events[0]->{text}, "<i>kirari hikaru yume o taisetsu ni dakishimete\n</i>");
is($events[1]->{timing}->[0], 8.1);
is($events[1]->{timing}->[1], 12.0);
is($events[1]->{text}, "<i>ippo dzutsu aruite yukou\n</i>");
is($events[0]->t_start, 0.1);
is($events[0]->t_end, 8.0);
is($events[0]->text, "<i>kirari hikaru yume o taisetsu ni dakishimete\n</i>");
is($events[1]->t_start, 8.1);
is($events[1]->t_end, 12.0);
is($events[1]->text, "<i>ippo dzutsu aruite yukou\n</i>");
exit 0;

Loading…
Cancel
Save