annotate e2gallerypro/e2upload/Backend/Assets/getid3/module.audio-video.real.php @ 20:1038db2374ec judyates

change address
author Robert McIntyre <rlm@mit.edu>
date Sun, 08 Sep 2013 00:47:09 -0400
parents 3f6b44aa6b35
children
rev   line source
rlm@3 1 <?php
rlm@3 2 // +----------------------------------------------------------------------+
rlm@3 3 // | PHP version 5 |
rlm@3 4 // +----------------------------------------------------------------------+
rlm@3 5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
rlm@3 6 // +----------------------------------------------------------------------+
rlm@3 7 // | This source file is subject to version 2 of the GPL license, |
rlm@3 8 // | that is bundled with this package in the file license.txt and is |
rlm@3 9 // | available through the world-wide-web at the following url: |
rlm@3 10 // | http://www.gnu.org/copyleft/gpl.html |
rlm@3 11 // +----------------------------------------------------------------------+
rlm@3 12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
rlm@3 13 // +----------------------------------------------------------------------+
rlm@3 14 // | Authors: James Heinrich <infoØgetid3*org> |
rlm@3 15 // | Allan Hansen <ahØartemis*dk> |
rlm@3 16 // +----------------------------------------------------------------------+
rlm@3 17 // | module.audio-video.real.php |
rlm@3 18 // | Module for analyzing Real Audio/Video files |
rlm@3 19 // | dependencies: module.audio-video.riff.php |
rlm@3 20 // +----------------------------------------------------------------------+
rlm@3 21 //
rlm@3 22 // $Id: module.audio-video.real.php,v 1.4 2006/11/02 10:48:00 ah Exp $
rlm@3 23
rlm@3 24
rlm@3 25
rlm@3 26 class getid3_real extends getid3_handler
rlm@3 27 {
rlm@3 28
rlm@3 29 public function Analyze() {
rlm@3 30
rlm@3 31 $getid3 = $this->getid3;
rlm@3 32
rlm@3 33 $getid3->include_module('audio-video.riff');
rlm@3 34
rlm@3 35 $getid3->info['fileformat'] = 'real';
rlm@3 36 $getid3->info['bitrate'] = 0;
rlm@3 37 $getid3->info['playtime_seconds'] = 0;
rlm@3 38
rlm@3 39 fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
rlm@3 40 $chunk_counter = 0;
rlm@3 41
rlm@3 42 while (ftell($getid3->fp) < $getid3->info['avdataend']) {
rlm@3 43
rlm@3 44 $chunk_data = fread($getid3->fp, 8);
rlm@3 45 $chunk_name = substr($chunk_data, 0, 4);
rlm@3 46 $chunk_size = getid3_lib::BigEndian2Int(substr($chunk_data, 4, 4));
rlm@3 47
rlm@3 48 if ($chunk_name == '.ra'."\xFD") {
rlm@3 49 $chunk_data .= fread($getid3->fp, $chunk_size - 8);
rlm@3 50
rlm@3 51 if ($this->ParseOldRAheader(substr($chunk_data, 0, 128), $getid3->info['real']['old_ra_header'])) {
rlm@3 52
rlm@3 53 $getid3->info['audio']['dataformat'] = 'real';
rlm@3 54 $getid3->info['audio']['lossless'] = false;
rlm@3 55 $getid3->info['audio']['sample_rate'] = $getid3->info['real']['old_ra_header']['sample_rate'];
rlm@3 56 $getid3->info['audio']['bits_per_sample'] = $getid3->info['real']['old_ra_header']['bits_per_sample'];
rlm@3 57 $getid3->info['audio']['channels'] = $getid3->info['real']['old_ra_header']['channels'];
rlm@3 58
rlm@3 59 $getid3->info['playtime_seconds'] = 60 * ($getid3->info['real']['old_ra_header']['audio_bytes'] / $getid3->info['real']['old_ra_header']['bytes_per_minute']);
rlm@3 60 $getid3->info['audio']['bitrate'] = 8 * ($getid3->info['real']['old_ra_header']['audio_bytes'] / $getid3->info['playtime_seconds']);
rlm@3 61 $getid3->info['audio']['codec'] = $this->RealAudioCodecFourCClookup($getid3->info['real']['old_ra_header']['fourcc'], $getid3->info['audio']['bitrate']);
rlm@3 62
rlm@3 63 foreach ($getid3->info['real']['old_ra_header']['comments'] as $key => $value_array) {
rlm@3 64
rlm@3 65 if (strlen(trim($value_array[0])) > 0) {
rlm@3 66 $getid3->info['real']['comments'][$key][] = trim($value_array[0]);
rlm@3 67 }
rlm@3 68 }
rlm@3 69 return true;
rlm@3 70 }
rlm@3 71
rlm@3 72 throw new getid3_exception('There was a problem parsing this RealAudio file. Please submit it for analysis to http://www.getid3.org/upload/ or info@getid3.org');
rlm@3 73 }
rlm@3 74
rlm@3 75 $getid3->info['real']['chunks'][$chunk_counter] = array ();
rlm@3 76 $info_real_chunks_current_chunk = &$getid3->info['real']['chunks'][$chunk_counter];
rlm@3 77
rlm@3 78 $info_real_chunks_current_chunk['name'] = $chunk_name;
rlm@3 79 $info_real_chunks_current_chunk['offset'] = ftell($getid3->fp) - 8;
rlm@3 80 $info_real_chunks_current_chunk['length'] = $chunk_size;
rlm@3 81
rlm@3 82 if (($info_real_chunks_current_chunk['offset'] + $info_real_chunks_current_chunk['length']) > $getid3->info['avdataend']) {
rlm@3 83 $getid3->warning('Chunk "'.$info_real_chunks_current_chunk['name'].'" at offset '.$info_real_chunks_current_chunk['offset'].' claims to be '.$info_real_chunks_current_chunk['length'].' bytes long, which is beyond end of file');
rlm@3 84 return false;
rlm@3 85 }
rlm@3 86
rlm@3 87 if ($chunk_size > (getid3::FREAD_BUFFER_SIZE + 8)) {
rlm@3 88 $chunk_data .= fread($getid3->fp, getid3::FREAD_BUFFER_SIZE - 8);
rlm@3 89 fseek($getid3->fp, $info_real_chunks_current_chunk['offset'] + $chunk_size, SEEK_SET);
rlm@3 90
rlm@3 91 } elseif(($chunk_size - 8) > 0) {
rlm@3 92 $chunk_data .= fread($getid3->fp, $chunk_size - 8);
rlm@3 93 }
rlm@3 94 $offset = 8;
rlm@3 95
rlm@3 96 switch ($chunk_name) {
rlm@3 97
rlm@3 98 case '.RMF': // RealMedia File Header
rlm@3 99
rlm@3 100 $info_real_chunks_current_chunk['object_version'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 101 $offset += 2;
rlm@3 102
rlm@3 103 switch ($info_real_chunks_current_chunk['object_version']) {
rlm@3 104
rlm@3 105 case 0:
rlm@3 106 $info_real_chunks_current_chunk['file_version'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 4));
rlm@3 107 $offset += 4;
rlm@3 108
rlm@3 109 $info_real_chunks_current_chunk['headers_count'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 4));
rlm@3 110 $offset += 4;
rlm@3 111 break;
rlm@3 112
rlm@3 113 default:
rlm@3 114 //$getid3->warning('Expected .RMF-object_version to be "0", actual value is "'.$info_real_chunks_current_chunk['object_version'].'" (should not be a problem)';
rlm@3 115 break;
rlm@3 116
rlm@3 117 }
rlm@3 118 break;
rlm@3 119
rlm@3 120
rlm@3 121 case 'PROP': // Properties Header
rlm@3 122
rlm@3 123 $info_real_chunks_current_chunk['object_version'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 124 $offset += 2;
rlm@3 125
rlm@3 126 if ($info_real_chunks_current_chunk['object_version'] == 0) {
rlm@3 127
rlm@3 128 getid3_lib::ReadSequence('BigEndian2Int', $info_real_chunks_current_chunk, $chunk_data, $offset,
rlm@3 129 array (
rlm@3 130 'max_bit_rate' => 4,
rlm@3 131 'avg_bit_rate' => 4,
rlm@3 132 'max_packet_size' => 4,
rlm@3 133 'avg_packet_size' => 4,
rlm@3 134 'num_packets' => 4,
rlm@3 135 'duration' => 4,
rlm@3 136 'preroll' => 4,
rlm@3 137 'index_offset' => 4,
rlm@3 138 'data_offset' => 4,
rlm@3 139 'num_streams' => 2,
rlm@3 140 'flags_raw' => 2
rlm@3 141 )
rlm@3 142 );
rlm@3 143 $offset += 40;
rlm@3 144
rlm@3 145 $getid3->info['playtime_seconds'] = $info_real_chunks_current_chunk['duration'] / 1000;
rlm@3 146 if ($info_real_chunks_current_chunk['duration'] > 0) {
rlm@3 147 $getid3->info['bitrate'] += $info_real_chunks_current_chunk['avg_bit_rate'];
rlm@3 148 }
rlm@3 149
rlm@3 150 $info_real_chunks_current_chunk['flags']['save_enabled'] = (bool)($info_real_chunks_current_chunk['flags_raw'] & 0x0001);
rlm@3 151 $info_real_chunks_current_chunk['flags']['perfect_play'] = (bool)($info_real_chunks_current_chunk['flags_raw'] & 0x0002);
rlm@3 152 $info_real_chunks_current_chunk['flags']['live_broadcast'] = (bool)($info_real_chunks_current_chunk['flags_raw'] & 0x0004);
rlm@3 153 }
rlm@3 154 break;
rlm@3 155
rlm@3 156
rlm@3 157 case 'MDPR': // Media Properties Header
rlm@3 158
rlm@3 159 $info_real_chunks_current_chunk['object_version'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 160 $offset += 2;
rlm@3 161
rlm@3 162 if ($info_real_chunks_current_chunk['object_version'] == 0) {
rlm@3 163
rlm@3 164 getid3_lib::ReadSequence('BigEndian2Int', $info_real_chunks_current_chunk, $chunk_data, $offset,
rlm@3 165 array (
rlm@3 166 'stream_number' => 2,
rlm@3 167 'max_bit_rate' => 4,
rlm@3 168 'avg_bit_rate' => 4,
rlm@3 169 'max_packet_size' => 4,
rlm@3 170 'avg_packet_size' => 4,
rlm@3 171 'start_time' => 4,
rlm@3 172 'preroll' => 4,
rlm@3 173 'duration' => 4,
rlm@3 174 'stream_name_size' => 1
rlm@3 175 )
rlm@3 176 );
rlm@3 177 $offset += 31;
rlm@3 178
rlm@3 179 $info_real_chunks_current_chunk['stream_name'] = substr($chunk_data, $offset, $info_real_chunks_current_chunk['stream_name_size']);
rlm@3 180 $offset += $info_real_chunks_current_chunk['stream_name_size'];
rlm@3 181
rlm@3 182 $info_real_chunks_current_chunk['mime_type_size'] = getid3_lib::BigEndian2Int($chunk_data{$offset++});
rlm@3 183
rlm@3 184 $info_real_chunks_current_chunk['mime_type'] = substr($chunk_data, $offset, $info_real_chunks_current_chunk['mime_type_size']);
rlm@3 185 $offset += $info_real_chunks_current_chunk['mime_type_size'];
rlm@3 186
rlm@3 187 $info_real_chunks_current_chunk['type_specific_len'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 4));
rlm@3 188 $offset += 4;
rlm@3 189
rlm@3 190 $info_real_chunks_current_chunk['type_specific_data'] = substr($chunk_data, $offset, $info_real_chunks_current_chunk['type_specific_len']);
rlm@3 191 $offset += $info_real_chunks_current_chunk['type_specific_len'];
rlm@3 192
rlm@3 193 $info_real_chunks_current_chunk_typespecificdata = &$info_real_chunks_current_chunk['type_specific_data'];
rlm@3 194
rlm@3 195 switch ($info_real_chunks_current_chunk['mime_type']) {
rlm@3 196
rlm@3 197 case 'video/x-pn-realvideo':
rlm@3 198 case 'video/x-pn-multirate-realvideo':
rlm@3 199 // http://www.freelists.org/archives/matroska-devel/07-2003/msg00010.html
rlm@3 200
rlm@3 201 $info_real_chunks_current_chunk['video_info'] = array ();
rlm@3 202 $info_real_chunks_current_chunk_video_info = &$info_real_chunks_current_chunk['video_info'];
rlm@3 203
rlm@3 204 getid3_lib::ReadSequence('BigEndian2Int', $info_real_chunks_current_chunk_video_info, $info_real_chunks_current_chunk_typespecificdata, 0,
rlm@3 205 array (
rlm@3 206 'dwSize' => 4,
rlm@3 207 'fourcc1' => -4,
rlm@3 208 'fourcc2' => -4,
rlm@3 209 'width' => 2,
rlm@3 210 'height' => 2,
rlm@3 211 'bits_per_sample' => 2,
rlm@3 212 'IGNORE-unknown1' => 2,
rlm@3 213 'IGNORE-unknown2' => 2,
rlm@3 214 'frames_per_second' => 2,
rlm@3 215 'IGNORE-unknown3' => 2,
rlm@3 216 'IGNORE-unknown4' => 2,
rlm@3 217 'IGNORE-unknown5' => 2,
rlm@3 218 'IGNORE-unknown6' => 2,
rlm@3 219 'IGNORE-unknown7' => 2,
rlm@3 220 'IGNORE-unknown8' => 2,
rlm@3 221 'IGNORE-unknown9' => 2
rlm@3 222 )
rlm@3 223 );
rlm@3 224
rlm@3 225 $info_real_chunks_current_chunk_video_info['codec'] = getid3_riff::RIFFfourccLookup($info_real_chunks_current_chunk_video_info['fourcc2']);
rlm@3 226
rlm@3 227 $getid3->info['video']['resolution_x'] = $info_real_chunks_current_chunk_video_info['width'];
rlm@3 228 $getid3->info['video']['resolution_y'] = $info_real_chunks_current_chunk_video_info['height'];
rlm@3 229 $getid3->info['video']['frame_rate'] = (float)$info_real_chunks_current_chunk_video_info['frames_per_second'];
rlm@3 230 $getid3->info['video']['codec'] = $info_real_chunks_current_chunk_video_info['codec'];
rlm@3 231 $getid3->info['video']['bits_per_sample'] = $info_real_chunks_current_chunk_video_info['bits_per_sample'];
rlm@3 232 break;
rlm@3 233
rlm@3 234
rlm@3 235 case 'audio/x-pn-realaudio':
rlm@3 236 case 'audio/x-pn-multirate-realaudio':
rlm@3 237
rlm@3 238 $this->ParseOldRAheader($info_real_chunks_current_chunk_typespecificdata, $info_real_chunks_current_chunk['parsed_audio_data']);
rlm@3 239
rlm@3 240 $getid3->info['audio']['sample_rate'] = $info_real_chunks_current_chunk['parsed_audio_data']['sample_rate'];
rlm@3 241 $getid3->info['audio']['bits_per_sample'] = $info_real_chunks_current_chunk['parsed_audio_data']['bits_per_sample'];
rlm@3 242 $getid3->info['audio']['channels'] = $info_real_chunks_current_chunk['parsed_audio_data']['channels'];
rlm@3 243
rlm@3 244 if (!empty($getid3->info['audio']['dataformat'])) {
rlm@3 245 foreach ($getid3->info['audio'] as $key => $value) {
rlm@3 246 if ($key != 'streams') {
rlm@3 247 $getid3->info['audio']['streams'][$info_real_chunks_current_chunk['stream_number']][$key] = $value;
rlm@3 248 }
rlm@3 249 }
rlm@3 250 }
rlm@3 251 break;
rlm@3 252
rlm@3 253
rlm@3 254 case 'logical-fileinfo':
rlm@3 255
rlm@3 256 $info_real_chunks_current_chunk['logical_fileinfo']['logical_fileinfo_length'] = getid3_lib::BigEndian2Int(substr($info_real_chunks_current_chunk_typespecificdata, 0, 4));
rlm@3 257 // $info_real_chunks_current_chunk['logical_fileinfo']['IGNORE-unknown1'] = getid3_lib::BigEndian2Int(substr($info_real_chunks_current_chunk_typespecificdata, 4, 4));
rlm@3 258 $info_real_chunks_current_chunk['logical_fileinfo']['num_tags'] = getid3_lib::BigEndian2Int(substr($info_real_chunks_current_chunk_typespecificdata, 8, 4));
rlm@3 259 // $info_real_chunks_current_chunk['logical_fileinfo']['IGNORE-unknown2'] = getid3_lib::BigEndian2Int(substr($info_real_chunks_current_chunk_typespecificdata, 12, 4));
rlm@3 260 break;
rlm@3 261
rlm@3 262 }
rlm@3 263
rlm@3 264
rlm@3 265 if (empty($getid3->info['playtime_seconds'])) {
rlm@3 266 $getid3->info['playtime_seconds'] = max($getid3->info['playtime_seconds'], ($info_real_chunks_current_chunk['duration'] + $info_real_chunks_current_chunk['start_time']) / 1000);
rlm@3 267 }
rlm@3 268
rlm@3 269 if ($info_real_chunks_current_chunk['duration'] > 0) {
rlm@3 270
rlm@3 271 switch ($info_real_chunks_current_chunk['mime_type']) {
rlm@3 272
rlm@3 273 case 'audio/x-pn-realaudio':
rlm@3 274 case 'audio/x-pn-multirate-realaudio':
rlm@3 275
rlm@3 276 $getid3->info['audio']['bitrate'] = (isset($getid3->info['audio']['bitrate']) ? $getid3->info['audio']['bitrate'] : 0) + $info_real_chunks_current_chunk['avg_bit_rate'];
rlm@3 277 $getid3->info['audio']['codec'] = $this->RealAudioCodecFourCClookup($info_real_chunks_current_chunk['parsed_audio_data']['fourcc'], $getid3->info['audio']['bitrate']);
rlm@3 278 $getid3->info['audio']['dataformat'] = 'real';
rlm@3 279 $getid3->info['audio']['lossless'] = false;
rlm@3 280 break;
rlm@3 281
rlm@3 282
rlm@3 283 case 'video/x-pn-realvideo':
rlm@3 284 case 'video/x-pn-multirate-realvideo':
rlm@3 285
rlm@3 286 $getid3->info['video']['bitrate'] = (isset($getid3->info['video']['bitrate']) ? $getid3->info['video']['bitrate'] : 0) + $info_real_chunks_current_chunk['avg_bit_rate'];
rlm@3 287 $getid3->info['video']['bitrate_mode'] = 'cbr';
rlm@3 288 $getid3->info['video']['dataformat'] = 'real';
rlm@3 289 $getid3->info['video']['lossless'] = false;
rlm@3 290 $getid3->info['video']['pixel_aspect_ratio'] = (float)1;
rlm@3 291 break;
rlm@3 292
rlm@3 293
rlm@3 294 case 'audio/x-ralf-mpeg4-generic':
rlm@3 295
rlm@3 296 $getid3->info['audio']['bitrate'] = (isset($getid3->info['audio']['bitrate']) ? $getid3->info['audio']['bitrate'] : 0) + $info_real_chunks_current_chunk['avg_bit_rate'];
rlm@3 297 $getid3->info['audio']['codec'] = 'RealAudio Lossless';
rlm@3 298 $getid3->info['audio']['dataformat'] = 'real';
rlm@3 299 $getid3->info['audio']['lossless'] = true;
rlm@3 300 break;
rlm@3 301
rlm@3 302 }
rlm@3 303
rlm@3 304 $getid3->info['bitrate'] = (isset($getid3->info['video']['bitrate']) ? $getid3->info['video']['bitrate'] : 0) + (isset($getid3->info['audio']['bitrate']) ? $getid3->info['audio']['bitrate'] : 0);
rlm@3 305 }
rlm@3 306 }
rlm@3 307 break;
rlm@3 308
rlm@3 309
rlm@3 310 case 'CONT': // Content Description Header (text comments)
rlm@3 311
rlm@3 312 $info_real_chunks_current_chunk['object_version'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 313 $offset += 2;
rlm@3 314
rlm@3 315 if ($info_real_chunks_current_chunk['object_version'] == 0) {
rlm@3 316
rlm@3 317 $info_real_chunks_current_chunk['title_len'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 318 $offset += 2;
rlm@3 319
rlm@3 320 $info_real_chunks_current_chunk['title'] = (string) substr($chunk_data, $offset, $info_real_chunks_current_chunk['title_len']);
rlm@3 321 $offset += $info_real_chunks_current_chunk['title_len'];
rlm@3 322
rlm@3 323 $info_real_chunks_current_chunk['artist_len'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 324 $offset += 2;
rlm@3 325
rlm@3 326 $info_real_chunks_current_chunk['artist'] = (string) substr($chunk_data, $offset, $info_real_chunks_current_chunk['artist_len']);
rlm@3 327 $offset += $info_real_chunks_current_chunk['artist_len'];
rlm@3 328
rlm@3 329 $info_real_chunks_current_chunk['copyright_len'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 330 $offset += 2;
rlm@3 331
rlm@3 332 $info_real_chunks_current_chunk['copyright'] = (string) substr($chunk_data, $offset, $info_real_chunks_current_chunk['copyright_len']);
rlm@3 333 $offset += $info_real_chunks_current_chunk['copyright_len'];
rlm@3 334
rlm@3 335 $info_real_chunks_current_chunk['comment_len'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 336 $offset += 2;
rlm@3 337
rlm@3 338 $info_real_chunks_current_chunk['comment'] = (string) substr($chunk_data, $offset, $info_real_chunks_current_chunk['comment_len']);
rlm@3 339 $offset += $info_real_chunks_current_chunk['comment_len'];
rlm@3 340
rlm@3 341 foreach (array ('title'=>'title', 'artist'=>'artist', 'copyright'=>'copyright', 'comment'=>'comment') as $key => $val) {
rlm@3 342 if ($info_real_chunks_current_chunk[$key]) {
rlm@3 343 $getid3->info['real']['comments'][$val][] = trim($info_real_chunks_current_chunk[$key]);
rlm@3 344 }
rlm@3 345 }
rlm@3 346 }
rlm@3 347 break;
rlm@3 348
rlm@3 349
rlm@3 350 case 'DATA': // Data Chunk Header
rlm@3 351
rlm@3 352 // do nothing
rlm@3 353 break;
rlm@3 354
rlm@3 355
rlm@3 356 case 'INDX': // Index Section Header
rlm@3 357
rlm@3 358 $info_real_chunks_current_chunk['object_version'] = getid3_lib::BigEndian2Int(substr($chunk_data, $offset, 2));
rlm@3 359 $offset += 2;
rlm@3 360
rlm@3 361 if ($info_real_chunks_current_chunk['object_version'] == 0) {
rlm@3 362
rlm@3 363 getid3_lib::ReadSequence('BigEndian2Int', $info_real_chunks_current_chunk, $chunk_data, $offset,
rlm@3 364 array (
rlm@3 365 'num_indices' => 4,
rlm@3 366 'stream_number' => 2,
rlm@3 367 'next_index_header' => 4
rlm@3 368 )
rlm@3 369 );
rlm@3 370 $offset += 10;
rlm@3 371
rlm@3 372 if ($info_real_chunks_current_chunk['next_index_header'] == 0) {
rlm@3 373 // last index chunk found, ignore rest of file
rlm@3 374 break 2;
rlm@3 375 } else {
rlm@3 376 // non-last index chunk, seek to next index chunk (skipping actual index data)
rlm@3 377 fseek($getid3->fp, $info_real_chunks_current_chunk['next_index_header'], SEEK_SET);
rlm@3 378 }
rlm@3 379 }
rlm@3 380 break;
rlm@3 381
rlm@3 382
rlm@3 383 default:
rlm@3 384 $getid3->warning('Unhandled RealMedia chunk "'.$chunk_name.'" at offset '.$info_real_chunks_current_chunk['offset']);
rlm@3 385 break;
rlm@3 386 }
rlm@3 387 $chunk_counter++;
rlm@3 388 }
rlm@3 389
rlm@3 390 if (!empty($getid3->info['audio']['streams'])) {
rlm@3 391
rlm@3 392 $getid3->info['audio']['bitrate'] = 0;
rlm@3 393
rlm@3 394 foreach ($getid3->info['audio']['streams'] as $key => $value_array) {
rlm@3 395 $getid3->info['audio']['bitrate'] += $value_array['bitrate'];
rlm@3 396 }
rlm@3 397 }
rlm@3 398
rlm@3 399 return true;
rlm@3 400 }
rlm@3 401
rlm@3 402
rlm@3 403
rlm@3 404 public static function ParseOldRAheader($old_ra_header_data, &$parsed_array) {
rlm@3 405
rlm@3 406 // http://www.freelists.org/archives/matroska-devel/07-2003/msg00010.html
rlm@3 407
rlm@3 408 $parsed_array = array ();
rlm@3 409 $parsed_array['magic'] = substr($old_ra_header_data, 0, 4);
rlm@3 410
rlm@3 411 if ($parsed_array['magic'] != '.ra'."\xFD") {
rlm@3 412 return false;
rlm@3 413 }
rlm@3 414
rlm@3 415 $parsed_array['version1'] = getid3_lib::BigEndian2Int(substr($old_ra_header_data, 4, 2));
rlm@3 416
rlm@3 417 if ($parsed_array['version1'] < 3) {
rlm@3 418
rlm@3 419 return false;
rlm@3 420 }
rlm@3 421
rlm@3 422 if ($parsed_array['version1'] == 3) {
rlm@3 423
rlm@3 424 $parsed_array['fourcc1'] = '.ra3';
rlm@3 425 $parsed_array['bits_per_sample'] = 16; // hard-coded for old versions?
rlm@3 426 $parsed_array['sample_rate'] = 8000; // hard-coded for old versions?
rlm@3 427
rlm@3 428 getid3_lib::ReadSequence('BigEndian2Int', $parsed_array, $old_ra_header_data, 6,
rlm@3 429 array (
rlm@3 430 'header_size' => 2,
rlm@3 431 'channels' => 2, // always 1 (?)
rlm@3 432 'IGNORE-unknown1' => 2,
rlm@3 433 'IGNORE-unknown2' => 2,
rlm@3 434 'IGNORE-unknown3' => 2,
rlm@3 435 'bytes_per_minute' => 2,
rlm@3 436 'audio_bytes' => 4,
rlm@3 437 )
rlm@3 438 );
rlm@3 439
rlm@3 440 $parsed_array['comments_raw'] = substr($old_ra_header_data, 22, $parsed_array['header_size'] - 22 + 1); // not including null terminator
rlm@3 441
rlm@3 442 $comment_offset = 0;
rlm@3 443
rlm@3 444 foreach (array ('title', 'artist', 'copyright') as $name) {
rlm@3 445 $comment_length = getid3_lib::BigEndian2Int($parsed_array['comments_raw']{$comment_offset++});
rlm@3 446 $parsed_array['comments'][$name][]= substr($parsed_array['comments_raw'], $comment_offset, $comment_length);
rlm@3 447 $comment_offset += $comment_length;
rlm@3 448 }
rlm@3 449
rlm@3 450 $comment_offset++; // final null terminator (?)
rlm@3 451 $comment_offset++; // fourcc length (?) should be 4
rlm@3 452
rlm@3 453 $parsed_array['fourcc'] = substr($old_ra_header_data, 23 + $comment_offset, 4);
rlm@3 454
rlm@3 455
rlm@3 456 } elseif ($parsed_array['version1'] <= 5) {
rlm@3 457
rlm@3 458 getid3_lib::ReadSequence('BigEndian2Int', $parsed_array, $old_ra_header_data, 6,
rlm@3 459 array (
rlm@3 460 'IGNORE-unknown1' => 2,
rlm@3 461 'fourcc1' => -4,
rlm@3 462 'file_size' => 4,
rlm@3 463 'version2' => 2,
rlm@3 464 'header_size' => 4,
rlm@3 465 'codec_flavor_id' => 2,
rlm@3 466 'coded_frame_size' => 4,
rlm@3 467 'audio_bytes' => 4,
rlm@3 468 'bytes_per_minute' => 4,
rlm@3 469 'IGNORE-unknown5' => 4,
rlm@3 470 'sub_packet_h' => 2,
rlm@3 471 'frame_size' => 2,
rlm@3 472 'sub_packet_size' => 2,
rlm@3 473 'IGNORE-unknown6' => 2
rlm@3 474 )
rlm@3 475 );
rlm@3 476
rlm@3 477 switch ($parsed_array['version1']) {
rlm@3 478
rlm@3 479 case 4:
rlm@3 480
rlm@3 481 getid3_lib::ReadSequence('BigEndian2Int', $parsed_array, $old_ra_header_data, 48,
rlm@3 482 array (
rlm@3 483 'sample_rate' => 2,
rlm@3 484 'IGNORE-unknown8' => 2,
rlm@3 485 'bits_per_sample' => 2,
rlm@3 486 'channels' => 2,
rlm@3 487 'length_fourcc2' => 1,
rlm@3 488 'fourcc2' => -4,
rlm@3 489 'length_fourcc3' => 1,
rlm@3 490 'fourcc3' => -4,
rlm@3 491 'IGNORE-unknown9' => 1,
rlm@3 492 'IGNORE-unknown10' => 2,
rlm@3 493 )
rlm@3 494 );
rlm@3 495
rlm@3 496 $parsed_array['comments_raw'] = substr($old_ra_header_data, 69, $parsed_array['header_size'] - 69 + 16);
rlm@3 497
rlm@3 498 $comment_offset = 0;
rlm@3 499
rlm@3 500 foreach (array ('title', 'artist', 'copyright') as $name) {
rlm@3 501 $comment_length = getid3_lib::BigEndian2Int($parsed_array['comments_raw']{$comment_offset++});
rlm@3 502 $parsed_array['comments'][$name][]= substr($parsed_array['comments_raw'], $comment_offset, $comment_length);
rlm@3 503 $comment_offset += $comment_length;
rlm@3 504 }
rlm@3 505 break;
rlm@3 506
rlm@3 507
rlm@3 508 case 5:
rlm@3 509
rlm@3 510 getid3_lib::ReadSequence('BigEndian2Int', $parsed_array, $old_ra_header_data, 48,
rlm@3 511 array (
rlm@3 512 'sample_rate' => 4,
rlm@3 513 'sample_rate2' => 4,
rlm@3 514 'bits_per_sample' => 4,
rlm@3 515 'channels' => 2,
rlm@3 516 'genr' => -4,
rlm@3 517 'fourcc3' => -4,
rlm@3 518 )
rlm@3 519 );
rlm@3 520 $parsed_array['comments'] = array ();
rlm@3 521 break;
rlm@3 522
rlm@3 523 }
rlm@3 524
rlm@3 525 $parsed_array['fourcc'] = $parsed_array['fourcc3'];
rlm@3 526
rlm@3 527 }
rlm@3 528
rlm@3 529 foreach ($parsed_array['comments'] as $key => $value) {
rlm@3 530
rlm@3 531 if ($parsed_array['comments'][$key][0] === false) {
rlm@3 532 $parsed_array['comments'][$key][0] = '';
rlm@3 533 }
rlm@3 534 }
rlm@3 535
rlm@3 536 return true;
rlm@3 537 }
rlm@3 538
rlm@3 539
rlm@3 540
rlm@3 541 public static function RealAudioCodecFourCClookup($fourcc, $bitrate) {
rlm@3 542
rlm@3 543 // http://www.its.msstate.edu/net/real/reports/config/tags.stats
rlm@3 544 // http://www.freelists.org/archives/matroska-devel/06-2003/fullthread18.html
rlm@3 545
rlm@3 546 static $lookup;
rlm@3 547
rlm@3 548 if (empty($lookup)) {
rlm@3 549 $lookup['14_4'][8000] = 'RealAudio v2 (14.4kbps)';
rlm@3 550 $lookup['14.4'][8000] = 'RealAudio v2 (14.4kbps)';
rlm@3 551 $lookup['lpcJ'][8000] = 'RealAudio v2 (14.4kbps)';
rlm@3 552 $lookup['28_8'][15200] = 'RealAudio v2 (28.8kbps)';
rlm@3 553 $lookup['28.8'][15200] = 'RealAudio v2 (28.8kbps)';
rlm@3 554 $lookup['sipr'][4933] = 'RealAudio v4 (5kbps Voice)';
rlm@3 555 $lookup['sipr'][6444] = 'RealAudio v4 (6.5kbps Voice)';
rlm@3 556 $lookup['sipr'][8444] = 'RealAudio v4 (8.5kbps Voice)';
rlm@3 557 $lookup['sipr'][16000] = 'RealAudio v4 (16kbps Wideband)';
rlm@3 558 $lookup['dnet'][8000] = 'RealAudio v3 (8kbps Music)';
rlm@3 559 $lookup['dnet'][16000] = 'RealAudio v3 (16kbps Music Low Response)';
rlm@3 560 $lookup['dnet'][15963] = 'RealAudio v3 (16kbps Music Mid/High Response)';
rlm@3 561 $lookup['dnet'][20000] = 'RealAudio v3 (20kbps Music Stereo)';
rlm@3 562 $lookup['dnet'][32000] = 'RealAudio v3 (32kbps Music Mono)';
rlm@3 563 $lookup['dnet'][31951] = 'RealAudio v3 (32kbps Music Stereo)';
rlm@3 564 $lookup['dnet'][39965] = 'RealAudio v3 (40kbps Music Mono)';
rlm@3 565 $lookup['dnet'][40000] = 'RealAudio v3 (40kbps Music Stereo)';
rlm@3 566 $lookup['dnet'][79947] = 'RealAudio v3 (80kbps Music Mono)';
rlm@3 567 $lookup['dnet'][80000] = 'RealAudio v3 (80kbps Music Stereo)';
rlm@3 568
rlm@3 569 $lookup['dnet'][0] = 'RealAudio v3';
rlm@3 570 $lookup['sipr'][0] = 'RealAudio v4';
rlm@3 571 $lookup['cook'][0] = 'RealAudio G2';
rlm@3 572 $lookup['atrc'][0] = 'RealAudio 8';
rlm@3 573 }
rlm@3 574
rlm@3 575 $round_bitrate = intval(round($bitrate));
rlm@3 576
rlm@3 577 if (isset($lookup[$fourcc][$round_bitrate])) {
rlm@3 578 return $lookup[$fourcc][$round_bitrate];
rlm@3 579 }
rlm@3 580
rlm@3 581 if (isset($lookup[$fourcc][0])) {
rlm@3 582 return $lookup[$fourcc][0];
rlm@3 583 }
rlm@3 584
rlm@3 585 return $fourcc;
rlm@3 586 }
rlm@3 587
rlm@3 588 }
rlm@3 589
rlm@3 590
rlm@3 591 ?>