23 $ThisFileInfo[
'fileformat'] =
'ogg';
26 if (isset($ThisFileInfo[
'id3v2'])) {
27 $ThisFileInfo[
'warning'][] =
'Illegal ID3v2 tag present.';
29 if (isset($ThisFileInfo[
'id3v1'])) {
30 $ThisFileInfo[
'warning'][] =
'Illegal ID3v1 tag present.';
32 if (isset($ThisFileInfo[
'ape'])) {
33 $ThisFileInfo[
'warning'][] =
'Illegal APE tag present.';
39 fseek($fd, $ThisFileInfo[
'avdataoffset'], SEEK_SET);
42 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']] = $oggpageinfo;
45 $ThisFileInfo[
'error'][] =
'Could not find start of Ogg page in the first '.GETID3_FREAD_BUFFER_SIZE.
' bytes (this might not be an Ogg-Vorbis file?)';
46 unset($ThisFileInfo[
'fileformat']);
47 unset($ThisFileInfo[
'ogg']);
51 $filedata = fread($fd, $oggpageinfo[
'page_length']);
54 if (substr($filedata, 0, 4) ==
'fLaC') {
56 $ThisFileInfo[
'audio'][
'dataformat'] =
'flac';
57 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'vbr';
58 $ThisFileInfo[
'audio'][
'lossless'] =
true;
60 } elseif (substr($filedata, 1, 6) ==
'vorbis') {
62 $ThisFileInfo[
'audio'][
'dataformat'] =
'vorbis';
63 $ThisFileInfo[
'audio'][
'lossless'] =
false;
65 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'packet_type'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
67 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'stream_type'] = substr($filedata, $filedataoffset, 6);
73 $ThisFileInfo[
'audio'][
'channels'] = $ThisFileInfo[
'ogg'][
'numberofchannels'];
76 if ($ThisFileInfo[
'ogg'][
'samplerate'] == 0) {
77 $ThisFileInfo[
'error'][] =
'Corrupt Ogg file: sample rate == zero';
80 $ThisFileInfo[
'audio'][
'sample_rate'] = $ThisFileInfo[
'ogg'][
'samplerate'];
81 $ThisFileInfo[
'ogg'][
'samples'] = 0;
82 $ThisFileInfo[
'ogg'][
'bitrate_average'] = 0;
93 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'vbr';
94 if ($ThisFileInfo[
'ogg'][
'bitrate_max'] == 0xFFFFFFFF) {
95 unset($ThisFileInfo[
'ogg'][
'bitrate_max']);
96 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'abr';
98 if ($ThisFileInfo[
'ogg'][
'bitrate_nominal'] == 0xFFFFFFFF) {
99 unset($ThisFileInfo[
'ogg'][
'bitrate_nominal']);
101 if ($ThisFileInfo[
'ogg'][
'bitrate_min'] == 0xFFFFFFFF) {
102 unset($ThisFileInfo[
'ogg'][
'bitrate_min']);
103 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'abr';
106 } elseif (substr($filedata, 0, 8) ==
'Speex ') {
110 $ThisFileInfo[
'audio'][
'dataformat'] =
'speex';
111 $ThisFileInfo[
'mime_type'] =
'audio/speex';
112 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'abr';
113 $ThisFileInfo[
'audio'][
'lossless'] =
false;
115 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'speex_string'] = substr($filedata, $filedataoffset, 8);
116 $filedataoffset += 8;
117 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'speex_version'] = substr($filedata, $filedataoffset, 20);
118 $filedataoffset += 20;
119 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'speex_version_id'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
120 $filedataoffset += 4;
121 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'header_size'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
122 $filedataoffset += 4;
123 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'rate'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
124 $filedataoffset += 4;
125 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'mode'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
126 $filedataoffset += 4;
127 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'mode_bitstream_version'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
128 $filedataoffset += 4;
129 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'nb_channels'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
130 $filedataoffset += 4;
131 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'bitrate'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
132 $filedataoffset += 4;
133 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'framesize'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
134 $filedataoffset += 4;
135 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'vbr'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
136 $filedataoffset += 4;
137 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'frames_per_packet'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
138 $filedataoffset += 4;
139 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'extra_headers'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
140 $filedataoffset += 4;
141 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'reserved1'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
142 $filedataoffset += 4;
143 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'reserved2'] =
getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
144 $filedataoffset += 4;
146 $ThisFileInfo[
'speex'][
'speex_version'] = trim($ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'speex_version']);
147 $ThisFileInfo[
'speex'][
'sample_rate'] = $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'rate'];
148 $ThisFileInfo[
'speex'][
'channels'] = $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'nb_channels'];
149 $ThisFileInfo[
'speex'][
'vbr'] = (bool) $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'vbr'];
152 $ThisFileInfo[
'audio'][
'sample_rate'] = $ThisFileInfo[
'speex'][
'sample_rate'];
153 $ThisFileInfo[
'audio'][
'channels'] = $ThisFileInfo[
'speex'][
'channels'];
154 if ($ThisFileInfo[
'speex'][
'vbr']) {
155 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'vbr';
160 $ThisFileInfo[
'error'][] =
'Expecting either "Speex " or "vorbis" identifier strings, found neither';
161 unset($ThisFileInfo[
'ogg']);
162 unset($ThisFileInfo[
'mime_type']);
171 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']] = $oggpageinfo;
173 switch ($ThisFileInfo[
'audio'][
'dataformat']) {
176 $filedata = fread($fd, $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_length']);
178 $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'stream_type'] = substr($filedata, 1, 6);
185 $ThisFileInfo[
'error'][] =
'Failed to parse FLAC headers';
191 fseek($fd, $ThisFileInfo[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_length'], SEEK_CUR);
203 if ($LastOggSpostion = strpos($LastChunkOfOgg,
'SggO')) {
204 fseek($fd, $ThisFileInfo[
'avdataend'] - ($LastOggSpostion + strlen(
'SggO')), SEEK_SET);
205 $ThisFileInfo[
'avdataend'] = ftell($fd);
207 $ThisFileInfo[
'ogg'][
'samples'] = $ThisFileInfo[
'ogg'][
'pageheader'][
'eos'][
'pcm_abs_position'];
208 if ($ThisFileInfo[
'ogg'][
'samples'] == 0) {
209 $ThisFileInfo[
'error'][] =
'Corrupt Ogg file: eos.number of samples == zero';
212 $ThisFileInfo[
'ogg'][
'bitrate_average'] = (($ThisFileInfo[
'avdataend'] - $ThisFileInfo[
'avdataoffset']) * 8) / ($ThisFileInfo[
'ogg'][
'samples'] / $ThisFileInfo[
'audio'][
'sample_rate']);
215 if (!empty($ThisFileInfo[
'ogg'][
'bitrate_average'])) {
216 $ThisFileInfo[
'audio'][
'bitrate'] = $ThisFileInfo[
'ogg'][
'bitrate_average'];
217 } elseif (!empty($ThisFileInfo[
'ogg'][
'bitrate_nominal'])) {
218 $ThisFileInfo[
'audio'][
'bitrate'] = $ThisFileInfo[
'ogg'][
'bitrate_nominal'];
219 } elseif (!empty($ThisFileInfo[
'ogg'][
'bitrate_min']) && !empty($ThisFileInfo[
'ogg'][
'bitrate_max'])) {
220 $ThisFileInfo[
'audio'][
'bitrate'] = ($ThisFileInfo[
'ogg'][
'bitrate_min'] + $ThisFileInfo[
'ogg'][
'bitrate_max']) / 2;
222 if (isset($ThisFileInfo[
'audio'][
'bitrate']) && !isset($ThisFileInfo[
'playtime_seconds'])) {
223 if ($ThisFileInfo[
'audio'][
'bitrate'] == 0) {
224 $ThisFileInfo[
'error'][] =
'Corrupt Ogg file: bitrate_audio == zero';
227 $ThisFileInfo[
'playtime_seconds'] = (float) ((($ThisFileInfo[
'avdataend'] - $ThisFileInfo[
'avdataoffset']) * 8) / $ThisFileInfo[
'audio'][
'bitrate']);
230 if (isset($ThisFileInfo[
'ogg'][
'vendor'])) {
231 $ThisFileInfo[
'audio'][
'encoder'] = preg_replace(
'/^Encoded with /',
'', $ThisFileInfo[
'ogg'][
'vendor']);
234 if ($ThisFileInfo[
'audio'][
'dataformat'] ==
'vorbis') {
237 if (preg_match(
'/^Xiph.Org/', $ThisFileInfo[
'audio'][
'encoder'])) {
239 if ($ThisFileInfo[
'audio'][
'bitrate_mode'] ==
'abr') {
242 $ThisFileInfo[
'audio'][
'encoder_options'] =
'-b '.round($ThisFileInfo[
'ogg'][
'bitrate_nominal'] / 1000);
244 } elseif (($ThisFileInfo[
'audio'][
'bitrate_mode'] ==
'vbr') && ($ThisFileInfo[
'audio'][
'channels'] == 2) && ($ThisFileInfo[
'audio'][
'sample_rate'] >= 44100) && ($ThisFileInfo[
'audio'][
'sample_rate'] <= 48000)) {
246 $ThisFileInfo[
'audio'][
'encoder_options'] =
'-q '.$this->get_quality_from_nominal_bitrate($ThisFileInfo[
'ogg'][
'bitrate_nominal']);
251 if (empty($ThisFileInfo[
'audio'][
'encoder_options']) && !empty($ThisFileInfo[
'ogg'][
'bitrate_nominal'])) {
252 $ThisFileInfo[
'audio'][
'encoder_options'] =
'Nominal bitrate: '.intval(round($ThisFileInfo[
'ogg'][
'bitrate_nominal'] / 1000)).
'kbps';
ParseVorbisCommentsFilepointer(&$fd, &$ThisFileInfo)
const GETID3_FREAD_BUFFER_SIZE
FLACparseMETAdata(&$fd, &$ThisFileInfo)
LittleEndian2Int($byteword, $signed=false)
SpeexBandModeLookup($mode)