| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 ///////////////////////////////////////////////////////////////// 3 /// getID3() by James Heinrich <info@getid3.org> // 4 // available at http://getid3.sourceforge.net // 5 // or http://www.getid3.org // 6 ///////////////////////////////////////////////////////////////// 7 // See readme.txt for more details // 8 ///////////////////////////////////////////////////////////////// 9 // // 10 // write.real.php // 11 // module for writing RealAudio/RealVideo tags // 12 // dependencies: module.tag.real.php // 13 // /// 14 ///////////////////////////////////////////////////////////////// 15 16 class getid3_write_real 17 { 18 var $filename; 19 var $tag_data = array(); 20 var $warnings = array(); // any non-critical errors will be stored here 21 var $errors = array(); // any critical errors will be stored here 22 var $paddedlength = 512; // minimum length of CONT tag in bytes 23 24 function getid3_write_real() { 25 return true; 26 } 27 28 function WriteReal() { 29 // File MUST be writeable - CHMOD(646) at least 30 if (is_writeable($this->filename)) { 31 if ($fp_source = @fopen($this->filename, 'r+b')) { 32 33 // Initialize getID3 engine 34 $getID3 = new getID3; 35 $OldThisFileInfo = $getID3->analyze($this->filename); 36 if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) { 37 $this->errors[] = 'Cannot write Real tags on old-style file format'; 38 fclose($fp_source); 39 return false; 40 } 41 42 if (empty($OldThisFileInfo['real']['chunks'])) { 43 $this->errors[] = 'Cannot write Real tags because cannot find DATA chunk in file'; 44 fclose($fp_source); 45 return false; 46 } 47 foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) { 48 $oldChunkInfo[$chunkarray['name']] = $chunkarray; 49 } 50 if (!empty($oldChunkInfo['CONT']['length'])) { 51 $this->paddedlength = max($oldChunkInfo['CONT']['length'], $this->paddedlength); 52 } 53 54 $new_CONT_tag_data = $this->GenerateCONTchunk(); 55 $new_PROP_tag_data = $this->GeneratePROPchunk($OldThisFileInfo['real']['chunks'], $new_CONT_tag_data); 56 $new__RMF_tag_data = $this->GenerateRMFchunk($OldThisFileInfo['real']['chunks']); 57 58 if (@$oldChunkInfo['.RMF']['length'] == strlen($new__RMF_tag_data)) { 59 fseek($fp_source, $oldChunkInfo['.RMF']['offset'], SEEK_SET); 60 fwrite($fp_source, $new__RMF_tag_data); 61 } else { 62 $this->errors[] = 'new .RMF tag ('.strlen($new__RMF_tag_data).' bytes) different length than old .RMF tag ('.$oldChunkInfo['.RMF']['length'].' bytes)'; 63 fclose($fp_source); 64 return false; 65 } 66 67 if (@$oldChunkInfo['PROP']['length'] == strlen($new_PROP_tag_data)) { 68 fseek($fp_source, $oldChunkInfo['PROP']['offset'], SEEK_SET); 69 fwrite($fp_source, $new_PROP_tag_data); 70 } else { 71 $this->errors[] = 'new PROP tag ('.strlen($new_PROP_tag_data).' bytes) different length than old PROP tag ('.$oldChunkInfo['PROP']['length'].' bytes)'; 72 fclose($fp_source); 73 return false; 74 } 75 76 if (@$oldChunkInfo['CONT']['length'] == strlen($new_CONT_tag_data)) { 77 78 // new data length is same as old data length - just overwrite 79 fseek($fp_source, $oldChunkInfo['CONT']['offset'], SEEK_SET); 80 fwrite($fp_source, $new_CONT_tag_data); 81 fclose($fp_source); 82 return true; 83 84 } else { 85 86 if (empty($oldChunkInfo['CONT'])) { 87 // no existing CONT chunk 88 $BeforeOffset = $oldChunkInfo['DATA']['offset']; 89 $AfterOffset = $oldChunkInfo['DATA']['offset']; 90 } else { 91 // new data is longer than old data 92 $BeforeOffset = $oldChunkInfo['CONT']['offset']; 93 $AfterOffset = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length']; 94 } 95 if ($tempfilename = tempnam('*', 'getID3')) { 96 ob_start(); 97 if ($fp_temp = fopen($tempfilename, 'wb')) { 98 99 rewind($fp_source); 100 fwrite($fp_temp, fread($fp_source, $BeforeOffset)); 101 fwrite($fp_temp, $new_CONT_tag_data); 102 fseek($fp_source, $AfterOffset, SEEK_SET); 103 while ($buffer = fread($fp_source, GETID3_FREAD_BUFFER_SIZE)) { 104 fwrite($fp_temp, $buffer, strlen($buffer)); 105 } 106 fclose($fp_temp); 107 108 if (copy($tempfilename, $this->filename)) { 109 unlink($tempfilename); 110 fclose($fp_source); 111 return true; 112 } 113 unlink($tempfilename); 114 $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.') - '.strip_tags(ob_get_contents()); 115 116 } else { 117 118 $this->errors[] = 'Could not open '.$tempfilename.' mode "wb" - '.strip_tags(ob_get_contents()); 119 120 } 121 ob_end_clean(); 122 } 123 fclose($fp_source); 124 return false; 125 126 } 127 128 129 } else { 130 $this->errors[] = 'Could not open '.$this->filename.' mode "r+b"'; 131 return false; 132 } 133 } 134 $this->errors[] = 'File is not writeable: '.$this->filename; 135 return false; 136 } 137 138 function GenerateRMFchunk(&$chunks) { 139 $oldCONTexists = false; 140 foreach ($chunks as $key => $chunk) { 141 $chunkNameKeys[$chunk['name']] = $key; 142 if ($chunk['name'] == 'CONT') { 143 $oldCONTexists = true; 144 } 145 } 146 $newHeadersCount = $chunks[$chunkNameKeys['.RMF']]['headers_count'] + ($oldCONTexists ? 0 : 1); 147 148 $RMFchunk = "\x00\x00"; // object version 149 $RMFchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['.RMF']]['file_version'], 4); 150 $RMFchunk .= getid3_lib::BigEndian2String($newHeadersCount, 4); 151 152 $RMFchunk = '.RMF'.getid3_lib::BigEndian2String(strlen($RMFchunk) + 8, 4).$RMFchunk; // .RMF chunk identifier + chunk length 153 return $RMFchunk; 154 } 155 156 function GeneratePROPchunk(&$chunks, &$new_CONT_tag_data) { 157 $old_CONT_length = 0; 158 $old_DATA_offset = 0; 159 $old_INDX_offset = 0; 160 foreach ($chunks as $key => $chunk) { 161 $chunkNameKeys[$chunk['name']] = $key; 162 if ($chunk['name'] == 'CONT') { 163 $old_CONT_length = $chunk['length']; 164 } elseif ($chunk['name'] == 'DATA') { 165 if (!$old_DATA_offset) { 166 $old_DATA_offset = $chunk['offset']; 167 } 168 } elseif ($chunk['name'] == 'INDX') { 169 if (!$old_INDX_offset) { 170 $old_INDX_offset = $chunk['offset']; 171 } 172 } 173 } 174 $CONTdelta = strlen($new_CONT_tag_data) - $old_CONT_length; 175 176 $PROPchunk = "\x00\x00"; // object version 177 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['max_bit_rate'], 4); 178 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['avg_bit_rate'], 4); 179 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['max_packet_size'], 4); 180 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['avg_packet_size'], 4); 181 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['num_packets'], 4); 182 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['duration'], 4); 183 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['preroll'], 4); 184 $PROPchunk .= getid3_lib::BigEndian2String(max(0, $old_INDX_offset + $CONTdelta), 4); 185 $PROPchunk .= getid3_lib::BigEndian2String(max(0, $old_DATA_offset + $CONTdelta), 4); 186 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['num_streams'], 2); 187 $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['flags_raw'], 2); 188 189 $PROPchunk = 'PROP'.getid3_lib::BigEndian2String(strlen($PROPchunk) + 8, 4).$PROPchunk; // PROP chunk identifier + chunk length 190 return $PROPchunk; 191 } 192 193 function GenerateCONTchunk() { 194 foreach ($this->tag_data as $key => $value) { 195 // limit each value to 0xFFFF bytes 196 $this->tag_data[$key] = substr($value, 0, 65535); 197 } 198 199 $CONTchunk = "\x00\x00"; // object version 200 201 $CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['title']), 2); 202 $CONTchunk .= @$this->tag_data['title']; 203 204 $CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['artist']), 2); 205 $CONTchunk .= @$this->tag_data['artist']; 206 207 $CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['copyright']), 2); 208 $CONTchunk .= @$this->tag_data['copyright']; 209 210 $CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['comment']), 2); 211 $CONTchunk .= @$this->tag_data['comment']; 212 213 if ($this->paddedlength > (strlen($CONTchunk) + 8)) { 214 $CONTchunk .= str_repeat("\x00", $this->paddedlength - strlen($CONTchunk) - 8); 215 } 216 217 $CONTchunk = 'CONT'.getid3_lib::BigEndian2String(strlen($CONTchunk) + 8, 4).$CONTchunk; // CONT chunk identifier + chunk length 218 219 return $CONTchunk; 220 } 221 222 function RemoveReal() { 223 // File MUST be writeable - CHMOD(646) at least 224 if (is_writeable($this->filename)) { 225 if ($fp_source = @fopen($this->filename, 'r+b')) { 226 227 // Initialize getID3 engine 228 $getID3 = new getID3; 229 $OldThisFileInfo = $getID3->analyze($this->filename); 230 if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) { 231 $this->errors[] = 'Cannot remove Real tags from old-style file format'; 232 fclose($fp_source); 233 return false; 234 } 235 236 if (empty($OldThisFileInfo['real']['chunks'])) { 237 $this->errors[] = 'Cannot remove Real tags because cannot find DATA chunk in file'; 238 fclose($fp_source); 239 return false; 240 } 241 foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) { 242 $oldChunkInfo[$chunkarray['name']] = $chunkarray; 243 } 244 245 if (empty($oldChunkInfo['CONT'])) { 246 // no existing CONT chunk 247 fclose($fp_source); 248 return true; 249 } 250 251 $BeforeOffset = $oldChunkInfo['CONT']['offset']; 252 $AfterOffset = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length']; 253 if ($tempfilename = tempnam('*', 'getID3')) { 254 ob_start(); 255 if ($fp_temp = fopen($tempfilename, 'wb')) { 256 257 rewind($fp_source); 258 fwrite($fp_temp, fread($fp_source, $BeforeOffset)); 259 fseek($fp_source, $AfterOffset, SEEK_SET); 260 while ($buffer = fread($fp_source, GETID3_FREAD_BUFFER_SIZE)) { 261 fwrite($fp_temp, $buffer, strlen($buffer)); 262 } 263 fclose($fp_temp); 264 265 if (copy($tempfilename, $this->filename)) { 266 unlink($tempfilename); 267 fclose($fp_source); 268 return true; 269 } 270 unlink($tempfilename); 271 $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.') - '.strip_tags(ob_get_contents()); 272 273 } else { 274 275 $this->errors[] = 'Could not open '.$tempfilename.' mode "wb" - '.strip_tags(ob_get_contents()); 276 277 } 278 ob_end_clean(); 279 } 280 fclose($fp_source); 281 return false; 282 283 284 } else { 285 $this->errors[] = 'Could not open '.$this->filename.' mode "r+b"'; 286 return false; 287 } 288 } 289 $this->errors[] = 'File is not writeable: '.$this->filename; 290 return false; 291 } 292 293 } 294 295 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |