22 $ThisFileInfo[
'fileformat'] =
'real';
23 $ThisFileInfo[
'bitrate'] = 0;
24 $ThisFileInfo[
'playtime_seconds'] = 0;
26 fseek($fd, $ThisFileInfo[
'avdataoffset'], SEEK_SET);
28 while (ftell($fd) < $ThisFileInfo[
'avdataend']) {
29 $ChunkData = fread($fd, 8);
30 $ChunkName = substr($ChunkData, 0, 4);
33 if ($ChunkName ==
'.ra'.
"\xFD") {
34 $ChunkData .= fread($fd, $ChunkSize - 8);
35 if ($this->
ParseOldRAheader(substr($ChunkData, 0, 128), $ThisFileInfo[
'real'][
'old_ra_header'])) {
36 $ThisFileInfo[
'audio'][
'dataformat'] =
'real';
37 $ThisFileInfo[
'audio'][
'lossless'] =
false;
38 $ThisFileInfo[
'audio'][
'sample_rate'] = $ThisFileInfo[
'real'][
'old_ra_header'][
'sample_rate'];
39 $ThisFileInfo[
'audio'][
'bits_per_sample'] = $ThisFileInfo[
'real'][
'old_ra_header'][
'bits_per_sample'];
40 $ThisFileInfo[
'audio'][
'channels'] = $ThisFileInfo[
'real'][
'old_ra_header'][
'channels'];
42 $ThisFileInfo[
'playtime_seconds'] = 60 * ($ThisFileInfo[
'real'][
'old_ra_header'][
'audio_bytes'] / $ThisFileInfo[
'real'][
'old_ra_header'][
'bytes_per_minute']);
43 $ThisFileInfo[
'audio'][
'bitrate'] = 8 * ($ThisFileInfo[
'real'][
'old_ra_header'][
'audio_bytes'] / $ThisFileInfo[
'playtime_seconds']);
44 $ThisFileInfo[
'audio'][
'codec'] = $this->
RealAudioCodecFourCClookup($ThisFileInfo[
'real'][
'old_ra_header'][
'fourcc'], $ThisFileInfo[
'audio'][
'bitrate']);
46 foreach ($ThisFileInfo[
'real'][
'old_ra_header'][
'comments'] as $key => $valuearray) {
47 if (strlen(trim($valuearray[0])) > 0) {
48 $ThisFileInfo[
'real'][
'comments'][$key][] = trim($valuearray[0]);
53 $ThisFileInfo[
'error'][] =
'There was a problem parsing this RealAudio file. Please submit it for analysis to http://www.getid3.org/upload/ or info@getid3.org';
54 unset($ThisFileInfo[
'bitrate']);
55 unset($ThisFileInfo[
'playtime_seconds']);
60 $ThisFileInfo[
'real'][
'chunks'][$ChunkCounter] = array();
61 $thisfile_real_chunks_currentchunk = &$ThisFileInfo[
'real'][
'chunks'][$ChunkCounter];
63 $thisfile_real_chunks_currentchunk[
'name'] = $ChunkName;
64 $thisfile_real_chunks_currentchunk[
'offset'] = ftell($fd) - 8;
65 $thisfile_real_chunks_currentchunk[
'length'] = $ChunkSize;
66 if (($thisfile_real_chunks_currentchunk[
'offset'] + $thisfile_real_chunks_currentchunk[
'length']) > $ThisFileInfo[
'avdataend']) {
67 $ThisFileInfo[
'warning'][] =
'Chunk "'.$thisfile_real_chunks_currentchunk[
'name'].
'" at offset '.$thisfile_real_chunks_currentchunk[
'offset'].
' claims to be '.$thisfile_real_chunks_currentchunk[
'length'].
' bytes long, which is beyond end of file';
74 fseek($fd, $thisfile_real_chunks_currentchunk[
'offset'] + $ChunkSize, SEEK_SET);
78 $ChunkData .= fread($fd, $ChunkSize - 8);
88 switch ($thisfile_real_chunks_currentchunk[
'object_version']) {
108 if ($thisfile_real_chunks_currentchunk[
'object_version'] == 0) {
131 $ThisFileInfo[
'playtime_seconds'] = $thisfile_real_chunks_currentchunk[
'duration'] / 1000;
132 if ($thisfile_real_chunks_currentchunk[
'duration'] > 0) {
133 $ThisFileInfo[
'bitrate'] += $thisfile_real_chunks_currentchunk[
'avg_bit_rate'];
135 $thisfile_real_chunks_currentchunk[
'flags'][
'save_enabled'] = (bool) ($thisfile_real_chunks_currentchunk[
'flags_raw'] & 0x0001);
136 $thisfile_real_chunks_currentchunk[
'flags'][
'perfect_play'] = (bool) ($thisfile_real_chunks_currentchunk[
'flags_raw'] & 0x0002);
137 $thisfile_real_chunks_currentchunk[
'flags'][
'live_broadcast'] = (bool) ($thisfile_real_chunks_currentchunk[
'flags_raw'] & 0x0004);
144 if ($thisfile_real_chunks_currentchunk[
'object_version'] == 0) {
163 $thisfile_real_chunks_currentchunk[
'stream_name'] = substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk[
'stream_name_size']);
164 $offset += $thisfile_real_chunks_currentchunk[
'stream_name_size'];
167 $thisfile_real_chunks_currentchunk[
'mime_type'] = substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk[
'mime_type_size']);
168 $offset += $thisfile_real_chunks_currentchunk[
'mime_type_size'];
171 $thisfile_real_chunks_currentchunk[
'type_specific_data'] = substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk[
'type_specific_len']);
172 $offset += $thisfile_real_chunks_currentchunk[
'type_specific_len'];
175 $thisfile_real_chunks_currentchunk_typespecificdata = &$thisfile_real_chunks_currentchunk[
'type_specific_data'];
177 switch ($thisfile_real_chunks_currentchunk[
'mime_type']) {
178 case 'video/x-pn-realvideo':
179 case 'video/x-pn-multirate-realvideo':
183 $thisfile_real_chunks_currentchunk[
'video_info'] = array();
184 $thisfile_real_chunks_currentchunk_videoinfo = &$thisfile_real_chunks_currentchunk[
'video_info'];
186 $thisfile_real_chunks_currentchunk_videoinfo[
'dwSize'] =
getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 0, 4));
187 $thisfile_real_chunks_currentchunk_videoinfo[
'fourcc1'] = substr($thisfile_real_chunks_currentchunk_typespecificdata, 4, 4);
188 $thisfile_real_chunks_currentchunk_videoinfo[
'fourcc2'] = substr($thisfile_real_chunks_currentchunk_typespecificdata, 8, 4);
189 $thisfile_real_chunks_currentchunk_videoinfo[
'width'] =
getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 12, 2));
190 $thisfile_real_chunks_currentchunk_videoinfo[
'height'] =
getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 14, 2));
191 $thisfile_real_chunks_currentchunk_videoinfo[
'bits_per_sample'] =
getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 16, 2));
194 $thisfile_real_chunks_currentchunk_videoinfo[
'frames_per_second'] =
getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 22, 2));
203 $thisfile_real_chunks_currentchunk_videoinfo[
'codec'] =
getid3_riff::RIFFfourccLookup($thisfile_real_chunks_currentchunk_videoinfo[
'fourcc2']);
205 $ThisFileInfo[
'video'][
'resolution_x'] = $thisfile_real_chunks_currentchunk_videoinfo[
'width'];
206 $ThisFileInfo[
'video'][
'resolution_y'] = $thisfile_real_chunks_currentchunk_videoinfo[
'height'];
207 $ThisFileInfo[
'video'][
'frame_rate'] = (float) $thisfile_real_chunks_currentchunk_videoinfo[
'frames_per_second'];
208 $ThisFileInfo[
'video'][
'codec'] = $thisfile_real_chunks_currentchunk_videoinfo[
'codec'];
209 $ThisFileInfo[
'video'][
'bits_per_sample'] = $thisfile_real_chunks_currentchunk_videoinfo[
'bits_per_sample'];
212 case 'audio/x-pn-realaudio':
213 case 'audio/x-pn-multirate-realaudio':
214 $this->
ParseOldRAheader($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk[
'parsed_audio_data']);
216 $ThisFileInfo[
'audio'][
'sample_rate'] = $thisfile_real_chunks_currentchunk[
'parsed_audio_data'][
'sample_rate'];
217 $ThisFileInfo[
'audio'][
'bits_per_sample'] = $thisfile_real_chunks_currentchunk[
'parsed_audio_data'][
'bits_per_sample'];
218 $ThisFileInfo[
'audio'][
'channels'] = $thisfile_real_chunks_currentchunk[
'parsed_audio_data'][
'channels'];
219 if (!empty($ThisFileInfo[
'audio'][
'dataformat'])) {
220 foreach ($ThisFileInfo[
'audio'] as $key => $value) {
221 if ($key !=
'streams') {
222 $ThisFileInfo[
'audio'][
'streams'][$thisfile_real_chunks_currentchunk[
'stream_number']][$key] = $value;
228 case 'logical-fileinfo':
230 $thisfile_real_chunks_currentchunk[
'logical_fileinfo'] = array();
231 $thisfile_real_chunks_currentchunk_logicalfileinfo = &$thisfile_real_chunks_currentchunk[
'logical_fileinfo'];
233 $thisfile_real_chunks_currentchunk_logicalfileinfo_offset = 0;
234 $thisfile_real_chunks_currentchunk_logicalfileinfo[
'logical_fileinfo_length'] =
getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 4));
235 $thisfile_real_chunks_currentchunk_logicalfileinfo_offset += 4;
238 $thisfile_real_chunks_currentchunk_logicalfileinfo_offset += 4;
240 $thisfile_real_chunks_currentchunk_logicalfileinfo[
'num_tags'] =
getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 4));
241 $thisfile_real_chunks_currentchunk_logicalfileinfo_offset += 4;
244 $thisfile_real_chunks_currentchunk_logicalfileinfo_offset += 4;
258 if (empty($ThisFileInfo[
'playtime_seconds'])) {
259 $ThisFileInfo[
'playtime_seconds'] = max($ThisFileInfo[
'playtime_seconds'], ($thisfile_real_chunks_currentchunk[
'duration'] + $thisfile_real_chunks_currentchunk[
'start_time']) / 1000);
261 if ($thisfile_real_chunks_currentchunk[
'duration'] > 0) {
262 switch ($thisfile_real_chunks_currentchunk[
'mime_type']) {
263 case 'audio/x-pn-realaudio':
264 case 'audio/x-pn-multirate-realaudio':
265 $ThisFileInfo[
'audio'][
'bitrate'] = (isset($ThisFileInfo[
'audio'][
'bitrate']) ? $ThisFileInfo[
'audio'][
'bitrate'] : 0) + $thisfile_real_chunks_currentchunk[
'avg_bit_rate'];
266 $ThisFileInfo[
'audio'][
'codec'] = $this->
RealAudioCodecFourCClookup($thisfile_real_chunks_currentchunk[
'parsed_audio_data'][
'fourcc'], $ThisFileInfo[
'audio'][
'bitrate']);
267 $ThisFileInfo[
'audio'][
'dataformat'] =
'real';
268 $ThisFileInfo[
'audio'][
'lossless'] =
false;
271 case 'video/x-pn-realvideo':
272 case 'video/x-pn-multirate-realvideo':
273 $ThisFileInfo[
'video'][
'bitrate'] = (isset($ThisFileInfo[
'video'][
'bitrate']) ? $ThisFileInfo[
'video'][
'bitrate'] : 0) + $thisfile_real_chunks_currentchunk[
'avg_bit_rate'];
274 $ThisFileInfo[
'video'][
'bitrate_mode'] =
'cbr';
275 $ThisFileInfo[
'video'][
'dataformat'] =
'real';
276 $ThisFileInfo[
'video'][
'lossless'] =
false;
277 $ThisFileInfo[
'video'][
'pixel_aspect_ratio'] = (float) 1;
280 case 'audio/x-ralf-mpeg4-generic':
281 $ThisFileInfo[
'audio'][
'bitrate'] = (isset($ThisFileInfo[
'audio'][
'bitrate']) ? $ThisFileInfo[
'audio'][
'bitrate'] : 0) + $thisfile_real_chunks_currentchunk[
'avg_bit_rate'];
282 $ThisFileInfo[
'audio'][
'codec'] =
'RealAudio Lossless';
283 $ThisFileInfo[
'audio'][
'dataformat'] =
'real';
284 $ThisFileInfo[
'audio'][
'lossless'] =
true;
287 $ThisFileInfo[
'bitrate'] = (isset($ThisFileInfo[
'video'][
'bitrate']) ? $ThisFileInfo[
'video'][
'bitrate'] : 0) + (isset($ThisFileInfo[
'audio'][
'bitrate']) ? $ThisFileInfo[
'audio'][
'bitrate'] : 0);
295 if ($thisfile_real_chunks_currentchunk[
'object_version'] == 0) {
298 $thisfile_real_chunks_currentchunk[
'title'] = (string) substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk[
'title_len']);
299 $offset += $thisfile_real_chunks_currentchunk[
'title_len'];
303 $thisfile_real_chunks_currentchunk[
'artist'] = (string) substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk[
'artist_len']);
304 $offset += $thisfile_real_chunks_currentchunk[
'artist_len'];
308 $thisfile_real_chunks_currentchunk[
'copyright'] = (string) substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk[
'copyright_len']);
309 $offset += $thisfile_real_chunks_currentchunk[
'copyright_len'];
313 $thisfile_real_chunks_currentchunk[
'comment'] = (string) substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk[
'comment_len']);
314 $offset += $thisfile_real_chunks_currentchunk[
'comment_len'];
317 $commentkeystocopy = array(
'title'=>
'title',
'artist'=>
'artist',
'copyright'=>
'copyright',
'comment'=>
'comment');
318 foreach ($commentkeystocopy as $key => $val) {
319 if ($thisfile_real_chunks_currentchunk[$key]) {
320 $ThisFileInfo[
'real'][
'comments'][$val][] = trim($thisfile_real_chunks_currentchunk[$key]);
335 if ($thisfile_real_chunks_currentchunk[
'object_version'] == 0) {
343 if ($thisfile_real_chunks_currentchunk[
'next_index_header'] == 0) {
348 fseek($fd, $thisfile_real_chunks_currentchunk[
'next_index_header'], SEEK_SET);
354 $ThisFileInfo[
'warning'][] =
'Unhandled RealMedia chunk "'.$ChunkName.
'" at offset '.$thisfile_real_chunks_currentchunk[
'offset'];
360 if (!empty($ThisFileInfo[
'audio'][
'streams'])) {
361 $ThisFileInfo[
'audio'][
'bitrate'] = 0;
362 foreach ($ThisFileInfo[
'audio'][
'streams'] as $key => $valuearray) {
363 $ThisFileInfo[
'audio'][
'bitrate'] += $valuearray[
'bitrate'];
374 $ParsedArray = array();
375 $ParsedArray[
'magic'] = substr($OldRAheaderData, 0, 4);
376 if ($ParsedArray[
'magic'] !=
'.ra'.
"\xFD") {
381 if ($ParsedArray[
'version1'] < 3) {
385 } elseif ($ParsedArray[
'version1'] == 3) {
387 $ParsedArray[
'fourcc1'] =
'.ra3';
388 $ParsedArray[
'bits_per_sample'] = 16;
389 $ParsedArray[
'sample_rate'] = 8000;
398 $ParsedArray[
'comments_raw'] = substr($OldRAheaderData, 22, $ParsedArray[
'header_size'] - 22 + 1);
402 $ParsedArray[
'comments'][
'title'][] = substr($ParsedArray[
'comments_raw'], $commentoffset, $commentlength);
403 $commentoffset += $commentlength;
406 $ParsedArray[
'comments'][
'artist'][] = substr($ParsedArray[
'comments_raw'], $commentoffset, $commentlength);
407 $commentoffset += $commentlength;
410 $ParsedArray[
'comments'][
'copyright'][] = substr($ParsedArray[
'comments_raw'], $commentoffset, $commentlength);
411 $commentoffset += $commentlength;
415 $ParsedArray[
'fourcc'] = substr($OldRAheaderData, 23 + $commentoffset, 4);
417 } elseif ($ParsedArray[
'version1'] <= 5) {
420 $ParsedArray[
'fourcc1'] = substr($OldRAheaderData, 8, 4);
434 switch ($ParsedArray[
'version1']) {
442 $ParsedArray[
'fourcc2'] = substr($OldRAheaderData, 57, 4);
444 $ParsedArray[
'fourcc3'] = substr($OldRAheaderData, 62, 4);
447 $ParsedArray[
'comments_raw'] = substr($OldRAheaderData, 69, $ParsedArray[
'header_size'] - 69 + 16);
451 $ParsedArray[
'comments'][
'title'][] = substr($ParsedArray[
'comments_raw'], $commentoffset, $commentlength);
452 $commentoffset += $commentlength;
455 $ParsedArray[
'comments'][
'artist'][] = substr($ParsedArray[
'comments_raw'], $commentoffset, $commentlength);
456 $commentoffset += $commentlength;
459 $ParsedArray[
'comments'][
'copyright'][] = substr($ParsedArray[
'comments_raw'], $commentoffset, $commentlength);
460 $commentoffset += $commentlength;
468 $ParsedArray[
'genr'] = substr($OldRAheaderData, 62, 4);
469 $ParsedArray[
'fourcc3'] = substr($OldRAheaderData, 66, 4);
470 $ParsedArray[
'comments'] = array();
473 $ParsedArray[
'fourcc'] = $ParsedArray[
'fourcc3'];
476 foreach ($ParsedArray[
'comments'] as $key => $value) {
477 if ($ParsedArray[
'comments'][$key][0] ===
false) {
478 $ParsedArray[
'comments'][$key][0] =
'';
486 static $RealAudioCodecFourCClookup = array();
487 if (empty($RealAudioCodecFourCClookup)) {
491 $RealAudioCodecFourCClookup[
'14_4'][8000] =
'RealAudio v2 (14.4kbps)';
492 $RealAudioCodecFourCClookup[
'14.4'][8000] =
'RealAudio v2 (14.4kbps)';
493 $RealAudioCodecFourCClookup[
'lpcJ'][8000] =
'RealAudio v2 (14.4kbps)';
494 $RealAudioCodecFourCClookup[
'28_8'][15200] =
'RealAudio v2 (28.8kbps)';
495 $RealAudioCodecFourCClookup[
'28.8'][15200] =
'RealAudio v2 (28.8kbps)';
496 $RealAudioCodecFourCClookup[
'sipr'][4933] =
'RealAudio v4 (5kbps Voice)';
497 $RealAudioCodecFourCClookup[
'sipr'][6444] =
'RealAudio v4 (6.5kbps Voice)';
498 $RealAudioCodecFourCClookup[
'sipr'][8444] =
'RealAudio v4 (8.5kbps Voice)';
499 $RealAudioCodecFourCClookup[
'sipr'][16000] =
'RealAudio v4 (16kbps Wideband)';
500 $RealAudioCodecFourCClookup[
'dnet'][8000] =
'RealAudio v3 (8kbps Music)';
501 $RealAudioCodecFourCClookup[
'dnet'][16000] =
'RealAudio v3 (16kbps Music Low Response)';
502 $RealAudioCodecFourCClookup[
'dnet'][15963] =
'RealAudio v3 (16kbps Music Mid/High Response)';
503 $RealAudioCodecFourCClookup[
'dnet'][20000] =
'RealAudio v3 (20kbps Music Stereo)';
504 $RealAudioCodecFourCClookup[
'dnet'][32000] =
'RealAudio v3 (32kbps Music Mono)';
505 $RealAudioCodecFourCClookup[
'dnet'][31951] =
'RealAudio v3 (32kbps Music Stereo)';
506 $RealAudioCodecFourCClookup[
'dnet'][39965] =
'RealAudio v3 (40kbps Music Mono)';
507 $RealAudioCodecFourCClookup[
'dnet'][40000] =
'RealAudio v3 (40kbps Music Stereo)';
508 $RealAudioCodecFourCClookup[
'dnet'][79947] =
'RealAudio v3 (80kbps Music Mono)';
509 $RealAudioCodecFourCClookup[
'dnet'][80000] =
'RealAudio v3 (80kbps Music Stereo)';
511 $RealAudioCodecFourCClookup[
'dnet'][0] =
'RealAudio v3';
512 $RealAudioCodecFourCClookup[
'sipr'][0] =
'RealAudio v4';
513 $RealAudioCodecFourCClookup[
'cook'][0] =
'RealAudio G2';
514 $RealAudioCodecFourCClookup[
'atrc'][0] =
'RealAudio 8';
516 $roundbitrate = intval(round($bitrate));
517 if (isset($RealAudioCodecFourCClookup[$fourcc][$roundbitrate])) {
518 return $RealAudioCodecFourCClookup[$fourcc][$roundbitrate];
519 } elseif (isset($RealAudioCodecFourCClookup[$fourcc][0])) {
520 return $RealAudioCodecFourCClookup[$fourcc][0];