/** * 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; }