line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
2
|
|
|
|
|
|
|
## Package: Magic.pm |
3
|
|
|
|
|
|
|
## Author: Allen Day |
4
|
|
|
|
|
|
|
## Notice: Copyright (c) 2002 Allen Day |
5
|
|
|
|
|
|
|
## Purpose: Attempt to determine video file type. Based on /usr/share/magic |
6
|
|
|
|
|
|
|
## Comments: None |
7
|
|
|
|
|
|
|
## CVS: $Header: /cvsroot/perlvideo/Info/Magic.pm,v 1.4 2002/11/12 04:20:03 allenday Exp $ |
8
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
package Video::Info::Magic; |
11
|
8
|
|
|
8
|
|
449
|
use 5.006; |
|
8
|
|
|
|
|
28
|
|
|
8
|
|
|
|
|
364
|
|
12
|
8
|
|
|
8
|
|
43
|
use strict; |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
246
|
|
13
|
8
|
|
|
8
|
|
39
|
use warnings; |
|
8
|
|
|
|
|
25
|
|
|
8
|
|
|
|
|
929
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
require Exporter; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
18
|
|
|
|
|
|
|
our $VERSION = '1.01'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
#we're going to use a enhexable string as the constant value |
21
|
|
|
|
|
|
|
#that matches the first four bytes of that filetype. For lack |
22
|
|
|
|
|
|
|
#of better values. |
23
|
8
|
|
|
8
|
|
44
|
use constant VIDEO_UNKNOWN_FORMAT => 0x01; |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
782
|
|
24
|
8
|
|
|
8
|
|
49
|
use constant VIDEO_MPEG1 => 0x02; |
|
8
|
|
|
|
|
12
|
|
|
8
|
|
|
|
|
514
|
|
25
|
8
|
|
|
8
|
|
40
|
use constant VIDEO_MPEG2 => 0x03; |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
943
|
|
26
|
8
|
|
|
8
|
|
278
|
use constant VIDEO_MPEG_LAYER_2 => 0x04; |
|
8
|
|
|
|
|
12
|
|
|
8
|
|
|
|
|
435
|
|
27
|
8
|
|
|
8
|
|
38
|
use constant VIDEO_MPEG_LAYER_3 => 0x05; |
|
8
|
|
|
|
|
11
|
|
|
8
|
|
|
|
|
372
|
|
28
|
8
|
|
|
8
|
|
48
|
use constant VIDEO_MPEG_VIDEO_STREAM => 0x000001b3; |
|
8
|
|
|
|
|
12
|
|
|
8
|
|
|
|
|
559
|
|
29
|
8
|
|
|
8
|
|
39
|
use constant VIDEO_MPEG_SYSTEM_STREAM => 0x000001ba; |
|
8
|
|
|
|
|
17
|
|
|
8
|
|
|
|
|
372
|
|
30
|
8
|
|
|
8
|
|
38
|
use constant VIDEO_RIFF => 0x52494646; |
|
8
|
|
|
|
|
22
|
|
|
8
|
|
|
|
|
493
|
|
31
|
8
|
|
|
8
|
|
36
|
use constant VIDEO_REALAUDIO => 0x2e7261fd; |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
386
|
|
32
|
8
|
|
|
8
|
|
44
|
use constant VIDEO_REALMEDIA => 0x2e524d46; |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
364
|
|
33
|
8
|
|
|
8
|
|
37
|
use constant VIDEO_QUICKTIME_MOOV => 0x6d6f6f76; |
|
8
|
|
|
|
|
22
|
|
|
8
|
|
|
|
|
315
|
|
34
|
8
|
|
|
8
|
|
35
|
use constant VIDEO_QUICKTIME_MDAT => 0x6d646174; |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
362
|
|
35
|
8
|
|
|
8
|
|
40
|
use constant VIDEO_QUICKTIME_PNOT => 0x706e6f74; |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
835
|
|
36
|
8
|
|
|
8
|
|
40
|
use constant VIDEO_ASF1 => 0x75b22630; |
|
8
|
|
|
|
|
24
|
|
|
8
|
|
|
|
|
8986
|
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
39
|
|
|
|
|
|
|
## Items to export into callers namespace by default. Note: do not export |
40
|
|
|
|
|
|
|
## names by default without a very good reason. Use EXPORT_OK instead. |
41
|
|
|
|
|
|
|
## Do not simply export all your public functions/methods/constants. |
42
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
43
|
|
|
|
|
|
|
## This allows declaration use Video::Info ':all'; |
44
|
|
|
|
|
|
|
## If you do not need this, moving things directly into @EXPORT or |
45
|
|
|
|
|
|
|
## @EXPORT_OK will save memory. |
46
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
47
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( 'all' => [ qw() ] ); |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
our @EXPORT = qw( MPEG1 |
52
|
|
|
|
|
|
|
VIDEO_MPEG2 |
53
|
|
|
|
|
|
|
VIDEO_MPEG_LAYER_2 |
54
|
|
|
|
|
|
|
VIDEO_MPEG_LAYER_3 |
55
|
|
|
|
|
|
|
VIDEO_MPEG_VIDEO_STREAM |
56
|
|
|
|
|
|
|
VIDEO_MPEG_SYSTEM_STREAM |
57
|
|
|
|
|
|
|
VIDEO_RIFF |
58
|
|
|
|
|
|
|
VIDEO_REALAUDIO |
59
|
|
|
|
|
|
|
VIDEO_REALMEDIA |
60
|
|
|
|
|
|
|
VIDEO_QUICKTIME_MOOV |
61
|
|
|
|
|
|
|
VIDEO_QUICKTIME_MDAT |
62
|
|
|
|
|
|
|
VIDEO_UNKNOWN_FORMAT |
63
|
|
|
|
|
|
|
VIDEO_ASF1 |
64
|
|
|
|
|
|
|
divine |
65
|
|
|
|
|
|
|
acodec2str |
66
|
|
|
|
|
|
|
); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
69
|
|
|
|
|
|
|
## Preloaded methods go here. |
70
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
71
|
|
|
|
|
|
|
1; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub divine { |
74
|
|
|
|
|
|
|
# warn "caller: ", caller, "\n"; |
75
|
6
|
|
50
|
6
|
0
|
24
|
my $filename = shift || die "divine(): please provide path/to/file"; |
76
|
|
|
|
|
|
|
|
77
|
6
|
50
|
|
|
|
422
|
open(F,$filename) || die "divine(): couldn't open $filename: $!"; |
78
|
6
|
|
|
|
|
15
|
my($four1,$four2) = undef; |
79
|
6
|
50
|
|
|
|
71
|
sysread(F,$four1,4) == 4 or die "divine(): sysread()\n"; |
80
|
6
|
50
|
|
|
|
43
|
sysread(F,$four2,4) == 4 or die "divine(): sysread()\n"; |
81
|
6
|
|
|
|
|
111
|
close(F); |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
## convert the four bytes to an unsigned long |
84
|
6
|
|
|
|
|
36
|
my $two = unpack( 'n', substr($four1,0,2) ); |
85
|
6
|
|
|
|
|
18
|
$four1 = unpack( 'N', $four1 ); |
86
|
6
|
|
|
|
|
15
|
$four2 = unpack( 'N', $four2 ); |
87
|
|
|
|
|
|
|
#warn( sprintf( "Hex: 0x%04x\n", $two ) ); |
88
|
|
|
|
|
|
|
#warn( sprintf( "Hex: 0x%08x\n", $four1 ) ); |
89
|
|
|
|
|
|
|
#warn( sprintf( "Hex: 0x%16x\n", $four2 ) ); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
#TODO: MPEG1 MPEG2 |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
## try to match the big, specific ones first |
94
|
6
|
|
|
|
|
159
|
my %table4 = ( |
95
|
|
|
|
|
|
|
0x000001b3 => [VIDEO_MPEG_VIDEO_STREAM, 'MPEG'], |
96
|
|
|
|
|
|
|
0x000001ba => [VIDEO_MPEG_SYSTEM_STREAM, 'MPEG'], |
97
|
|
|
|
|
|
|
0x52494646 => [VIDEO_RIFF, 'RIFF'], |
98
|
|
|
|
|
|
|
0x41564920 => [VIDEO_RIFF, 'RIFF'], |
99
|
|
|
|
|
|
|
0x2e7261fd => [VIDEO_REALAUDIO, 'Real'], |
100
|
|
|
|
|
|
|
0x2e524d46 => [VIDEO_REALMEDIA, 'Real'], |
101
|
|
|
|
|
|
|
0x6d6f6f76 => [VIDEO_QUICKTIME_MOOV,'Quicktime'], |
102
|
|
|
|
|
|
|
0x6d646174 => [VIDEO_QUICKTIME_MDAT,'Quicktime'], |
103
|
|
|
|
|
|
|
0x706e6f74 => [VIDEO_QUICKTIME_PNOT,'Quicktime'], |
104
|
|
|
|
|
|
|
0x3026b275 => [VIDEO_ASF1, 'ASF'], |
105
|
|
|
|
|
|
|
); |
106
|
|
|
|
|
|
|
# 0x75b22630 => [VIDEO_ASF1, 'ASF'], |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
## there may be more possible second bits (f0-f9) for MPEG I audio layers |
109
|
6
|
|
|
|
|
85
|
my %table2 = ( |
110
|
|
|
|
|
|
|
0xfffa => [VIDEO_MPEG_LAYER_3, 'MP3'], #11111010 for sure |
111
|
|
|
|
|
|
|
0xfffb => [VIDEO_MPEG_LAYER_3, 'MP3'], #11111011 for sure |
112
|
|
|
|
|
|
|
0xfffc => [VIDEO_MPEG_LAYER_2, 'MP3'], #11111100 for sure |
113
|
|
|
|
|
|
|
0xfffd => [VIDEO_MPEG_LAYER_2, 'MP3'], #11111101 not yet |
114
|
|
|
|
|
|
|
0xfffe => [VIDEO_MPEG_LAYER_3, 'MP3'], #11111110 probably |
115
|
|
|
|
|
|
|
0xffff => [VIDEO_MPEG_LAYER_3, 'MP3'], #11111111 not yet |
116
|
|
|
|
|
|
|
0x4944 => [VIDEO_MPEG_LAYER_3, 'MP3'], #THIS HAS AN ID3 TAG |
117
|
|
|
|
|
|
|
); |
118
|
|
|
|
|
|
|
|
119
|
6
|
100
|
|
|
|
64
|
$table4{$four1} ? return $table4{$four1} : 0; |
120
|
2
|
50
|
|
|
|
10
|
$table4{$four2} ? return $table4{$four2} : 0; |
121
|
2
|
50
|
|
|
|
27
|
$table2{$two} ? return $table2{$two} : 0; |
122
|
|
|
|
|
|
|
|
123
|
0
|
|
|
|
|
0
|
return [VIDEO_UNKNOWN_FORMAT,undef]; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
127
|
|
|
|
|
|
|
## acodec2str() |
128
|
|
|
|
|
|
|
## |
129
|
|
|
|
|
|
|
## Return the common name for a hexadecimal codec. |
130
|
|
|
|
|
|
|
##------------------------------------------------------------------------ |
131
|
|
|
|
|
|
|
sub acodec2str { |
132
|
10
|
|
|
10
|
0
|
60
|
my $numeric = shift; |
133
|
|
|
|
|
|
|
|
134
|
10
|
|
|
|
|
300
|
my %codec = ( |
135
|
|
|
|
|
|
|
0x1 => 'Uncompressed PCM', |
136
|
|
|
|
|
|
|
0x2 => 'MS ADPCM', |
137
|
|
|
|
|
|
|
0x4 => 'Windows Media Audio', #is this right? |
138
|
|
|
|
|
|
|
0x6 => 'aLaw', |
139
|
|
|
|
|
|
|
0x7 => 'uLaw', |
140
|
|
|
|
|
|
|
0xa => 'DivX audio (WMA)', |
141
|
|
|
|
|
|
|
0x11 => 'IMA ADPCM', |
142
|
|
|
|
|
|
|
0x31 => 'MS GSM 6.10', |
143
|
|
|
|
|
|
|
0x32 => 'MS GSM 6.10', # MSN Audio |
144
|
|
|
|
|
|
|
0x50 => 'MPEG Layer 1/2', |
145
|
|
|
|
|
|
|
0x55 => 'MPEG Layer 3', |
146
|
|
|
|
|
|
|
0x61 => 'Duck DK4 ADPCM (rogue format number)', |
147
|
|
|
|
|
|
|
0x62 => 'Duck DK3 ADPCM (rogue format number)', |
148
|
|
|
|
|
|
|
0x75 => 'VoxWare', |
149
|
|
|
|
|
|
|
0x85 => 'MPEG Layer 3', |
150
|
|
|
|
|
|
|
0x111 => 'Vivo G.723', |
151
|
|
|
|
|
|
|
0x112 => 'Vivo G.723/Siren', |
152
|
|
|
|
|
|
|
0x130 => 'ACELP.net Sipro Lab Audio Decoder', |
153
|
|
|
|
|
|
|
0x160 => 'DivX audio (WMA)', |
154
|
|
|
|
|
|
|
0x161 => 'DivX audio (WMA)', |
155
|
|
|
|
|
|
|
0x270 => 'Sony ATRAC3', |
156
|
|
|
|
|
|
|
0x401 => 'Intel Music Coder', |
157
|
|
|
|
|
|
|
0x2000 => 'AC3', |
158
|
|
|
|
|
|
|
0xfffe => 'OggVorbis Audio Decoder', |
159
|
|
|
|
|
|
|
0x1fc4 => 'ALF2', |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
## Hrm, we only grab a 2-byte short so these can't exist |
162
|
|
|
|
|
|
|
# 0x20776172 => 'PCM', # raw (MOV files) |
163
|
|
|
|
|
|
|
# 0x736f7774 => 'PCM', # twos (MOV files) |
164
|
|
|
|
|
|
|
# 0x33706d2e => 'MPEG Layer 3', # ".mp3" CBR/VBR MP3 (MOV files) |
165
|
|
|
|
|
|
|
# 0x5500736d => 'MPEG Layer 3', # "ms\0\x55" older mp3 fcc (MOV files) |
166
|
|
|
|
|
|
|
# 0x77616c75 => 'uLaw', # "ulaw" (MOV files) |
167
|
|
|
|
|
|
|
# 0x10001 => 'Uncompressed DVD PCM', |
168
|
|
|
|
|
|
|
); |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
#warn "num: $numeric , cod: $codec{$numeric}"; |
171
|
10
|
50
|
33
|
|
|
109
|
if ( defined $numeric && defined $codec{$numeric} ) { |
172
|
10
|
|
|
|
|
197
|
return $codec{$numeric}; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
__END__ |