FLV::MetaTag - Flash video file data structure


FLV-Info documentation Contained in the FLV-Info distribution.

Index


Code Index:

NAME

Top

FLV::MetaTag - Flash video file data structure

LICENSE

Top

See FLV::Info

DESCRIPTION

Top

As best I can tell, FLV meta tags are a pair of AMF data: one is the event name and one is the payload. I learned that from looking at sample FLV files and reading the FLVTool2 code.

I've seen no specification for the meta tag, so this is all empirical for me, unlike the other tags.

METHODS

Top

This is a subclass of FLV::Base.

$self->parse($fileinst)

Takes a FLV::File instance and extracts an FLV meta tag from the file stream. This method throws exceptions if the stream is not a valid FLV v1.0 or v1.1 file.

There is no return value.

The majority of the work is done by FLV::AMFReader.

$self->clone()

Create an independent copy of this instance.

$self->serialize()

Returns a byte string representation of the tag data. Throws an exception via croak() on error.

$self->get_info()

Returns a hash of FLV metadata. See FLV::Info for more details.

$self->get_values();
$self->get_value($key);
$self->set_value($key, $value);

These are convenience functions for interacting with an onMetadata hash.

get_values() returns a hash of all metadata key-value pairs. get_value($key) returns a single value. set_value() has no return value.

AUTHOR

Top

See FLV::Info


FLV-Info documentation Contained in the FLV-Info distribution.
package FLV::MetaTag;

use warnings;
use strict;
use 5.008;
use Carp;
use English qw(-no_match_vars);

use base 'FLV::Base';

use FLV::AMFReader;
use FLV::AMFWriter;
use FLV::Util;
use FLV::Tag;

our $VERSION = '0.24';

sub parse
{
   my $self     = shift;
   my $file     = shift;
   my $datasize = shift;

   $self->{data} = [ $self->_deserialize($file->get_bytes($datasize)) ];
   return;
}

sub _deserialize
{
   my $self    = shift;
   my $content = shift;

   return FLV::AMFReader->new($content)->read_flv_meta();
}

sub clone
{
   my $self = shift;

   my $copy = FLV::MetaTag->new;
   FLV::Tag->copy_tag($self, $copy);
   $copy->{data} = [ $self->_deserialize($self->serialize) ];
   return $copy;
}

sub serialize
{
   my $self = shift;

   my $content = FLV::AMFWriter->new()->write_flv_meta(@{ $self->{data} });
   return $content;
}

sub get_info
{
   my ($pkg, @tags) = @_;

   my @records;
   my %keys;
   for my $tag (@tags)
   {
      my $data = $tag->{data}->[1];
      if ($data)
      {
         my %fields;
         for my $key (keys %{$data})
         {
            my $value = $data->{$key};
            if (!defined $value)
            {
               $value = q{};
            }
            $value =~ s/ \A \s+    //xms;
            $value =~ s/    \s+ \z //xms;
            $fields{$key} = $value;
            $keys{$key}   = undef;
         }
         push @records, \%fields;
      }
   }
   my %info = $pkg->_get_info('meta', \%keys, \@records);
   return %info;
}

sub get_values
{
   my $self = shift;

   return if (!$self->{data});
   return if (@{ $self->{data} } < 2);
   return if ($self->{data}->[0] ne 'onMetaData');
   return %{ $self->{data}->[1] };
}

sub get_value
{
   my $self = shift;
   my $key  = shift;

   return if (!$self->{data});
   return if (@{ $self->{data} } < 2);
   return if ($self->{data}->[0] ne 'onMetaData');
   return $self->{data}->[1]->{$key};
}

sub set_value
{
   my ($self, @keyvalues) = @_;

   $self->{data} ||= [];
   if (@{ $self->{data} } < 2 || $self->{data}->[0] ne 'onMetaData')
   {
      unshift @{ $self->{data} }, 'onMetaData', {};
   }

   while (@keyvalues)
   {
      my ($key, $value) = splice @keyvalues, 0, 2;

      if (defined $value)
      {
         $self->{data}->[1]->{$key} = $value;
      }
      else
      {
         delete $self->{data}->[1]->{$key};
      }
   }

   return;
}

1;

__END__