001
function
readframe(
$file
) {
002
if
(! (
$f
=
fopen
(
$file
,
'rb'
)) )
die
(
"Unable to open "
.
$file
);
003
$res
[
'filesize'
] =
filesize
(
$file
);
004
do
{
005
while
(
fread
(
$f
,1) !=
Chr
(255)) {
// Find the first frame
006
if
(
feof
(
$f
))
die
(
"No mpeg frame found"
) ;
007
}
008
fseek
(
$f
,
ftell
(
$f
) - 1);
// back up one byte
009
010
$frameoffset
=
ftell
(
$f
);
011
012
$r
=
fread
(
$f
, 4);
013
014
$bits
= sprintf(
"%'08b%'08b%'08b%'08b"
, ord(
$r
{0}), ord(
$r
{1}), ord(
$r
{2}), ord(
$r
{3}));
015
}
016
while
(!
$bits
[8]
and
!
$bits
[9]
and
!
$bits
[10]);
// 1st 8 bits true from the while
017
018
// Detect VBR header
019
if
(
$bits
[11] == 0) {
020
if
((
$bits
[24] == 1) && (
$bits
[25] == 1)) {
021
$vbroffset
= 9;
// MPEG 2.5 Mono
022
}
else
{
023
$vbroffset
= 17;
// MPEG 2.5 Stereo
024
}
025
}
else
if
(
$bits
[12] == 0) {
026
if
((
$bits
[24] == 1) && (
$bits
[25] == 1)) {
027
$vbroffset
= 9;
// MPEG 2 Mono
028
}
else
{
029
$vbroffset
= 17;
// MPEG 2 Stereo
030
}
031
}
else
{
032
if
((
$bits
[24] == 1) && (
$bits
[25] == 1)) {
033
$vbroffset
= 17;
// MPEG 1 Mono
034
}
else
{
035
$vbroffset
= 32;
// MPEG 1 Stereo
036
}
037
}
038
039
fseek
(
$f
,
ftell
(
$f
) +
$vbroffset
);
040
$r
=
fread
(
$f
, 4);
041
042
switch
(
$r
) {
043
case
'Xing'
:
044
$res
[
'encoding_type'
] =
'VBR'
;
045
case
'VBRI'
:
046
default
:
047
if
(
$vbroffset
!= 32) {
048
// VBRI Header is fixed after 32 bytes, so maybe we are looking at the wrong place.
049
fseek
(
$f
,
ftell
(
$f
) + 32 -
$vbroffset
);
050
$r
=
fread
(
$f
, 4);
051
052
if
(
$r
!=
'VBRI'
) {
053
$res
[
'encoding_type'
] =
'CBR'
;
054
break
;
055
}
056
}
else
{
057
$res
[
'encoding_type'
] =
'CBR'
;
058
break
;
059
}
060
061
$res
[
'encoding_type'
] =
'VBR'
;
062
}
063
064
fclose(
$f
);
065
066
if
(
$bits
[11] == 0) {
067
$res
[
'mpeg_ver'
] =
"2.5"
;
068
$bitrates
=
array
(
069
'1'
=>
array
(0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0),
070
'2'
=>
array
(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),
071
'3'
=>
array
(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),
072
);
073
}
else
if
(
$bits
[12] == 0) {
074
$res
[
'mpeg_ver'
] =
"2"
;
075
$bitrates
=
array
(
076
'1'
=>
array
(0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0),
077
'2'
=>
array
(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),
078
'3'
=>
array
(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),
079
);
080
}
else
{
081
$res
[
'mpeg_ver'
] =
"1"
;
082
$bitrates
=
array
(
083
'1'
=>
array
(0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0),
084
'2'
=>
array
(0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0),
085
'3'
=>
array
(0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0),
086
);
087
}
088
089
$layer
=
array
(
090
array
(0,3),
091
array
(2,1),
092
);
093
$res
[
'layer'
] =
$layer
[
$bits
[13]][
$bits
[14]];
094
095
if
(
$bits
[15] == 0) {
096
// It's backwards, if the bit is not set then it is protected.
097
$res
[
'crc'
] = true;
098
}
099
100
$bitrate
= 0;
101
if
(
$bits
[16] == 1)
$bitrate
+= 8;
102
if
(
$bits
[17] == 1)
$bitrate
+= 4;
103
if
(
$bits
[18] == 1)
$bitrate
+= 2;
104
if
(
$bits
[19] == 1)
$bitrate
+= 1;
105
$res
[
'bitrate'
] =
$bitrates
[
$res
[
'layer'
]][
$bitrate
];
106
107
$frequency
=
array
(
108
'1'
=>
array
(
109
'0'
=>
array
(44100, 48000),
110
'1'
=>
array
(32000, 0),
111
),
112
'2'
=>
array
(
113
'0'
=>
array
(22050, 24000),
114
'1'
=>
array
(16000, 0),
115
),
116
'2.5'
=>
array
(
117
'0'
=>
array
(11025, 12000),
118
'1'
=>
array
(8000, 0),
119
),
120
);
121
$res
[
'frequency'
] =
$frequency
[
$res
[
'mpeg_ver'
]][
$bits
[20]][
$bits
[21]];
122
123
$mode
=
array
(
124
array
(
'Stereo'
,
'Joint Stereo'
),
125
array
(
'Dual Channel'
,
'Mono'
),
126
);
127
$res
[
'mode'
] =
$mode
[
$bits
[24]][
$bits
[25]];
128
129
$samplesperframe
=
array
(
130
'1'
=>
array
(
131
'1'
=> 384,
132
'2'
=> 1152,
133
'3'
=> 1152
134
),
135
'2'
=>
array
(
136
'1'
=> 384,
137
'2'
=> 1152,
138
'3'
=> 576
139
),
140
'2.5'
=>
array
(
141
'1'
=> 384,
142
'2'
=> 1152,
143
'3'
=> 576
144
),
145
);
146
$res
[
'samples_per_frame'
] =
$samplesperframe
[
$res
[
'mpeg_ver'
]][
$res
[
'layer'
]];
147
148
if
(
$res
[
'encoding_type'
] !=
'VBR'
) {
149
if
(
$res
[
'bitrate'
] == 0) {
150
$s
= -1;
151
}
else
{
152
$s
= ((8*
filesize
(
$file
))/1000) /
$res
[
'bitrate'
];
153
}
154
$res
[
'length'
] = sprintf(
'%02d:%02d'
,
floor
(
$s
/60),
floor
(
$s
-(
floor
(
$s
/60)*60)));
155
$res
[
'lengthh'
] = sprintf(
'%02d:%02d:%02d'
,
floor
(
$s
/3600),
floor
(
$s
/60),
floor
(
$s
-(
floor
(
$s
/60)*60)));
156
$res
[
'lengths'
] = (int)
$s
;
157
158
$res
[
'samples'
] =
ceil
(
$res
[
'lengths'
] *
$res
[
'frequency'
]);
159
if
(0 !=
$res
[
'samples_per_frame'
]) {
160
$res
[
'frames'
] =
ceil
(
$res
[
'samples'
] /
$res
[
'samples_per_frame'
]);
161
}
else
{
162
$res
[
'frames'
] = 0;
163
}
164
$res
[
'musicsize'
] =
ceil
(
$res
[
'lengths'
] *
$res
[
'bitrate'
] * 1000 / 8);
165
}
else
{
166
$res
[
'samples'
] =
$res
[
'samples_per_frame'
] *
$res
[
'frames'
];
167
$s
=
$res
[
'samples'
] /
$res
[
'frequency'
];
168
169
$res
[
'length'
] = sprintf(
'%02d:%02d'
,
floor
(
$s
/60),
floor
(
$s
-(
floor
(
$s
/60)*60)));
170
$res
[
'lengthh'
] = sprintf(
'%02d:%02d:%02d'
,
floor
(
$s
/3600),
floor
(
$s
/60),
floor
(
$s
-(
floor
(
$s
/60)*60)));
171
$res
[
'lengths'
] = (int)
$s
;
172
173
$res
[
'bitrate'
] = (int)((
$res
[
'musicsize'
] /
$s
) * 8 / 1000);
174
}
175
176
return
$res
;
177
}