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

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

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

Loading…
Cancel
Save