Пример #1
0
 /**
  * Returns the header raw data.
  *
  * @return string
  */
 public function __toString()
 {
   /* ID3v2.3.0 ExtendedHeader */
   if ($this->getOption("version", 4) < 4) {
     return Transform::toUInt32BE($this->_size) .
       Transform::toUInt16BE($this->hasFlag(self::CRC32) ? 0x8000 : 0) .
       Transform::toUInt32BE($this->_padding) .
       ($this->hasFlag(self::CRC32) ? Transform::toUInt32BE($this->_crc) : "");
   }
   
   /* ID3v2.4.0 ExtendedHeader */
   else {
     return Transform::toUInt32BE($this->encodeSynchsafe32($this->_size)) .
       Transform::toInt8(1) . Transform::toInt8($this->_flags) .
       ($this->hasFlag(self::UPDATE) ? "\0" : "") .
       ($this->hasFlag(self::CRC32) ? Transform::toInt8(5) .
        Transform::toInt8($this->_crc & 0xf0000000 >> 28 & 0xf /*eq >>> 28*/) .
        Transform::toUInt32BE($this->encodeSynchsafe32($this->_crc)) : "") .
       ($this->hasFlag(self::RESTRICTED) ? 
          Transform::toInt8(1) . Transform::toInt8($this->_restrictions) : "");
   }
 }
 /**
  * Returns the header raw data.
  *
  * @return string
  */
 public function __toString()
 {
     /* ID3v2.3.0 ExtendedHeader */
     if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
         return Transform::toUInt32BE($this->_size) . Transform::toUInt16BE($this->hasFlag(self::CRC32) ? 0x8000 : 0) . Transform::toUInt32BE($this->_padding) . ($this->hasFlag(self::CRC32) ? Transform::toUInt32BE($this->_crc) : "");
     } else {
         return Transform::toUInt32BE($this->encodeSynchsafe32($this->_size)) . Transform::toInt8(1) . Transform::toInt8($this->_flags) . ($this->hasFlag(self::UPDATE) ? "" : "") . ($this->hasFlag(self::CRC32) ? Transform::toInt8(5) . Transform::toInt8($this->_crc & 0xf0000000 >> 28 & 0xf) . Transform::toUInt32BE(encodeSynchsafe32($this->_crc)) : "") . ($this->hasFlag(self::RESTRICTED) ? Transform::toInt8(1) . Transform::toInt8($this->_restrictions) : "");
     }
 }
Пример #3
0
 /**
  * Returns the box raw data.
  *
  * @return string
  */
 public function __toString($data = "")
 {
   return parent::__toString
     (Transform::toUInt32BE($this->_version << 24 | $this->_flags) . $data);
 }
Пример #4
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
   $data = Transform::toUInt8($this->_encoding) . $this->_language .
     Transform::toUInt8($this->_format) . Transform::toUInt8($this->_type);
   switch ($this->_encoding) {
   case self::UTF16:
   case self::UTF16LE:
     $data .= Transform::toString16
       ($this->_description, $this->_encoding == self::UTF16 ?
        Transform::MACHINE_ENDIAN_ORDER : Transform::LITTLE_ENDIAN_ORDER) .
       "\0\0";
     break;
   case self::UTF16BE:
     $data .= Transform::toString16BE($this->_description) . "\0\0";
     break;
   default:
     $data .= $this->_description . "\0";
   }
   foreach ($this->_events as $timestamp => $syllable) {
     switch ($this->_encoding) {
     case self::UTF16:
     case self::UTF16LE:
       $data .= Transform::toString16
         ($syllable, $this->_encoding == self::UTF16 ?
          Transform::MACHINE_ENDIAN_ORDER : Transform::LITTLE_ENDIAN_ORDER) .
         "\0\0";
       break;
     case self::UTF16BE:
       $data .= Transform::toString16BE($syllable) . "\0\0";
       break;
     default:
       $data .= $syllable . "\0";
     }
     $data .= Transform::toUInt32BE($timestamp);
   }
   $this->setData($data);
   return parent::__toString();
 }
Пример #5
0
 /**
  * swaps the index from end to beginning
  *
  * swaps the index from end to beginning
  * 
  * @return  mixed True if everything wents fine, otherwise error-message as string
  * @author  Benjamin Carl <*****@*****.**>
  * @version 0.1
  * @since   Method available since Release 0.1
  * @access  private
  */
 private function _swapIndex()
 {
     $moovSize = $this->_moovBytes->bytesAvailable();
     $moovAType = '';
     $moovASize = 0;
     $offsetCount = 0;
     $compressionCheck = $this->_moovBytes->readBytes(12, 4);
     if ($compressionCheck == Atom::CMOV_ATOM) {
         throw new Exception('compressed MP4/QT-file can\'t do this file: ' . $file);
     }
     // begin of metadata
     $metaDataOffsets = array();
     $metaDataStrings = array();
     $metaDataCurrentLevel = 0;
     $moovStartOffset = 12;
     for ($i = $moovStartOffset; $i < $moovSize - $moovStartOffset; $i++) {
         $moovAType = $this->_moovBytes->readUTFBytes($i, 4);
         if (Atom::isValidAtom($moovAType)) {
             $moovASize = $this->_moovBytes->readUnsignedInt($i - 4);
             if ($moovASize > 8 && $moovASize + $i < $moovSize - $moovStartOffset) {
                 try {
                     $containerLength = 0;
                     $containerString = $moovAType;
                     for ($mi = count($metaDataOffsets) - 1; $mi > -1; $mi--) {
                         $containerLength = $metaDataOffsets[$mi];
                         if ($i - $moovStartOffset < $containerLength && $i - $moovStartOffset + $moovASize > $containerLength) {
                             throw new Exception('bad atom nested size');
                         }
                         if ($i - $moovStartOffset == $containerLength) {
                             array_pop($metaDataOffsets);
                             array_pop($metaDataStrings);
                         } else {
                             $containerString = $metaDataStrings[$mi] . "." . $containerString;
                         }
                     }
                     if ($i - $moovStartOffset <= $containerLength) {
                         array_push($metaDataOffsets, $i - $moovStartOffset + $moovASize);
                         array_push($metaDataStrings, $moovAType);
                     }
                     if ($moovAType != Atom::STCO_ATOM && $moovAType != Atom::CO64_ATOM) {
                         $i += 4;
                     } elseif ($moovAType == Atom::URL_ATOM || $moovAType == Atom::XML_ATOM) {
                         $i += $moovASize - 4;
                     }
                 } catch (Exception $e) {
                     echo 'EXCEPTION: ' . $e->getMessage();
                 }
             }
         }
         if ($moovAType == Atom::STCO_ATOM) {
             $moovASize = $this->_moovBytes->readUnsignedInt($i - 4);
             if ($i + $moovASize - $moovStartOffset > $moovSize) {
                 throw new Exception('bad atom size');
                 return;
             }
             $offsetCount = $this->_moovBytes->readUnsignedInt($i + 8);
             for ($j = 0; $j < $offsetCount; $j++) {
                 $position = $i + 12 + $j * 4;
                 $currentOffset = $this->_moovBytes->readUnsignedInt($position);
                 // cause of mooving the moov-atom right before the rest of data
                 // (behind ftyp) the new offset is caluclated:
                 // current-offset + size of moov atom (box) = new offset
                 $currentOffset += $moovSize;
                 $this->_moovBytes->writeBytes(Transform::toUInt32BE($currentOffset), $position + 1);
             }
             $i += $moovASize - 4;
         } else {
             if ($moovAType == Atom::CO64_ATOM) {
                 $moovASize = $this->_moovBytes->readUnsignedInt($i - 4);
                 if ($i + $moovASize - $moovStartOffset > $moovSize) {
                     throw new Exception('bad atom size');
                     return;
                 }
                 $offsetCount = $this->_moovBytes->readDouble($i + 8);
                 for ($j2 = 0; $j2 < $offsetCount; $j2++) {
                     $position = $i + 12 + $j * 8;
                     $currentOffset = $this->_moovBytes->readUnsignedInt($position);
                     // cause of mooving the moov-atom right before the rest of data
                     // (behind ftyp) the new offset is caluclated:
                     // current-offset + size of moov atom (box) = new offset
                     $currentOffset += $moovSize;
                     // TODO implement!
                     //$this->_moovBytes->writeBytes(Transform::toUInt64BE($currentOffset), $position+1);
                 }
                 $i += $moovASize - 4;
             }
         }
     }
     return true;
 }
Пример #6
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
   $this->setData
     (Transform::toUInt8($this->_format) .
      Transform::toUInt32BE($this->_position));
   return parent::__toString();
 }
Пример #7
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
   $this->setData
     ($this->_owner . "\0" . Transform::toInt8($this->_rating) .
      ($this->_counter > 0xffffffff ?
       Transform::toInt64BE($this->_counter) :
       ($this->_counter > 0 ? Transform::toUInt32BE($this->_counter) : 0)));
   return parent::__toString();
 }
Пример #8
0
  /**
   * Writes the changes back to the original media file.
   *
   * Please note: currently the method writes only ID32 and ILST boxes to
   * <i>moov.udta.meta</i>. Changes to any other box are discarded. Write
   * operation will overwrite <i>moov.udta</i>, if found.
   */
  public function write()
  {
    if (!isset($this->moov->udta->meta->ilst) &&
        !isset($this->moov->udta->meta->id32))
      throw new ISO14496_Exception("Nothing to write");

    if ($this->getOption("readonly", false) !== false)
      throw new ISO14496_Exception("File is read only");
    
    if (($fd = fopen($this->_filename, file_exists
                     ($this->_filename) ? "r+b" : "wb")) === false)
      throw new ISO14496_Exception
        ("Unable to open file for writing: " . $filename);
    
    $this->moov->udta->meta->hdlr->setHandlerType("mdir");
    
    /* Calculate start position */
    $mark = ($this->moov->udta->getOffset() > 0 ?
             $this->moov->udta->getOffset() :
             $this->moov->getOffset() + $this->moov->getSize());
    
    /* Calculate file size */
    fseek($fd, 0, SEEK_END);
    $oldFileSize = ftell($fd);
    $newFileSize = $oldFileSize -
      ($this->moov->udta->getOffset() > 0 ? $this->moov->udta->getSize() : 0) -
      (isset($this->moov->udta->meta->free) ?
       $this->moov->udta->meta->free->getSize() : 0) +
      strlen($this->moov->udta);

    /* Calculate free space size */
    if ($oldFileSize < $newFileSize) {
      // Add free space to the file calculated using the following logaritmic
      // equation: log(0.2(x + 10)), ranging from 1k to 9k given the file size
      // of 0..4G
      $this->moov->udta->meta->free->setSize
        (ceil(log(0.2 * ($newFileSize / 1024 + 10), 10) * 1024));
      ftruncate($fd, $newFileSize += $this->moov->udta->meta->free->getSize());
      
      // Move data to the end of the file
      for ($i = 1, $cur = $oldFileSize; $cur > $mark; $cur -= 1024, $i++) {
        fseek($fd, -(($i * 1024) +
              ($excess = $cur - 1024 > $mark ? 0 : $cur - $mark - 1024) +
              ($newFileSize - $oldFileSize)), SEEK_END);
        $buffer = fread($fd, 1024);
        fseek($fd, -(($i * 1024) + $excess), SEEK_END);
        fwrite($fd, $buffer, 1024);
      }
      
      // Update stco/co64 to correspond the data move
      foreach ($this->moov->getBoxesByIdentifier("trak") as $trak) {
        $chunkOffsetBox = 
          (isset($trak->mdia->minf->stbl->stco) ?
           $trak->mdia->minf->stbl->stco : $trak->mdia->minf->stbl->co64);
        $chunkOffsetTable = $chunkOffsetBox->getChunkOffsetTable();
        $chunkOffsetTableCount = count($chunkOffsetTable);
        $chunkOffsetDelta = $newFileSize - $oldFileSize;
        for ($i = 1; $i <= $chunkOffsetTableCount; $i++)
          $chunkOffsetTable[$i] += $chunkOffsetDelta;
        $chunkOffsetBox->setChunkOffsetTable($chunkOffsetTable);
        fseek($fd, $chunkOffsetBox->getOffset());
        fwrite($fd, $chunkOffsetBox, $chunkOffsetBox->getSize());
      }
    } 
    else
      $this->moov->udta->meta->free->setSize($oldFileSize - $newFileSize);
    
    /* Update the target box */
    fseek($fd, $mark);
    $this->moov->udta->setSize(fwrite($fd, $this->moov->udta));
    
    /* Update the parent box */
    fseek($fd, $this->moov->getOffset());
    fwrite($fd, Transform::toUInt32BE($this->moov->getSize()));
    
    fclose($fd);
  }
Пример #9
0
 /**
  * Returns the box raw data.
  *
  * @return string
  */
 public function __toString($data = "")
 {
   if ($this->isContainer())
     foreach ($this->getBoxes() as $name => $boxes)
       foreach ($boxes as $box)
         $data .= $box;
   $size = strlen($data) + 8;
   if ($size > 0xffffffff)
     $size += 8;
   if (strlen($this->_type) > 4)
     $size += 16;
   return ($size > 0xffffffff ?
            Transform::toUInt32BE(1) : Transform::toUInt32BE($size)) .
     (strlen($this->_type) > 4 ? "uuid" : $this->_type) .
     ($size > 0xffffffff ? Transform::toInt64BE($size) : "") . 
     (strlen($this->_type) > 4 ? Transform::toGUID($this->_type) : "") . $data;
 }
Пример #10
0
 /**
  * Returns the header/footer raw data without the identifier.
  *
  * @return string
  */
 public function __toString()
 {
     return Transform::toInt8(floor($this->_version)) . Transform::toInt8(($this->_version - floor($this->_version)) * 10) . Transform::toInt8($this->_flags) . Transform::toUInt32BE($this->encodeSynchsafe32($this->_size));
 }
Пример #11
0
 /**
  * Returns the box raw data.
  *
  * @return string
  */
 public function __toString($data = "")
 {
   return parent::__toString(Transform::toUInt32BE(count($this->_boxes)));
 }
Пример #12
0
 /**
  * Returns the box raw data.
  *
  * @return string
  */
 public function __toString($data = "")
 {
   $data = Transform::toUInt32BE(count($this->_chunkOffsetTable));
   foreach ($this->_chunkOffsetTable as $chunkOffset)
     $data .= Transform::toInt64BE($chunkOffset);
   return parent::__toString($data);
 }
Пример #13
0
  /**
   * Returns the frame raw data.
   *
   * @return string
   */
  public function __toString()
  {
    /* ID3v2.3.0 Flags; convert from 2.4.0 format */
    if ($this->getOption("version", 4) < 4) {
      $flags = 0;
      if ($this->hasFlag(self::DISCARD_ON_TAGCHANGE))
        $flags = $flags | 0x8000;
      if ($this->hasFlag(self::DISCARD_ON_FILECHANGE))
        $flags = $flags | 0x4000;
      if ($this->hasFlag(self::READ_ONLY))
        $flags = $flags | 0x2000;
      if ($this->hasFlag(self::COMPRESSION))
        $flags = $flags | 0x80;
      if ($this->hasFlag(self::ENCRYPTION))
        $flags = $flags | 0x40;
      if ($this->hasFlag(self::GROUPING_IDENTITY))
        $flags = $flags | 0x20;
    }

    /* ID3v2.4.0 Flags */
    else
      $flags = $this->_flags;
    
    $size = $this->_size;
    if ($this->getOption("version", 4) < 4)
      $data = $this->_data;
    else {
      $data = $this->encodeUnsynchronisation($this->_data);
      if (($dataLength = strlen($data)) != $size) {
        $size = 4 + $dataLength;
        $data = Transform::toUInt32BE($this->encodeSynchsafe32($this->_size)) .
          $data;
        $flags |= self::DATA_LENGTH_INDICATOR | self::UNSYNCHRONISATION;
        $this->setOption("unsyncronisation", true);
      }
    }
    return Transform::toString8(substr($this->_identifier, 0, 4), 4) .
      Transform::toUInt32BE($this->encodeSynchsafe32($size)) .
      Transform::toUInt16BE($flags) . $data;
  }
Пример #14
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
   $data = Transform::toUInt8($this->_format);
   foreach ($this->_events as $timestamp => $tempo) {
     if ($tempo >= 0xff)
       $data .= Transform::toUInt8(0xff) . Transform::toUInt8($tempo - 0xff);
     else
       $data .= Transform::toUInt8($tempo);
     $data .= Transform::toUInt32BE($timestamp);
   }
   parent::setData($data);
   return parent::__toString();
 }
Пример #15
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
   $data = Transform::toUInt8($this->_format);
   foreach ($this->_events as $timestamp => $type)
     $data .= Transform::toUInt8($type) . Transform::toUInt32BE($timestamp);
   $this->setData($data);
   return parent::__toString();
 }
Пример #16
0
 /**
  * Returns the box raw data.
  *
  * @return string
  */
 public function __toString($data = "")
 {
   return parent::__toString
     ("appl" . $this->_handlerType . Transform::toUInt32BE(0) .
      Transform::toUInt32BE(0) . Transform::toUInt32BE(0) . $this->_name .
      "\0");
 }
Пример #17
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
   $this->setData
     ($this->_counter > 4294967295 ?
      Transform::toInt64BE($this->_counter) : // UInt64
      Transform::toUInt32BE($this->_counter));
   return parent::__toString();
 }
Пример #18
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
     $data = $this->_device . "";
     foreach ($this->_adjustments as $channel) {
         $data .= Transform::toInt8($channel["channelType"]) . Transform::toInt16BE($channel["volumeAdjustment"]);
         if ($channel["peakVolume"] < 255) {
             $data .= Transform::toInt8(8) . Transform::toInt8($channel["peakVolume"]);
         } else {
             if ($channel["peakVolume"] < 65535) {
                 $data .= Transform::toInt8(16) . Transform::toUInt16BE($channel["peakVolume"]);
             } else {
                 if ($channel["peakVolume"] < 4294967295) {
                     $data .= Transform::toInt8(32) . Transform::toUInt32BE($channel["peakVolume"]);
                 } else {
                     $data .= Transform::toInt8(64) . Transform::toUInt64BE($channel["peakVolume"]);
                 }
             }
         }
     }
     $this->setData($data);
     return parent::__toString();
 }
Пример #19
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
   $this->setData
     (substr(Transform::toUInt32BE($this->_bufferSize), 1, 3) .
      Transform::toInt8($this->_infoFlags) .
      Transform::toInt32BE($this->_offset));
   return parent::__toString();
 }
Пример #20
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
   $data = $this->_device . "\0";
   foreach ($this->_adjustments as $channel) {
     $data .= Transform::toInt8($channel[self::channelType]) .
       Transform::toInt16BE($channel[self::volumeAdjustment] * 512);
     if (abs($channel[self::peakVolume]) <= 0xff)
       $data .= Transform::toInt8(8) .
         Transform::toUInt8($channel[self::peakVolume]);
     else if (abs($channel[self::peakVolume]) <= 0xffff)
       $data .= Transform::toInt8(16) .
         Transform::toUInt16BE($channel[self::peakVolume]);
     else if (abs($channel[self::peakVolume]) <= 0xffffffff)
       $data .= Transform::toInt8(32) .
         Transform::toUInt32BE($channel[self::peakVolume]);
     else
       $data .= Transform::toInt8(64) .
         Transform::toInt64BE($channel[self::peakVolume]); // UInt64
   }
   $this->setData($data);
   return parent::__toString();
 }
Пример #21
0
 /**
  * Returns the frame raw data.
  *
  * @return string
  */
 public function __toString()
 {
     /* ID3v2.3.0 Flags; convert from 2.4.0 format */
     if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
         $flags = 0;
         if ($this->hasFlag(self::DISCARD_ON_TAGCHANGE)) {
             $flags = $flags | 0x8000;
         }
         if ($this->hasFlag(self::DISCARD_ON_FILECHANGE)) {
             $flags = $flags | 0x4000;
         }
         if ($this->hasFlag(self::READ_ONLY)) {
             $flags = $flags | 0x2000;
         }
         if ($this->hasFlag(self::COMPRESSION)) {
             $flags = $flags | 0x80;
         }
         if ($this->hasFlag(self::ENCRYPTION)) {
             $flags = $flags | 0x40;
         }
         if ($this->hasFlag(self::GROUPING_IDENTITY)) {
             $flags = $flags | 0x20;
         }
     } else {
         $flags = $this->_flags;
     }
     return Transform::toString8(substr($this->_identifier, 0, 4), 4) . Transform::toUInt32BE($this->encodeSynchsafe32($this->_size)) . Transform::toUInt16BE($flags) . $this->_data;
 }