#!/usr/bin/perl
use warnings;
use strict;
use File::Temp qw(tempfile);
use File::Spec;
use Test::More tests => 12 + 2 * 18; # general tests + number of samples * test per sample
BEGIN
{
use_ok('FLV::Info');
}
my @samples = (
{
file => File::Spec->catfile('t', 'samples', 'flash6.flv'),
expect => {
video_codec => 'Sorenson H.263',
duration => '7418',
audio_format => 'MP3',
audio_type => 'stereo',
meta_framerate => '20',
has_video => 1,
has_audio => 1,
tags => 435,
video_tags => 149,
audio_tags => 285,
meta_tags => 1,
},
},
{
file => File::Spec->catfile('t', 'samples', 'flash8.flv'),
expect => {
video_codec => 'On2 VP6',
duration => '7418',
audio_format => 'MP3',
audio_type => 'stereo',
meta_framerate => '20',
has_video => 1,
has_audio => 1,
tags => 435,
video_tags => 149,
audio_tags => 285,
meta_tags => 1,
},
},
);
my @cleanup;
END
{
# Delete temp files
unlink $_ for @cleanup;
}
{
my $reader = FLV::Info->new();
eval { $reader->parse('nosuchfile.flv'); };
like($@, qr/Failed to read FLV file/, 'parse non-existent file');
my ($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
close $fh;
eval { $reader->parse($tempfilename); };
like($@, qr/Unexpected end of file/, 'parse empty file');
($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
print {$fh} 'foo';
close $fh;
eval { $reader->parse($tempfilename); };
like($@, qr/Unexpected end of file/, 'parse non-flv file');
($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
print {$fh} 'FLV';
close $fh;
eval { $reader->parse($tempfilename); };
like($@, qr/Unexpected end of file/, 'parse non-flv file');
($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
print {$fh} 'foo' x 1000;
close $fh;
eval { $reader->parse($tempfilename); };
like($@, qr/Not an FLV file/, 'parse long non-flv file');
($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
print {$fh} 'FLV'.pack 'CCN', 200, 0, 9;
close $fh;
eval { $reader->parse($tempfilename); };
like($@, qr/only understand FLV version 1/, 'parse badly versioned flv header');
($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
print {$fh} 'FLV'.pack 'CCN', 1, 128, 9;
close $fh;
eval { $reader->parse($tempfilename); };
like($@, qr/Reserved header flags are non-zero/, 'parse reserved-flag using flv header');
($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
print {$fh} 'FLV'.pack 'CCN', 1, 0, 8;
close $fh;
eval { $reader->parse($tempfilename); };
like($@, qr/Illegal value for body offset/, 'parse too-small length flv header');
($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
print {$fh} 'FLV'.pack 'CCNC', 1, 0, 10, 0;
close $fh;
eval { $reader->parse($tempfilename); };
like($@, qr/Unexpected end of file/, 'parse long flv header');
eval { $reader->get_file()->serialize(); };
like($@, qr/Please specify a filehandle/, 'serialize with no filehandle');
# Expect a failure with a warning
local $SIG{__WARN__} = sub{};
ok(!$reader->get_file()->serialize($fh), 'serialize with closed filehandle');
}
for my $sample (@samples)
{
# Read an FLV file and check selected metadata against expectations
my $reader = FLV::Info->new();
ok(!scalar $reader->get_info(), 'get_info');
$reader->parse($sample->{file});
ok(scalar $reader->get_info(), 'get_info');
ok($reader->report(), 'report');
my $flv = $reader->get_file();
is($flv->get_filename(), $sample->{file}, 'get_filename');
my %info = (
$reader->get_info(),
'has_video' => $flv->get_header()->has_video(),
'has_audio' => $flv->get_header()->has_audio(),
'tags' => scalar $flv->get_body()->get_tags(),
'video_tags' => scalar $flv->get_body()->get_video_frames(),
'audio_tags' => scalar $flv->get_body()->get_audio_packets(),
'meta_tags' => scalar $flv->get_body()->get_meta_tags(),
#'end_time' => $flv->get_body()->end_time(),
);
#use Data::Dumper;
#diag Dumper \%info;
#diag Dumper [$flv->get_body()->get_meta_tags()];
for my $key (sort keys %{$sample->{expect}})
{
is($info{$key}, $sample->{expect}->{$key}, $sample->{file}.' - '.$key);
}
# Write the FLV back out as a temp file
my ($fh, $tempfilename) = tempfile();
die if (! -f $tempfilename);
push @cleanup, $tempfilename;
ok($flv->serialize($fh), 'serialize');
close $fh;
# Read the temp file back and compare it to the original -- should
# be identical except for hash key ordering
my $rereader = FLV::Info->new();
$rereader->parse($tempfilename);
my $newflv = $rereader->get_file();
# remove filename properties which are guaranteed to differ
$flv->{filename} = undef;
$newflv->{filename} = undef;
is_deeply($newflv, $flv, 'compare re-serialized');
# read it again, this time via filehandle
open my $fh2, '<', $tempfilename or die;
binmode $fh2 or die;
$rereader->parse($fh2);
close $fh2;
is_deeply($newflv, $flv, 'compare re-serialized');
}