[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/getid3/getid3/ -> write.real.php (source)

   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  ?>


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7