ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
module.audio-video.real.php
Go to the documentation of this file.
1 <?php
4 // available at http://getid3.sourceforge.net //
5 // or http://www.getid3.org //
6 // also https://github.com/JamesHeinrich/getID3 //
8 // See readme.txt for more details //
10 // //
11 // module.audio-video.real.php //
12 // module for analyzing Real Audio/Video files //
13 // dependencies: module.audio-video.riff.php //
14 // ///
16 
17 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
18 
20 {
21 
22  public function Analyze() {
23  $info = &$this->getid3->info;
24 
25  $info['fileformat'] = 'real';
26  $info['bitrate'] = 0;
27  $info['playtime_seconds'] = 0;
28 
29  $this->fseek($info['avdataoffset']);
30  $ChunkCounter = 0;
31  while ($this->ftell() < $info['avdataend']) {
32  $ChunkData = $this->fread(8);
33  $ChunkName = substr($ChunkData, 0, 4);
34  $ChunkSize = getid3_lib::BigEndian2Int(substr($ChunkData, 4, 4));
35 
36  if ($ChunkName == '.ra'."\xFD") {
37  $ChunkData .= $this->fread($ChunkSize - 8);
38  if ($this->ParseOldRAheader(substr($ChunkData, 0, 128), $info['real']['old_ra_header'])) {
39  $info['audio']['dataformat'] = 'real';
40  $info['audio']['lossless'] = false;
41  $info['audio']['sample_rate'] = $info['real']['old_ra_header']['sample_rate'];
42  $info['audio']['bits_per_sample'] = $info['real']['old_ra_header']['bits_per_sample'];
43  $info['audio']['channels'] = $info['real']['old_ra_header']['channels'];
44 
45  $info['playtime_seconds'] = 60 * ($info['real']['old_ra_header']['audio_bytes'] / $info['real']['old_ra_header']['bytes_per_minute']);
46  $info['audio']['bitrate'] = 8 * ($info['real']['old_ra_header']['audio_bytes'] / $info['playtime_seconds']);
47  $info['audio']['codec'] = $this->RealAudioCodecFourCClookup($info['real']['old_ra_header']['fourcc'], $info['audio']['bitrate']);
48 
49  foreach ($info['real']['old_ra_header']['comments'] as $key => $valuearray) {
50  if (strlen(trim($valuearray[0])) > 0) {
51  $info['real']['comments'][$key][] = trim($valuearray[0]);
52  }
53  }
54  return true;
55  }
56  $this->error('There was a problem parsing this RealAudio file. Please submit it for analysis to info@getid3.org');
57  unset($info['bitrate']);
58  unset($info['playtime_seconds']);
59  return false;
60  }
61 
62  // shortcut
63  $info['real']['chunks'][$ChunkCounter] = array();
64  $thisfile_real_chunks_currentchunk = &$info['real']['chunks'][$ChunkCounter];
65 
66  $thisfile_real_chunks_currentchunk['name'] = $ChunkName;
67  $thisfile_real_chunks_currentchunk['offset'] = $this->ftell() - 8;
68  $thisfile_real_chunks_currentchunk['length'] = $ChunkSize;
69  if (($thisfile_real_chunks_currentchunk['offset'] + $thisfile_real_chunks_currentchunk['length']) > $info['avdataend']) {
70  $this->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');
71  return false;
72  }
73 
74  if ($ChunkSize > ($this->getid3->fread_buffer_size() + 8)) {
75 
76  $ChunkData .= $this->fread($this->getid3->fread_buffer_size() - 8);
77  $this->fseek($thisfile_real_chunks_currentchunk['offset'] + $ChunkSize);
78 
79  } elseif(($ChunkSize - 8) > 0) {
80 
81  $ChunkData .= $this->fread($ChunkSize - 8);
82 
83  }
84  $offset = 8;
85 
86  switch ($ChunkName) {
87 
88  case '.RMF': // RealMedia File Header
89  $thisfile_real_chunks_currentchunk['object_version'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
90  $offset += 2;
91  switch ($thisfile_real_chunks_currentchunk['object_version']) {
92 
93  case 0:
94  $thisfile_real_chunks_currentchunk['file_version'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
95  $offset += 4;
96  $thisfile_real_chunks_currentchunk['headers_count'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
97  $offset += 4;
98  break;
99 
100  default:
101  //$this->warning('Expected .RMF-object_version to be "0", actual value is "'.$thisfile_real_chunks_currentchunk['object_version'].'" (should not be a problem)');
102  break;
103 
104  }
105  break;
106 
107 
108  case 'PROP': // Properties Header
109  $thisfile_real_chunks_currentchunk['object_version'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
110  $offset += 2;
111  if ($thisfile_real_chunks_currentchunk['object_version'] == 0) {
112  $thisfile_real_chunks_currentchunk['max_bit_rate'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
113  $offset += 4;
114  $thisfile_real_chunks_currentchunk['avg_bit_rate'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
115  $offset += 4;
116  $thisfile_real_chunks_currentchunk['max_packet_size'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
117  $offset += 4;
118  $thisfile_real_chunks_currentchunk['avg_packet_size'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
119  $offset += 4;
120  $thisfile_real_chunks_currentchunk['num_packets'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
121  $offset += 4;
122  $thisfile_real_chunks_currentchunk['duration'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
123  $offset += 4;
124  $thisfile_real_chunks_currentchunk['preroll'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
125  $offset += 4;
126  $thisfile_real_chunks_currentchunk['index_offset'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
127  $offset += 4;
128  $thisfile_real_chunks_currentchunk['data_offset'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
129  $offset += 4;
130  $thisfile_real_chunks_currentchunk['num_streams'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
131  $offset += 2;
132  $thisfile_real_chunks_currentchunk['flags_raw'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
133  $offset += 2;
134  $info['playtime_seconds'] = $thisfile_real_chunks_currentchunk['duration'] / 1000;
135  if ($thisfile_real_chunks_currentchunk['duration'] > 0) {
136  $info['bitrate'] += $thisfile_real_chunks_currentchunk['avg_bit_rate'];
137  }
138  $thisfile_real_chunks_currentchunk['flags']['save_enabled'] = (bool) ($thisfile_real_chunks_currentchunk['flags_raw'] & 0x0001);
139  $thisfile_real_chunks_currentchunk['flags']['perfect_play'] = (bool) ($thisfile_real_chunks_currentchunk['flags_raw'] & 0x0002);
140  $thisfile_real_chunks_currentchunk['flags']['live_broadcast'] = (bool) ($thisfile_real_chunks_currentchunk['flags_raw'] & 0x0004);
141  }
142  break;
143 
144  case 'MDPR': // Media Properties Header
145  $thisfile_real_chunks_currentchunk['object_version'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
146  $offset += 2;
147  if ($thisfile_real_chunks_currentchunk['object_version'] == 0) {
148  $thisfile_real_chunks_currentchunk['stream_number'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
149  $offset += 2;
150  $thisfile_real_chunks_currentchunk['max_bit_rate'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
151  $offset += 4;
152  $thisfile_real_chunks_currentchunk['avg_bit_rate'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
153  $offset += 4;
154  $thisfile_real_chunks_currentchunk['max_packet_size'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
155  $offset += 4;
156  $thisfile_real_chunks_currentchunk['avg_packet_size'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
157  $offset += 4;
158  $thisfile_real_chunks_currentchunk['start_time'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
159  $offset += 4;
160  $thisfile_real_chunks_currentchunk['preroll'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
161  $offset += 4;
162  $thisfile_real_chunks_currentchunk['duration'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
163  $offset += 4;
164  $thisfile_real_chunks_currentchunk['stream_name_size'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 1));
165  $offset += 1;
166  $thisfile_real_chunks_currentchunk['stream_name'] = substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk['stream_name_size']);
167  $offset += $thisfile_real_chunks_currentchunk['stream_name_size'];
168  $thisfile_real_chunks_currentchunk['mime_type_size'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 1));
169  $offset += 1;
170  $thisfile_real_chunks_currentchunk['mime_type'] = substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk['mime_type_size']);
171  $offset += $thisfile_real_chunks_currentchunk['mime_type_size'];
172  $thisfile_real_chunks_currentchunk['type_specific_len'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
173  $offset += 4;
174  $thisfile_real_chunks_currentchunk['type_specific_data'] = substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk['type_specific_len']);
175  $offset += $thisfile_real_chunks_currentchunk['type_specific_len'];
176 
177  // shortcut
178  $thisfile_real_chunks_currentchunk_typespecificdata = &$thisfile_real_chunks_currentchunk['type_specific_data'];
179 
180  switch ($thisfile_real_chunks_currentchunk['mime_type']) {
181  case 'video/x-pn-realvideo':
182  case 'video/x-pn-multirate-realvideo':
183  // http://www.freelists.org/archives/matroska-devel/07-2003/msg00010.html
184 
185  // shortcut
186  $thisfile_real_chunks_currentchunk['video_info'] = array();
187  $thisfile_real_chunks_currentchunk_videoinfo = &$thisfile_real_chunks_currentchunk['video_info'];
188 
189  $thisfile_real_chunks_currentchunk_videoinfo['dwSize'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 0, 4));
190  $thisfile_real_chunks_currentchunk_videoinfo['fourcc1'] = substr($thisfile_real_chunks_currentchunk_typespecificdata, 4, 4);
191  $thisfile_real_chunks_currentchunk_videoinfo['fourcc2'] = substr($thisfile_real_chunks_currentchunk_typespecificdata, 8, 4);
192  $thisfile_real_chunks_currentchunk_videoinfo['width'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 12, 2));
193  $thisfile_real_chunks_currentchunk_videoinfo['height'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 14, 2));
194  $thisfile_real_chunks_currentchunk_videoinfo['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 16, 2));
195  //$thisfile_real_chunks_currentchunk_videoinfo['unknown1'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 18, 2));
196  //$thisfile_real_chunks_currentchunk_videoinfo['unknown2'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 20, 2));
197  $thisfile_real_chunks_currentchunk_videoinfo['frames_per_second'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 22, 2));
198  //$thisfile_real_chunks_currentchunk_videoinfo['unknown3'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 24, 2));
199  //$thisfile_real_chunks_currentchunk_videoinfo['unknown4'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 26, 2));
200  //$thisfile_real_chunks_currentchunk_videoinfo['unknown5'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 28, 2));
201  //$thisfile_real_chunks_currentchunk_videoinfo['unknown6'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 30, 2));
202  //$thisfile_real_chunks_currentchunk_videoinfo['unknown7'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 32, 2));
203  //$thisfile_real_chunks_currentchunk_videoinfo['unknown8'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 34, 2));
204  //$thisfile_real_chunks_currentchunk_videoinfo['unknown9'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 36, 2));
205 
206  $thisfile_real_chunks_currentchunk_videoinfo['codec'] = getid3_riff::fourccLookup($thisfile_real_chunks_currentchunk_videoinfo['fourcc2']);
207 
208  $info['video']['resolution_x'] = $thisfile_real_chunks_currentchunk_videoinfo['width'];
209  $info['video']['resolution_y'] = $thisfile_real_chunks_currentchunk_videoinfo['height'];
210  $info['video']['frame_rate'] = (float) $thisfile_real_chunks_currentchunk_videoinfo['frames_per_second'];
211  $info['video']['codec'] = $thisfile_real_chunks_currentchunk_videoinfo['codec'];
212  $info['video']['bits_per_sample'] = $thisfile_real_chunks_currentchunk_videoinfo['bits_per_sample'];
213  break;
214 
215  case 'audio/x-pn-realaudio':
216  case 'audio/x-pn-multirate-realaudio':
217  $this->ParseOldRAheader($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk['parsed_audio_data']);
218 
219  $info['audio']['sample_rate'] = $thisfile_real_chunks_currentchunk['parsed_audio_data']['sample_rate'];
220  $info['audio']['bits_per_sample'] = $thisfile_real_chunks_currentchunk['parsed_audio_data']['bits_per_sample'];
221  $info['audio']['channels'] = $thisfile_real_chunks_currentchunk['parsed_audio_data']['channels'];
222  if (!empty($info['audio']['dataformat'])) {
223  foreach ($info['audio'] as $key => $value) {
224  if ($key != 'streams') {
225  $info['audio']['streams'][$thisfile_real_chunks_currentchunk['stream_number']][$key] = $value;
226  }
227  }
228  }
229  break;
230 
231  case 'logical-fileinfo':
232  // shortcut
233  $thisfile_real_chunks_currentchunk['logical_fileinfo'] = array();
234  $thisfile_real_chunks_currentchunk_logicalfileinfo = &$thisfile_real_chunks_currentchunk['logical_fileinfo'];
235 
236  $thisfile_real_chunks_currentchunk_logicalfileinfo_offset = 0;
237  $thisfile_real_chunks_currentchunk_logicalfileinfo['logical_fileinfo_length'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 4));
238  $thisfile_real_chunks_currentchunk_logicalfileinfo_offset += 4;
239 
240  //$thisfile_real_chunks_currentchunk_logicalfileinfo['unknown1'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 4));
241  $thisfile_real_chunks_currentchunk_logicalfileinfo_offset += 4;
242 
243  $thisfile_real_chunks_currentchunk_logicalfileinfo['num_tags'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 4));
244  $thisfile_real_chunks_currentchunk_logicalfileinfo_offset += 4;
245 
246  //$thisfile_real_chunks_currentchunk_logicalfileinfo['unknown2'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 4));
247  $thisfile_real_chunks_currentchunk_logicalfileinfo_offset += 4;
248 
249  //$thisfile_real_chunks_currentchunk_logicalfileinfo['d'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 1));
250 
251  //$thisfile_real_chunks_currentchunk_logicalfileinfo['one_type'] = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 4));
252  //$thisfile_real_chunks_currentchunk_logicalfileinfo_thislength = getid3_lib::BigEndian2Int(substr($thisfile_real_chunks_currentchunk_typespecificdata, 4 + $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, 2));
253  //$thisfile_real_chunks_currentchunk_logicalfileinfo['one'] = substr($thisfile_real_chunks_currentchunk_typespecificdata, 6 + $thisfile_real_chunks_currentchunk_logicalfileinfo_offset, $thisfile_real_chunks_currentchunk_logicalfileinfo_thislength);
254  //$thisfile_real_chunks_currentchunk_logicalfileinfo_offset += (6 + $thisfile_real_chunks_currentchunk_logicalfileinfo_thislength);
255 
256  break;
257 
258  }
259 
260 
261  if (empty($info['playtime_seconds'])) {
262  $info['playtime_seconds'] = max($info['playtime_seconds'], ($thisfile_real_chunks_currentchunk['duration'] + $thisfile_real_chunks_currentchunk['start_time']) / 1000);
263  }
264  if ($thisfile_real_chunks_currentchunk['duration'] > 0) {
265  switch ($thisfile_real_chunks_currentchunk['mime_type']) {
266  case 'audio/x-pn-realaudio':
267  case 'audio/x-pn-multirate-realaudio':
268  $info['audio']['bitrate'] = (isset($info['audio']['bitrate']) ? $info['audio']['bitrate'] : 0) + $thisfile_real_chunks_currentchunk['avg_bit_rate'];
269  $info['audio']['codec'] = $this->RealAudioCodecFourCClookup($thisfile_real_chunks_currentchunk['parsed_audio_data']['fourcc'], $info['audio']['bitrate']);
270  $info['audio']['dataformat'] = 'real';
271  $info['audio']['lossless'] = false;
272  break;
273 
274  case 'video/x-pn-realvideo':
275  case 'video/x-pn-multirate-realvideo':
276  $info['video']['bitrate'] = (isset($info['video']['bitrate']) ? $info['video']['bitrate'] : 0) + $thisfile_real_chunks_currentchunk['avg_bit_rate'];
277  $info['video']['bitrate_mode'] = 'cbr';
278  $info['video']['dataformat'] = 'real';
279  $info['video']['lossless'] = false;
280  $info['video']['pixel_aspect_ratio'] = (float) 1;
281  break;
282 
283  case 'audio/x-ralf-mpeg4-generic':
284  $info['audio']['bitrate'] = (isset($info['audio']['bitrate']) ? $info['audio']['bitrate'] : 0) + $thisfile_real_chunks_currentchunk['avg_bit_rate'];
285  $info['audio']['codec'] = 'RealAudio Lossless';
286  $info['audio']['dataformat'] = 'real';
287  $info['audio']['lossless'] = true;
288  break;
289  }
290  $info['bitrate'] = (isset($info['video']['bitrate']) ? $info['video']['bitrate'] : 0) + (isset($info['audio']['bitrate']) ? $info['audio']['bitrate'] : 0);
291  }
292  }
293  break;
294 
295  case 'CONT': // Content Description Header (text comments)
296  $thisfile_real_chunks_currentchunk['object_version'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
297  $offset += 2;
298  if ($thisfile_real_chunks_currentchunk['object_version'] == 0) {
299  $thisfile_real_chunks_currentchunk['title_len'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
300  $offset += 2;
301  $thisfile_real_chunks_currentchunk['title'] = (string) substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk['title_len']);
302  $offset += $thisfile_real_chunks_currentchunk['title_len'];
303 
304  $thisfile_real_chunks_currentchunk['artist_len'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
305  $offset += 2;
306  $thisfile_real_chunks_currentchunk['artist'] = (string) substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk['artist_len']);
307  $offset += $thisfile_real_chunks_currentchunk['artist_len'];
308 
309  $thisfile_real_chunks_currentchunk['copyright_len'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
310  $offset += 2;
311  $thisfile_real_chunks_currentchunk['copyright'] = (string) substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk['copyright_len']);
312  $offset += $thisfile_real_chunks_currentchunk['copyright_len'];
313 
314  $thisfile_real_chunks_currentchunk['comment_len'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
315  $offset += 2;
316  $thisfile_real_chunks_currentchunk['comment'] = (string) substr($ChunkData, $offset, $thisfile_real_chunks_currentchunk['comment_len']);
317  $offset += $thisfile_real_chunks_currentchunk['comment_len'];
318 
319 
320  $commentkeystocopy = array('title'=>'title', 'artist'=>'artist', 'copyright'=>'copyright', 'comment'=>'comment');
321  foreach ($commentkeystocopy as $key => $val) {
322  if ($thisfile_real_chunks_currentchunk[$key]) {
323  $info['real']['comments'][$val][] = trim($thisfile_real_chunks_currentchunk[$key]);
324  }
325  }
326 
327  }
328  break;
329 
330 
331  case 'DATA': // Data Chunk Header
332  // do nothing
333  break;
334 
335  case 'INDX': // Index Section Header
336  $thisfile_real_chunks_currentchunk['object_version'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
337  $offset += 2;
338  if ($thisfile_real_chunks_currentchunk['object_version'] == 0) {
339  $thisfile_real_chunks_currentchunk['num_indices'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
340  $offset += 4;
341  $thisfile_real_chunks_currentchunk['stream_number'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 2));
342  $offset += 2;
343  $thisfile_real_chunks_currentchunk['next_index_header'] = getid3_lib::BigEndian2Int(substr($ChunkData, $offset, 4));
344  $offset += 4;
345 
346  if ($thisfile_real_chunks_currentchunk['next_index_header'] == 0) {
347  // last index chunk found, ignore rest of file
348  break 2;
349  } else {
350  // non-last index chunk, seek to next index chunk (skipping actual index data)
351  $this->fseek($thisfile_real_chunks_currentchunk['next_index_header']);
352  }
353  }
354  break;
355 
356  default:
357  $this->warning('Unhandled RealMedia chunk "'.$ChunkName.'" at offset '.$thisfile_real_chunks_currentchunk['offset']);
358  break;
359  }
360  $ChunkCounter++;
361  }
362 
363  if (!empty($info['audio']['streams'])) {
364  $info['audio']['bitrate'] = 0;
365  foreach ($info['audio']['streams'] as $key => $valuearray) {
366  $info['audio']['bitrate'] += $valuearray['bitrate'];
367  }
368  }
369 
370  return true;
371  }
372 
373 
374  public function ParseOldRAheader($OldRAheaderData, &$ParsedArray) {
375  // http://www.freelists.org/archives/matroska-devel/07-2003/msg00010.html
376 
377  $ParsedArray = array();
378  $ParsedArray['magic'] = substr($OldRAheaderData, 0, 4);
379  if ($ParsedArray['magic'] != '.ra'."\xFD") {
380  return false;
381  }
382  $ParsedArray['version1'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 4, 2));
383 
384  if ($ParsedArray['version1'] < 3) {
385 
386  return false;
387 
388  } elseif ($ParsedArray['version1'] == 3) {
389 
390  $ParsedArray['fourcc1'] = '.ra3';
391  $ParsedArray['bits_per_sample'] = 16; // hard-coded for old versions?
392  $ParsedArray['sample_rate'] = 8000; // hard-coded for old versions?
393 
394  $ParsedArray['header_size'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 6, 2));
395  $ParsedArray['channels'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 8, 2)); // always 1 (?)
396  //$ParsedArray['unknown1'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 10, 2));
397  //$ParsedArray['unknown2'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 12, 2));
398  //$ParsedArray['unknown3'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 14, 2));
399  $ParsedArray['bytes_per_minute'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 16, 2));
400  $ParsedArray['audio_bytes'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 18, 4));
401  $ParsedArray['comments_raw'] = substr($OldRAheaderData, 22, $ParsedArray['header_size'] - 22 + 1); // not including null terminator
402 
403  $commentoffset = 0;
404  $commentlength = getid3_lib::BigEndian2Int(substr($ParsedArray['comments_raw'], $commentoffset++, 1));
405  $ParsedArray['comments']['title'][] = substr($ParsedArray['comments_raw'], $commentoffset, $commentlength);
406  $commentoffset += $commentlength;
407 
408  $commentlength = getid3_lib::BigEndian2Int(substr($ParsedArray['comments_raw'], $commentoffset++, 1));
409  $ParsedArray['comments']['artist'][] = substr($ParsedArray['comments_raw'], $commentoffset, $commentlength);
410  $commentoffset += $commentlength;
411 
412  $commentlength = getid3_lib::BigEndian2Int(substr($ParsedArray['comments_raw'], $commentoffset++, 1));
413  $ParsedArray['comments']['copyright'][] = substr($ParsedArray['comments_raw'], $commentoffset, $commentlength);
414  $commentoffset += $commentlength;
415 
416  $commentoffset++; // final null terminator (?)
417  $commentoffset++; // fourcc length (?) should be 4
418  $ParsedArray['fourcc'] = substr($OldRAheaderData, 23 + $commentoffset, 4);
419 
420  } elseif ($ParsedArray['version1'] <= 5) {
421 
422  //$ParsedArray['unknown1'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 6, 2));
423  $ParsedArray['fourcc1'] = substr($OldRAheaderData, 8, 4);
424  $ParsedArray['file_size'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 12, 4));
425  $ParsedArray['version2'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 16, 2));
426  $ParsedArray['header_size'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 18, 4));
427  $ParsedArray['codec_flavor_id'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 22, 2));
428  $ParsedArray['coded_frame_size'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 24, 4));
429  $ParsedArray['audio_bytes'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 28, 4));
430  $ParsedArray['bytes_per_minute'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 32, 4));
431  //$ParsedArray['unknown5'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 36, 4));
432  $ParsedArray['sub_packet_h'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 40, 2));
433  $ParsedArray['frame_size'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 42, 2));
434  $ParsedArray['sub_packet_size'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 44, 2));
435  //$ParsedArray['unknown6'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 46, 2));
436 
437  switch ($ParsedArray['version1']) {
438 
439  case 4:
440  $ParsedArray['sample_rate'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 48, 2));
441  //$ParsedArray['unknown8'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 50, 2));
442  $ParsedArray['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 52, 2));
443  $ParsedArray['channels'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 54, 2));
444  $ParsedArray['length_fourcc2'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 56, 1));
445  $ParsedArray['fourcc2'] = substr($OldRAheaderData, 57, 4);
446  $ParsedArray['length_fourcc3'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 61, 1));
447  $ParsedArray['fourcc3'] = substr($OldRAheaderData, 62, 4);
448  //$ParsedArray['unknown9'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 66, 1));
449  //$ParsedArray['unknown10'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 67, 2));
450  $ParsedArray['comments_raw'] = substr($OldRAheaderData, 69, $ParsedArray['header_size'] - 69 + 16);
451 
452  $commentoffset = 0;
453  $commentlength = getid3_lib::BigEndian2Int(substr($ParsedArray['comments_raw'], $commentoffset++, 1));
454  $ParsedArray['comments']['title'][] = substr($ParsedArray['comments_raw'], $commentoffset, $commentlength);
455  $commentoffset += $commentlength;
456 
457  $commentlength = getid3_lib::BigEndian2Int(substr($ParsedArray['comments_raw'], $commentoffset++, 1));
458  $ParsedArray['comments']['artist'][] = substr($ParsedArray['comments_raw'], $commentoffset, $commentlength);
459  $commentoffset += $commentlength;
460 
461  $commentlength = getid3_lib::BigEndian2Int(substr($ParsedArray['comments_raw'], $commentoffset++, 1));
462  $ParsedArray['comments']['copyright'][] = substr($ParsedArray['comments_raw'], $commentoffset, $commentlength);
463  $commentoffset += $commentlength;
464  break;
465 
466  case 5:
467  $ParsedArray['sample_rate'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 48, 4));
468  $ParsedArray['sample_rate2'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 52, 4));
469  $ParsedArray['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 56, 4));
470  $ParsedArray['channels'] = getid3_lib::BigEndian2Int(substr($OldRAheaderData, 60, 2));
471  $ParsedArray['genr'] = substr($OldRAheaderData, 62, 4);
472  $ParsedArray['fourcc3'] = substr($OldRAheaderData, 66, 4);
473  $ParsedArray['comments'] = array();
474  break;
475  }
476  $ParsedArray['fourcc'] = $ParsedArray['fourcc3'];
477 
478  }
479  foreach ($ParsedArray['comments'] as $key => $value) {
480  if ($ParsedArray['comments'][$key][0] === false) {
481  $ParsedArray['comments'][$key][0] = '';
482  }
483  }
484 
485  return true;
486  }
487 
488  public function RealAudioCodecFourCClookup($fourcc, $bitrate) {
489  static $RealAudioCodecFourCClookup = array();
490  if (empty($RealAudioCodecFourCClookup)) {
491  // http://www.its.msstate.edu/net/real/reports/config/tags.stats
492  // http://www.freelists.org/archives/matroska-devel/06-2003/fullthread18.html
493 
494  $RealAudioCodecFourCClookup['14_4'][8000] = 'RealAudio v2 (14.4kbps)';
495  $RealAudioCodecFourCClookup['14.4'][8000] = 'RealAudio v2 (14.4kbps)';
496  $RealAudioCodecFourCClookup['lpcJ'][8000] = 'RealAudio v2 (14.4kbps)';
497  $RealAudioCodecFourCClookup['28_8'][15200] = 'RealAudio v2 (28.8kbps)';
498  $RealAudioCodecFourCClookup['28.8'][15200] = 'RealAudio v2 (28.8kbps)';
499  $RealAudioCodecFourCClookup['sipr'][4933] = 'RealAudio v4 (5kbps Voice)';
500  $RealAudioCodecFourCClookup['sipr'][6444] = 'RealAudio v4 (6.5kbps Voice)';
501  $RealAudioCodecFourCClookup['sipr'][8444] = 'RealAudio v4 (8.5kbps Voice)';
502  $RealAudioCodecFourCClookup['sipr'][16000] = 'RealAudio v4 (16kbps Wideband)';
503  $RealAudioCodecFourCClookup['dnet'][8000] = 'RealAudio v3 (8kbps Music)';
504  $RealAudioCodecFourCClookup['dnet'][16000] = 'RealAudio v3 (16kbps Music Low Response)';
505  $RealAudioCodecFourCClookup['dnet'][15963] = 'RealAudio v3 (16kbps Music Mid/High Response)';
506  $RealAudioCodecFourCClookup['dnet'][20000] = 'RealAudio v3 (20kbps Music Stereo)';
507  $RealAudioCodecFourCClookup['dnet'][32000] = 'RealAudio v3 (32kbps Music Mono)';
508  $RealAudioCodecFourCClookup['dnet'][31951] = 'RealAudio v3 (32kbps Music Stereo)';
509  $RealAudioCodecFourCClookup['dnet'][39965] = 'RealAudio v3 (40kbps Music Mono)';
510  $RealAudioCodecFourCClookup['dnet'][40000] = 'RealAudio v3 (40kbps Music Stereo)';
511  $RealAudioCodecFourCClookup['dnet'][79947] = 'RealAudio v3 (80kbps Music Mono)';
512  $RealAudioCodecFourCClookup['dnet'][80000] = 'RealAudio v3 (80kbps Music Stereo)';
513 
514  $RealAudioCodecFourCClookup['dnet'][0] = 'RealAudio v3';
515  $RealAudioCodecFourCClookup['sipr'][0] = 'RealAudio v4';
516  $RealAudioCodecFourCClookup['cook'][0] = 'RealAudio G2';
517  $RealAudioCodecFourCClookup['atrc'][0] = 'RealAudio 8';
518  }
519  $roundbitrate = intval(round($bitrate));
520  if (isset($RealAudioCodecFourCClookup[$fourcc][$roundbitrate])) {
521  return $RealAudioCodecFourCClookup[$fourcc][$roundbitrate];
522  } elseif (isset($RealAudioCodecFourCClookup[$fourcc][0])) {
523  return $RealAudioCodecFourCClookup[$fourcc][0];
524  }
525  return $fourcc;
526  }
527 
528 }
Add rich text string
error($text)
Definition: getid3.php:1752
RealAudioCodecFourCClookup($fourcc, $bitrate)
warning($text)
Definition: getid3.php:1758
static IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
static fourccLookup($fourcc)
fread($bytes)
Definition: getid3.php:1683
Create styles array
The data for the language used.
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1711
$info
Definition: index.php:5
$key
Definition: croninfo.php:18
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:263
ParseOldRAheader($OldRAheaderData, &$ParsedArray)