App-MHFS
view release on metacpan or search on metacpan
lib/MHFS/Plugin/GetVideo.pm view on Meta::CPAN
$framecnt = unpack('C', substr($data, 0, 1, ''))+1;
my $firstframessize = 0;
for(my $i = 0; $i < ($framecnt-1); $i++) {
my $fsize = 0;
while(1) {
my $val = unpack('C', substr($data, 0, 1, ''));
$fsize += $val;
last if($val < 255);
}
push @sizes, $fsize;
$firstframessize += $fsize;
}
push @sizes, (length($data) - $firstframessize);
}
# EBML
elsif($lacing == 0x6) {
$framecnt = unpack('C', substr($data, 0, 1, ''))+1;
my $last = read_and_parse_vint_from_buf(\$data);
push @sizes, $last;
my $sum = $last;
for(my $i = 0; $i < ($framecnt - 2); $i++) {
my $width;
my $offset = read_and_parse_vint_from_buf(\$data, \$width);
# multiple by 2^bitwidth - 1 (with adjusted bitwidth)
my $desiredbits = (8 * $width) - ($width+1);
my $subtract = (1 << $desiredbits) - 1;
my $result = $offset - $subtract;
$last += $result;
say "offset $offset width $width factor: " . sprintf("0x%X ", $subtract) . "result $result evaled $last";
push @sizes, $last;
$sum += $last;
}
my $lastlast = length($data) - $sum;
say "lastlast $lastlast";
push @sizes, $lastlast;
}
# fixed
elsif($lacing == 0x4) {
$framecnt = unpack('C', substr($data, 0, 1, ''))+1;
my $framesize = length($data) / $framecnt;
for(my $i = 0; $i < $framecnt; $i++) {
push @sizes, $framesize;
}
}
# no lacing
else {
push @sizes, length($data);
}
return {
'trackno' => $trackno,
'rawts' => $rawts,
'rawflag' => $rawflag,
'frame_lengths' => \@sizes,
'data' => $data,
'ts' => unpack('s>', $rawts)
};
}
sub telmval {
my ($track, $stringid) = @_;
my $constname = "EBMLID_$stringid";
my $id = __PACKAGE__->$constname;
return $track->{$id}{'value'} // $track->{$id}{'data'};
#return $track->{"$stringid"}}{'value'} // $track->{$EBMLID->{$stringid}}{'data'};
}
sub trackno_is_audio {
my ($tracks, $trackno) = @_;
foreach my $track (@$tracks) {
if(telmval($track, 'TrackNumber') == $trackno) {
return telmval($track, 'TrackType') == 0x2;
}
}
return undef;
}
sub flac_read_METADATA_BLOCK {
my $fh = $_[0];
my $type = \$_[1];
my $done = \$_[2];
my $buf;
my $headread = read($fh, $buf, 4);
($headread && ($headread == 4)) or return undef;
my ($blocktypelast, $sizehi, $sizemid, $sizelo) = unpack('CCCC',$buf);
$$done = $blocktypelast & 0x80;
$$type = $blocktypelast & 0x7F;
my $size = ($sizehi << 16) | ($sizemid << 8) | ($sizelo);
#say "islast $$done type $type size $size";
$$type != 0x7F or return undef;
my $tbuf;
my $dataread = read($fh, $tbuf, $size);
($dataread && ($dataread == $size)) or return undef;
$buf .= $tbuf;
return \$buf;
}
sub flac_parseStreamInfo {
# https://metacpan.org/source/DANIEL/Audio-FLAC-Header-2.4/Header.pm
my ($buf) = @_;
my $metaBinString = unpack('B144', $buf);
my $x32 = 0 x 32;
my $info = {};
$info->{'MINIMUMBLOCKSIZE'} = unpack('N', pack('B32', substr($x32 . substr($metaBinString, 0, 16), -32)));
$info->{'MAXIMUMBLOCKSIZE'} = unpack('N', pack('B32', substr($x32 . substr($metaBinString, 16, 16), -32)));
$info->{'MINIMUMFRAMESIZE'} = unpack('N', pack('B32', substr($x32 . substr($metaBinString, 32, 24), -32)));
$info->{'MAXIMUMFRAMESIZE'} = unpack('N', pack('B32', substr($x32 . substr($metaBinString, 56, 24), -32)));
$info->{'SAMPLERATE'} = unpack('N', pack('B32', substr($x32 . substr($metaBinString, 80, 20), -32)));
$info->{'NUMCHANNELS'} = unpack('N', pack('B32', substr($x32 . substr($metaBinString, 100, 3), -32))) + 1;
$info->{'BITSPERSAMPLE'} = unpack('N', pack('B32', substr($x32 . substr($metaBinString, 103, 5), -32))) + 1;
# Calculate total samples in two parts
my $highBits = unpack('N', pack('B32', substr($x32 . substr($metaBinString, 108, 4), -32)));
$info->{'TOTALSAMPLES'} = $highBits * 2 ** 32 +
unpack('N', pack('B32', substr($x32 . substr($metaBinString, 112, 32), -32)));
# Return the MD5 as a 32-character hexadecimal string
$info->{'MD5CHECKSUM'} = unpack('H32',substr($buf, 18, 16));
return $info;
}
sub flac_read_to_audio {
( run in 1.163 second using v1.01-cache-2.11-cpan-ceb78f64989 )