line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package FLV::MetaTag; |
2
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
37
|
use warnings; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
217
|
|
4
|
6
|
|
|
6
|
|
31
|
use strict; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
332
|
|
5
|
6
|
|
|
6
|
|
120
|
use 5.008; |
|
6
|
|
|
|
|
20
|
|
|
6
|
|
|
|
|
254
|
|
6
|
6
|
|
|
6
|
|
45
|
use Carp; |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
891
|
|
7
|
6
|
|
|
6
|
|
41
|
use English qw(-no_match_vars); |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
325
|
|
8
|
|
|
|
|
|
|
|
9
|
6
|
|
|
6
|
|
3951
|
use base 'FLV::Base'; |
|
6
|
|
|
|
|
171
|
|
|
6
|
|
|
|
|
933
|
|
10
|
|
|
|
|
|
|
|
11
|
6
|
|
|
6
|
|
4585
|
use FLV::AMFReader; |
|
6
|
|
|
|
|
21
|
|
|
6
|
|
|
|
|
178
|
|
12
|
6
|
|
|
6
|
|
3237
|
use FLV::AMFWriter; |
|
6
|
|
|
|
|
24
|
|
|
6
|
|
|
|
|
234
|
|
13
|
6
|
|
|
6
|
|
73
|
use FLV::Util; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
1211
|
|
14
|
6
|
|
|
6
|
|
39
|
use FLV::Tag; |
|
6
|
|
|
|
|
52
|
|
|
6
|
|
|
|
|
9617
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our $VERSION = '0.24'; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=for stopwords FLVTool2 AMF |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 NAME |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
FLV::MetaTag - Flash video file data structure |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 LICENSE |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
See L |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 DESCRIPTION |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
As best I can tell, FLV meta tags are a pair of AMF data: one is the |
31
|
|
|
|
|
|
|
event name and one is the payload. I learned that from looking at |
32
|
|
|
|
|
|
|
sample FLV files and reading the FLVTool2 code. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
I've seen no specification for the meta tag, so this is all empirical |
35
|
|
|
|
|
|
|
for me, unlike the other tags. |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head1 METHODS |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
This is a subclass of FLV::Base. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=over |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=item $self->parse($fileinst) |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
Takes a FLV::File instance and extracts an FLV meta tag from the file |
46
|
|
|
|
|
|
|
stream. This method throws exceptions if the stream is not a valid |
47
|
|
|
|
|
|
|
FLV v1.0 or v1.1 file. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
There is no return value. |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
The majority of the work is done by FLV::AMFReader. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=cut |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub parse |
56
|
|
|
|
|
|
|
{ |
57
|
31
|
|
|
31
|
1
|
73
|
my $self = shift; |
58
|
31
|
|
|
|
|
48
|
my $file = shift; |
59
|
31
|
|
|
|
|
146
|
my $datasize = shift; |
60
|
|
|
|
|
|
|
|
61
|
31
|
|
|
|
|
119
|
$self->{data} = [ $self->_deserialize($file->get_bytes($datasize)) ]; |
62
|
31
|
|
|
|
|
1087
|
return; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub _deserialize |
66
|
|
|
|
|
|
|
{ |
67
|
39
|
|
|
39
|
|
82
|
my $self = shift; |
68
|
39
|
|
|
|
|
70
|
my $content = shift; |
69
|
|
|
|
|
|
|
|
70
|
39
|
|
|
|
|
392
|
return FLV::AMFReader->new($content)->read_flv_meta(); |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=item $self->clone() |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
Create an independent copy of this instance. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=cut |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub clone |
80
|
|
|
|
|
|
|
{ |
81
|
8
|
|
|
8
|
1
|
19
|
my $self = shift; |
82
|
|
|
|
|
|
|
|
83
|
8
|
|
|
|
|
40
|
my $copy = FLV::MetaTag->new; |
84
|
8
|
|
|
|
|
58
|
FLV::Tag->copy_tag($self, $copy); |
85
|
8
|
|
|
|
|
64
|
$copy->{data} = [ $self->_deserialize($self->serialize) ]; |
86
|
8
|
|
|
|
|
183
|
return $copy; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=item $self->serialize() |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Returns a byte string representation of the tag data. Throws an |
92
|
|
|
|
|
|
|
exception via croak() on error. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=cut |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub serialize |
97
|
|
|
|
|
|
|
{ |
98
|
38
|
|
|
38
|
1
|
86
|
my $self = shift; |
99
|
|
|
|
|
|
|
|
100
|
38
|
|
|
|
|
476
|
my $content = FLV::AMFWriter->new()->write_flv_meta(@{ $self->{data} }); |
|
38
|
|
|
|
|
1679
|
|
101
|
38
|
|
|
|
|
683
|
return $content; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item $self->get_info() |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Returns a hash of FLV metadata. See FLV::Info for more details. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=cut |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub get_info |
111
|
|
|
|
|
|
|
{ |
112
|
4
|
|
|
4
|
1
|
28
|
my ($pkg, @tags) = @_; |
113
|
|
|
|
|
|
|
|
114
|
4
|
|
|
|
|
10
|
my @records; |
115
|
|
|
|
|
|
|
my %keys; |
116
|
4
|
|
|
|
|
11
|
for my $tag (@tags) |
117
|
|
|
|
|
|
|
{ |
118
|
4
|
|
|
|
|
18
|
my $data = $tag->{data}->[1]; |
119
|
4
|
50
|
|
|
|
19
|
if ($data) |
120
|
|
|
|
|
|
|
{ |
121
|
4
|
|
|
|
|
9
|
my %fields; |
122
|
4
|
|
|
|
|
9
|
for my $key (keys %{$data}) |
|
4
|
|
|
|
|
36
|
|
123
|
|
|
|
|
|
|
{ |
124
|
60
|
|
|
|
|
90
|
my $value = $data->{$key}; |
125
|
60
|
50
|
|
|
|
99
|
if (!defined $value) |
126
|
|
|
|
|
|
|
{ |
127
|
0
|
|
|
|
|
0
|
$value = q{}; |
128
|
|
|
|
|
|
|
} |
129
|
60
|
|
|
|
|
287
|
$value =~ s/ \A \s+ //xms; |
130
|
60
|
|
|
|
|
179
|
$value =~ s/ \s+ \z //xms; |
131
|
60
|
|
|
|
|
103
|
$fields{$key} = $value; |
132
|
60
|
|
|
|
|
107
|
$keys{$key} = undef; |
133
|
|
|
|
|
|
|
} |
134
|
4
|
|
|
|
|
22
|
push @records, \%fields; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
} |
137
|
4
|
|
|
|
|
38
|
my %info = $pkg->_get_info('meta', \%keys, \@records); |
138
|
4
|
|
|
|
|
117
|
return %info; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=item $self->get_values(); |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=item $self->get_value($key); |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=item $self->set_value($key, $value); |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
These are convenience functions for interacting with an C |
148
|
|
|
|
|
|
|
hash. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
C returns a hash of all metadata key-value pairs. |
151
|
|
|
|
|
|
|
C returns a single value. C has no return |
152
|
|
|
|
|
|
|
value. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=cut |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub get_values |
157
|
|
|
|
|
|
|
{ |
158
|
18
|
|
|
18
|
1
|
37
|
my $self = shift; |
159
|
|
|
|
|
|
|
|
160
|
18
|
50
|
|
|
|
80
|
return if (!$self->{data}); |
161
|
18
|
50
|
|
|
|
30
|
return if (@{ $self->{data} } < 2); |
|
18
|
|
|
|
|
75
|
|
162
|
18
|
50
|
|
|
|
88
|
return if ($self->{data}->[0] ne 'onMetaData'); |
163
|
18
|
|
|
|
|
39
|
return %{ $self->{data}->[1] }; |
|
18
|
|
|
|
|
328
|
|
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub get_value |
167
|
|
|
|
|
|
|
{ |
168
|
562
|
|
|
562
|
1
|
759
|
my $self = shift; |
169
|
562
|
|
|
|
|
754
|
my $key = shift; |
170
|
|
|
|
|
|
|
|
171
|
562
|
100
|
|
|
|
1749
|
return if (!$self->{data}); |
172
|
539
|
50
|
|
|
|
618
|
return if (@{ $self->{data} } < 2); |
|
539
|
|
|
|
|
1384
|
|
173
|
539
|
50
|
|
|
|
1377
|
return if ($self->{data}->[0] ne 'onMetaData'); |
174
|
539
|
|
|
|
|
2535
|
return $self->{data}->[1]->{$key}; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub set_value |
178
|
|
|
|
|
|
|
{ |
179
|
471
|
|
|
471
|
1
|
1087
|
my ($self, @keyvalues) = @_; |
180
|
|
|
|
|
|
|
|
181
|
471
|
|
100
|
|
|
1403
|
$self->{data} ||= []; |
182
|
471
|
100
|
66
|
|
|
620
|
if (@{ $self->{data} } < 2 || $self->{data}->[0] ne 'onMetaData') |
|
471
|
|
|
|
|
2494
|
|
183
|
|
|
|
|
|
|
{ |
184
|
23
|
|
|
|
|
41
|
unshift @{ $self->{data} }, 'onMetaData', {}; |
|
23
|
|
|
|
|
102
|
|
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
471
|
|
|
|
|
1200
|
while (@keyvalues) |
188
|
|
|
|
|
|
|
{ |
189
|
471
|
|
|
|
|
936
|
my ($key, $value) = splice @keyvalues, 0, 2; |
190
|
|
|
|
|
|
|
|
191
|
471
|
50
|
|
|
|
1725
|
if (defined $value) |
192
|
|
|
|
|
|
|
{ |
193
|
471
|
|
|
|
|
1887
|
$self->{data}->[1]->{$key} = $value; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
else |
196
|
|
|
|
|
|
|
{ |
197
|
0
|
|
|
|
|
0
|
delete $self->{data}->[1]->{$key}; |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
471
|
|
|
|
|
1520
|
return; |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
1; |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
__END__ |