Beispiel #1
0
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int					$totalSize
  * @param	int					$boxType
  * @param	file|string			$f
  * @param	MP4Info_Box			$parent
  * @return 	MP4Info_Box_ilst_sub
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent)
 {
     if (!$parent instanceof MP4Info_Box_ilst) {
         throw new MP4Info_Exception('This box isn\'t "islt" child', MP4Info_Exception::CODE_INCOMPATIBLE, $boxType);
     }
     // Call ancestor
     parent::__construct($totalSize, $boxType, $data, $parent);
     // Get data
     $data = $this->data;
     // Unpack
     $type = self::getType($this->boxType);
     $ar = unpack('Nlen', $data);
     if (substr($data, 4, 4) == 'data') {
         $info = substr($data, 8, $ar['len'] - 8);
         switch ($type) {
             case 'uint8':
                 $info = reset(unpack('C', $info));
                 break;
             case 'uint16':
                 $info = reset(unpack('n', $info));
                 break;
             case 'uint32':
                 $info = reset(unpack('N', $info));
                 break;
             case 'text':
                 break;
         }
         $this->data = $info;
         $parent->setKeyValue($this->boxTypeStr, $info);
     } else {
         throw new MP4Info_Exception('Didn\'t get the "data" code');
     }
 }
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int						$totalSize
  * @param	int						$boxType
  * @param	file|string				$data
  * @param	MP4Info_Box				$parent
  * @return 	MP4Info_Box_Container
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent)
 {
     if (!self::isCompatible($boxType, $parent)) {
         throw new MP4Info_Exception('This box isn\'t a container', MP4Info_Exception::CODE_INCOMPATIBLE, $boxType);
     }
     // Call ancestor
     parent::__construct($totalSize, $boxType, false, $parent);
     // Unpack
     if (is_string($data)) {
         while ($data != '') {
             try {
                 $box = MP4Info_Box::fromString($data, $this);
                 if (!$box instanceof MP4Info_Box) {
                     break;
                 }
             } catch (Exception $e) {
                 break;
             }
         }
     } else {
         do {
             try {
                 $box = MP4Info_Box::fromStream($data, $this);
                 if (!$box instanceof MP4Info_Box) {
                     break;
                 }
             } catch (Exception $e) {
                 break;
             }
         } while ($box !== false);
     }
 }
Beispiel #3
0
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int					$totalSize
  * @param	int					$boxType
  * @param	file|string			$data
  * @param	MP4Info_Box			$parent
  * @return 	MP4Info_Box_uuid
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent)
 {
     if (!self::isCompatible($boxType, $parent)) {
         throw new Exception('This box isn\'t "uuid"');
     }
     // Call ancestor
     parent::__construct($totalSize, $boxType, '', $parent);
     // Unpack
     $data = self::getDataFrom3rd($data, $totalSize);
     $this->uuid = bin2hex(substr($data, 0, 16));
     $this->xmp = substr($data, 16);
 }
Beispiel #4
0
 /**
  * Get information from MP4 file
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	string		$file
  * @return	array
  * @access 	public
  * @static
  */
 public static function getInfo($file)
 {
     // Open file
     $f = fopen($file, 'rb');
     if (!$f) {
         throw new Exception('Cannot open file: ' . $file);
     }
     // Get all boxes
     try {
         while ($box = MP4Info_Box::fromStream($f)) {
             $boxes[] = $box;
         }
     } catch (Exception $e) {
     }
     // Close
     fclose($f);
     // Return info
     return self::getInfoFromBoxes($boxes);
 }
Beispiel #5
0
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int					$totalSize
  * @param	int					$boxType
  * @param	file|string			$data
  * @param	MP4Info_Box			$parent
  * @return 	MP4Info_Box_ftyp
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent)
 {
     if (!self::isCompatible($boxType, $parent)) {
         throw new MP4Info_Exception('This box isn\'t "ftyp"', MP4Info_Exception::CODE_INCOMPATIBLE, $boxType);
     }
     // Call ancestor
     parent::__construct($totalSize, $boxType, false, $parent);
     // Get data
     $data = self::getDataFrom3rd($data, $totalSize);
     // Unpack
     $ar = unpack('NmajorBrand/NminorVersion/N*compatibleBrands', $data);
     $compatibleBrands = array();
     foreach ($ar as $k => $v) {
         if (substr($k, 0, 16) == 'compatibleBrands') {
             $compatibleBrands[] = $v;
         }
     }
     // Save properties
     $this->majorBrand = $ar['majorBrand'];
     $this->minorVersion = $ar['minorVersion'];
     $this->compatibleBrands = $compatibleBrands;
 }
Beispiel #6
0
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int					$totalSize
  * @param	int					$boxType
  * @param	file|string			$data
  * @param	MP4Info_Box			$parent
  * @return 	MP4Info_Box_hdlr
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent)
 {
     if (!self::isCompatible($boxType, $parent)) {
         throw new Exception('This box isn\'t "iods"');
     }
     // Get timezone
     if (self::$timezone === false) {
         self::$timezone = date('Z');
     }
     // Call ancestor
     parent::__construct($totalSize, $boxType, '', $parent);
     // Get data
     $data = self::getDataFrom3rd($data, $totalSize);
     // Unpack
     $ar = unpack('Cversion/C3flags', $data);
     $ar2 = unpack('CiodTag/Nlength/nODID/CODProfileLevel/CsceneProfileLevel/CaudioProfileLevel/CvideoProfileLevel/CgraphicsProfileLevel', substr($data, 4));
     // Save
     $this->version = $ar['version'];
     $this->flags = $ar['flags1'] * 65536 + $ar['flags1'] * 256 + $ar['flags1'] * 1;
     print_r($ar2);
     die;
 }
Beispiel #7
0
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int					$totalSize
  * @param	int					$boxType
  * @param	file|string			$data
  * @param	MP4Info_Box			$parent
  * @return 	MP4Info_Box_hdlr
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent)
 {
     if (!self::isCompatible($boxType, $parent)) {
         throw new Exception('This box isn\'t "ftyp"');
     }
     // Get timezone
     if (self::$timezone === false) {
         self::$timezone = date('Z');
     }
     // Call ancestor
     parent::__construct($totalSize, $boxType, '', $parent);
     // Get data
     $data = self::getDataFrom3rd($data, $totalSize);
     // Unpack
     $ar = unpack('Cversion/C3flags', $data);
     if ($ar['version'] == 0) {
         // 32 bit
         $ar2 = unpack('Nctime/Nmtime/NtimeScale/Nduration', substr($data, 4));
         $len = 6 * 4;
     } else {
         if ($ar['version'] == 1) {
             // 64 bit
             $ar2 = unpack('N2ctime/N2mtime/NtimeScale/N2duration', substr($data, 4));
             $len = 9 * 4;
         } else {
             throw new Exception('Unhandled version: ' . $ar['version']);
         }
     }
     // Save
     $this->version = $ar['version'];
     $this->flags = $ar['flags1'] * 65536 + $ar['flags1'] * 256 + $ar['flags1'] * 1;
     $this->ctime = date('r', (isset($ar2['ctime']) ? $ar2['ctime'] : $ar2['ctime1']) - 2082826800 - self::$timezone);
     $this->mtime = date('r', (isset($ar2['mtime']) ? $ar2['mtime'] : $ar2['mtime1']) - 2082826800 - self::$timezone);
     $this->timeScale = $ar2['timeScale'];
     $this->duration = isset($ar2['duration']) ? $ar2['duration'] : $ar2['duration1'];
     $this->handlerType = substr($data, $len, 4);
     $this->name = substr($data, $len + 8, -1);
 }
Beispiel #8
0
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int					$totalSize
  * @param	int					$boxType
  * @param	file|string			$data
  * @param	MP4Info_Box			$parent
  * @return 	MP4Info_Box_stsd
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent)
 {
     if (!self::isCompatible($boxType, $parent)) {
         throw new Exception('This box isn\'t "stsd"');
     }
     // Call ancestor
     parent::__construct($totalSize, $boxType, '', $parent);
     // Get data
     $data = self::getDataFrom3rd($data, $totalSize);
     // Unpack
     $ar = unpack('Cversion/C3flags/Ncount', $data);
     $this->version = $ar['version'];
     $this->flags = $ar['flags1'] * 65536 + $ar['flags1'] * 256 + $ar['flags1'] * 1;
     $this->count = $ar['count'];
     // Unpack SAMPLEDESCRIPTION
     $desc = substr($data, 8);
     for ($i = 0; $i < $this->count; $i++) {
         $ar = unpack('Nlen', $desc);
         $type = substr($desc, 4, 4);
         $info = substr($desc, 8, $ar['len'] - 8);
         $desc = substr($desc, $ar['len']);
         $this->values[$type] = $info;
     }
 }
Beispiel #9
0
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int					$totalSize
  * @param	int					$boxType
  * @param	file|string			$data
  * @param	MP4Info_Box			$parent
  * @return 	MP4Info_Box_mvhd
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent)
 {
     if (!self::isCompatible($boxType)) {
         throw new Exception('This box isn\'t "mvhd"');
     }
     // Get timezone
     if (self::$timezone === false) {
         self::$timezone = date('Z');
     }
     // Call ancestor's constructor
     parent::__construct($totalSize, $boxType, '', $parent);
     // Unpack
     $ar = unpack('Cversion/C3flags', $data);
     if ($ar['version'] == 0) {
         // 32 bit
         $ar2 = unpack('Nctime/Nmtime/NtimeScale/Nduration/Nrate/nvolume/ndummy/N2dummy2/N9matrix/N3dummy3/NnextTrack', substr($data, 4));
     } else {
         if ($ar['version'] == 1) {
             // 64 bit
             $ar2 = unpack('N2ctime/N2mtime/NtimeScale/N2duration/Nrate/nvolume/ndummy/N2dummy2/N9matrix/N3dummy3/NnextTrack', substr($data, 4));
         } else {
             throw new Exception('Unhandled version: ' . $ar['version']);
         }
     }
     // Save
     $this->version = $ar['version'];
     $this->flags = $ar['flags1'] * 65536 + $ar['flags1'] * 256 + $ar['flags1'] * 1;
     $this->ctime = date('r', (isset($ar2['ctime']) ? $ar2['ctime'] : $ar2['ctime1']) - 2082826800 - self::$timezone);
     $this->mtime = date('r', (isset($ar2['mtime']) ? $ar2['mtime'] : $ar2['mtime1']) - 2082826800 - self::$timezone);
     $this->timeScale = $ar2['timeScale'];
     $this->duration = isset($ar2['duration']) ? $ar2['duration'] : $ar2['duration1'];
     $this->rate = MP4Info_Helper::fromFixed16($ar2['rate']);
     $this->volume = MP4Info_Helper::fromFixed8($ar2['volume']);
 }
Beispiel #10
0
 /**
  * Constructor
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	int					$totalSize
  * @param	int					$boxType
  * @param	file|string			$data
  * @param	MP4Info_Box			$parent
  * @return 	MP4Info_Box_tkhd
  * @access 	public
  * @throws 	MP4Info_Exception
  */
 public function __construct($totalSize, $boxType, $data, $parent = false)
 {
     if (!self::isCompatible($boxType, $parent)) {
         throw new Exception('This box isn\'t "tkhd"');
     }
     // Get timezone
     if (self::$timezone === false) {
         self::$timezone = date('Z');
     }
     // Call ancestor's constructor
     parent::__construct($totalSize, $boxType, '', $parent);
     // Get data
     $data = self::getDataFrom3rd($data, $totalSize);
     // Unpack
     $ar = unpack('Cversion/C3flags', $data);
     if ($ar['version'] == 0) {
         // 32 bit
         $ar2 = unpack('Nctime/Nmtime/NtrackId/Ndummy/Nduration/N2dummy1/nlayer/naltGroup/nvolume/ndummy2/N9matrix/Nwidth/Nheight', substr($data, 4));
     } else {
         if ($ar['version'] == 1) {
             // 64 bit
             $ar2 = unpack('N2ctime/N2mtime/NtrackId/Ndummy/N2duration/N2dummy1/nlayer/naltGroup/nvolume/ndummy2/N9matrix/Nwidth/Nheight', substr($data, 4));
         } else {
             throw new Exception('Unhandled version: ' . $ar['version']);
         }
     }
     // Save
     $this->version = $ar['version'];
     $this->flags = $ar['flags1'] * 65536 + $ar['flags1'] * 256 + $ar['flags1'] * 1;
     $this->ctime = date('r', (isset($ar2['ctime']) ? $ar2['ctime'] : $ar2['ctime1']) - 2082826800 - self::$timezone);
     $this->mtime = date('r', (isset($ar2['mtime']) ? $ar2['mtime'] : $ar2['mtime1']) - 2082826800 - self::$timezone);
     $this->trackId = $ar2['trackId'];
     $this->duration = isset($ar2['duration']) ? $ar2['duration'] : $ar2['duration1'];
     $this->layer = $ar2['layer'] > 32767 ? $ar2['layer'] - 65536 : $ar2['layer'];
     $this->volume = MP4Info_Helper::fromFixed8($ar2['volume']);
     $this->width = MP4Info_Helper::fromFixed16($ar2['width']);
     $this->height = MP4Info_Helper::fromFixed16($ar2['height']);
 }
Beispiel #11
0
 /**
  * Create a box from file stream
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @param	file				$f
  * @param	MP4Info_Box|false	$parent
  * @return	MP4Info_Box
  * @access 	public
  * @static
  */
 public static function fromStream($f, $parent = false)
 {
     // Get box header
     $buf = fread($f, 8);
     if (strlen($buf) < 8) {
         return false;
     }
     $ar = unpack('NtotalSize/NboxType', $buf);
     if ($ar['totalSize'] == 1) {
         // Size is bigger than 4GB :-O die
         // Skip ExtendedSize(UI64) and try to decode anyway
         $buf = fread($f, 8);
         $ar2 = unpack('N2extSize', $buf);
         if ($ar2['extSize1'] > 0) {
             throw new Exception('Extended size not supported');
         } else {
             $ar['totalSize'] = $ar2['extSize2'];
         }
     }
     // Check if we need to skip
     if (self::skipBoxType($ar['boxType'])) {
         //print '+++ Skipping box '.pack('N',$ar['boxType']).'<br>';
         fseek($f, $ar['totalSize'] - 8, SEEK_CUR);
         return self::fromStream($f, $parent);
     }
     // Check if box is a container, and skip it if so
     if (self::ignoreBoxType($ar['boxType'])) {
         //print '+++ Ignoring box '.pack('N',$ar['boxType']).' of size '.$ar['totalSize'].'<br>';
         return self::fromStream($f, $parent);
     }
     // Get box content
     if ($ar['totalSize'] > 0) {
         if ($ar['totalSize'] < 256 * 1024) {
             $data = fread($f, $ar['totalSize'] - 8);
         } else {
             $data = $f;
         }
     } else {
         $data = '';
     }
     // Create box object
     $box = MP4Info_Box::factory($ar['totalSize'], $ar['boxType'], $data, $parent);
     //print 'Got box from stream of type 0x'.dechex($ar['boxType']).'('.pack('N',$ar['boxType']).') and size '.$ar['totalSize'].' bytes: '.$box->toString().'<br>';
     return $box;
 }