diff options
author | James Bottomley <JBottomley@Parallels.com> | 2013-07-03 17:11:37 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-07-03 17:33:27 -0700 |
commit | c740c47627fd22b12dc25a6e556414b8d54d3fe5 (patch) | |
tree | 629c57f86dd6a3846b01505710b1115583809616 | |
parent | b1cd1f266417ec374f7d73d59a2501f789986048 (diff) | |
download | get-flash-videos-c740c47627fd22b12dc25a6e556414b8d54d3fe5.tar.gz |
F4VDownloader: Update for large boxes
The spec file actually defines a large box type which wasn't implemented in
the original F4VDownloader, leading it to fail on the new Channel4 F4V
streams. Fix by adding support for this. Also update the methods to be non
class, since they don't use any object data.
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | lib/FlashVideo/F4VDownloader.pm | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/lib/FlashVideo/F4VDownloader.pm b/lib/FlashVideo/F4VDownloader.pm index 0ca6a46..1b7ce14 100644 --- a/lib/FlashVideo/F4VDownloader.pm +++ b/lib/FlashVideo/F4VDownloader.pm @@ -38,20 +38,30 @@ use Data::AMF::Parser::AMF0; sub read_box_header { - my ($self, $s, $a) = @_; + my ($s, $a) = @_; + my $s_len = length($s); ($a->{len}, $a->{type}) = unpack('L>A4', $s); + $s = substr($s, 8); + $a->{headlen} = 8; + if ($a->{len} == 1) { + debug "LARGE BOX"; + # large box size + ($a->{len}) = unpack('Q>', $s); + $s = substr($s, 8); + $a->{headlen} += 8; + } debug "box header, size ".$a->{len}." type ".$a->{type}; - die "string not big enough (".length($s)." but should be >= ".$a->{len} if ($a->{len} > length($s)); - return substr($s, 8); + die "string not big enough (".$s_len." but should be >= ".$a->{len} if ($a->{len} > $s_len); + return $s; } sub read_segment_runtable { - my ($self, $s, $a) = @_; + my ($s, $a) = @_; my ($len, $totlen); - $s = $self->read_box_header($s, $a); + $s = read_box_header($s, $a); die "found wrong box ".$a->{type}." expecting asrt" if ($a->{type} ne 'asrt'); - $totlen = 8; + $totlen = $a->{headlen}; ($a->{version}, $a->{flags}, $a->{qualityentrycount}, @@ -86,11 +96,11 @@ sub read_segment_runtable { } sub read_fragment_runtable { - my ($self, $s, $a) = @_; + my ($s, $a) = @_; my ($len, $totlen); - $s = $self->read_box_header($s, $a); + $s = read_box_header($s, $a); die "found wrong box ".$a->{type}." expecting afrt" if ($a->{type} ne 'afrt'); - $totlen = 8; + $totlen = $a->{headlen}; ($a->{version}, $a->{flags}, $a->{timescale}, @@ -134,14 +144,14 @@ sub read_fragment_runtable { } sub read_bootstrap_box { - my ($self, $s) = @_; + my ($s) = @_; my $bb = {}; - $s = $self->read_box_header($s, $bb); - + $s = read_box_header($s, $bb); + die "found wrong box ".$bb->{type}." expecting abst" if ($bb->{type} ne 'abst'); my ($len, $totlen, $packedbit); - $totlen = 8; + $totlen = $bb->{headlen}; ($bb->{version}, $bb->{flags}, $bb->{bootstrapinfoversion}, @@ -186,7 +196,7 @@ sub read_bootstrap_box { my $i; for ($i = 0; $i < $bb->{segmentruntablecount}; $i++) { my $seg = {}; - $s = $self->read_segment_runtable($s, $seg); + $s = read_segment_runtable($s, $seg); push $bb->{segmentruntable},$seg; $totlen += $seg->{len}; } @@ -196,7 +206,7 @@ sub read_bootstrap_box { $bb->{fragmentruntable} = [()]; for ($i = 0; $i < $bb->{segmentruntablecount}; $i++) { my $seg = {}; - $s = $self->read_fragment_runtable($s, $seg); + $s = read_fragment_runtable($s, $seg); push $bb->{fragmentruntable},$seg; $totlen += $seg->{len}; } @@ -317,7 +327,7 @@ sub download { info "Selected stream of resolution ".$media->{md}->{height}."x".$media->{md}->{width}." and bitrate ".$bitrate; $media->{bootstrapInfo} = $manifest->{bootstrapInfo}->{$media->{bootstrapInfoId}}; - my $bb = $self->read_bootstrap_box(decode_base64($media->{bootstrapInfo}->{content})); + my $bb = read_bootstrap_box(decode_base64($media->{bootstrapInfo}->{content})); debug 'Parsed media bootstrap data is '.Dumper($bb); debug 'Parsed media metadata is '.Dumper($media); @@ -388,10 +398,10 @@ sub download { $bb = undef; while(length($s) > 0) { $a = {}; - $self->read_box_header($s, $a); + read_box_header($s, $a); die "Fragment $frag too short" if (length($s) < $a->{len}); - $bb = $self->read_bootstrap_box($s) if ($a->{type} eq 'abst'); - $dat = substr($s, 8, $a->{len} - 8) if ($a->{type} eq 'mdat'); + $bb = read_bootstrap_box($s) if ($a->{type} eq 'abst'); + $dat = substr($s, $a->{headlen}, $a->{len} - $a->{headlen}) if ($a->{type} eq 'mdat'); $s = substr($s, $a->{len}); } die "Didn't find the movie data box in fragment $frag" if (!defined($dat)); |