| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 | <?php//////////////////////////////////////////////////////////////////// getID3() by James Heinrich <info@getid3.org>               ////  available at https://github.com/JamesHeinrich/getID3       ////            or https://www.getid3.org                        ////            or http://getid3.sourceforge.net                 ////  see readme.txt for more details                            /////////////////////////////////////////////////////////////////////                                                             //// module.misc.cue.php                                         //// module for analyzing CUEsheet files                         //// dependencies: NONE                                          ////                                                             /////////////////////////////////////////////////////////////////////                                                             //// Module originally written [2009-Mar-25] by                  ////      Nigel Barnes <ngbarnesØhotmail*com>                    //// Minor reformatting and similar small changes to integrate   ////   into getID3 by James Heinrich <info@getid3.org>           ////                                                            /////////////////////////////////////////////////////////////////////* * CueSheet parser by Nigel Barnes. * * This is a PHP conversion of CueSharp 0.5 by Wyatt O'Day (wyday.com/cuesharp) *//** * A CueSheet class used to open and parse cuesheets. * */if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers	exit;}class getid3_cue extends getid3_handler{	public $cuesheet = array();	/**	 * @return bool	 */	public function Analyze() {		$info = &$this->getid3->info;		$info['fileformat'] = 'cue';		$this->readCueSheetFilename($info['filenamepath']);		$info['cue'] = $this->cuesheet;		return true;	}	/**	 * @param string $filename	 *	 * @return array	 */	public function readCueSheetFilename($filename)	{		$filedata = file_get_contents($filename);		return $this->readCueSheet($filedata);	}	/**	 * Parses a cue sheet file.	 *	 * @param string $filedata	 *	 * @return array	 */	public function readCueSheet(&$filedata)	{		$cue_lines = array();		foreach (explode("\n", str_replace("\r", '', $filedata)) as $line)		{			if ( (strlen($line) > 0) && ($line[0] != '#'))			{				$cue_lines[] = trim($line);			}		}		$this->parseCueSheet($cue_lines);		return $this->cuesheet;	}	/**	 * Parses the cue sheet array.	 *	 * @param array $file - The cuesheet as an array of each line.	 */	public function parseCueSheet($file)	{		//-1 means still global, all others are track specific		$track_on = -1;		$currentFile = null;		foreach ($file as $line) {			list($key) = explode(' ', strtolower($line), 2);			switch ($key)			{				case 'catalog':				case 'cdtextfile':				case 'isrc':				case 'performer':				case 'songwriter':				case 'title':					$this->parseString($line, $track_on);					break;				case 'file':					$currentFile = $this->parseFile($line);					break;				case 'flags':					$this->parseFlags($line, $track_on);					break;				case 'index':				case 'postgap':				case 'pregap':					$this->parseIndex($line, $track_on);					break;				case 'rem':					$this->parseComment($line, $track_on);					break;				case 'track':					$track_on++;					$this->parseTrack($line, $track_on);					if (isset($currentFile)) // if there's a file					{						$this->cuesheet['tracks'][$track_on]['datafile'] = $currentFile;					}					break;				default:					//save discarded junk and place string[] with track it was found in					$this->parseGarbage($line, $track_on);					break;			}		}	}	/**	 * Parses the REM command.	 *	 * @param string  $line - The line in the cue file that contains the TRACK command.	 * @param integer $track_on - The track currently processing.	 */	public function parseComment($line, $track_on)	{		$explodedline = explode(' ', $line, 3);		$comment_REM  = (isset($explodedline[0]) ? $explodedline[0] : '');		$comment_type = (isset($explodedline[1]) ? $explodedline[1] : '');		$comment_data = (isset($explodedline[2]) ? $explodedline[2] : '');		if (($comment_REM == 'REM') && $comment_type) {			$comment_type  = strtolower($comment_type);			$commment_data = trim($comment_data, ' "');			if ($track_on != -1) {				$this->cuesheet['tracks'][$track_on]['comments'][$comment_type][] = $comment_data;			} else {				$this->cuesheet['comments'][$comment_type][] = $comment_data;			}		}	}	/**	 * Parses the FILE command.	 *	 * @param string $line - The line in the cue file that contains the FILE command.	 *	 * @return array - Array of FILENAME and TYPE of file..	 */	public function parseFile($line)	{		$line =            substr($line, strpos($line, ' ') + 1);		$type = strtolower(substr($line, strrpos($line, ' ')));		//remove type		$line = substr($line, 0, strrpos($line, ' ') - 1);		//if quotes around it, remove them.		$line = trim($line, '"');		return array('filename'=>$line, 'type'=>$type);	}	/**	 * Parses the FLAG command.	 *	 * @param string  $line - The line in the cue file that contains the TRACK command.	 * @param integer $track_on - The track currently processing.	 */	public function parseFlags($line, $track_on)	{		if ($track_on != -1)		{			foreach (explode(' ', strtolower($line)) as $type)			{				switch ($type)				{					case 'flags':						// first entry in this line						$this->cuesheet['tracks'][$track_on]['flags'] = array(							'4ch'  => false,							'data' => false,							'dcp'  => false,							'pre'  => false,							'scms' => false,						);						break;					case 'data':					case 'dcp':					case '4ch':					case 'pre':					case 'scms':						$this->cuesheet['tracks'][$track_on]['flags'][$type] = true;						break;					default:						break;				}			}		}	}	/**	 * Collect any unidentified data.	 *	 * @param string  $line - The line in the cue file that contains the TRACK command.	 * @param integer $track_on - The track currently processing.	 */	public function parseGarbage($line, $track_on)	{		if ( strlen($line) > 0 )		{			if ($track_on == -1)			{				$this->cuesheet['garbage'][] = $line;			}			else			{				$this->cuesheet['tracks'][$track_on]['garbage'][] = $line;			}		}	}	/**	 * Parses the INDEX command of a TRACK.	 *	 * @param string  $line - The line in the cue file that contains the TRACK command.	 * @param integer $track_on - The track currently processing.	 */	public function parseIndex($line, $track_on)	{		$type = strtolower(substr($line, 0, strpos($line, ' ')));		$line =            substr($line, strpos($line, ' ') + 1);		$number = 0;		if ($type == 'index')		{			//read the index number			$number = intval(substr($line, 0, strpos($line, ' ')));			$line   =        substr($line, strpos($line, ' ') + 1);		}		//extract the minutes, seconds, and frames		$explodedline = explode(':', $line);		$minutes = (isset($explodedline[0]) ? $explodedline[0] : '');		$seconds = (isset($explodedline[1]) ? $explodedline[1] : '');		$frames  = (isset($explodedline[2]) ? $explodedline[2] : '');		switch ($type) {			case 'index':				$this->cuesheet['tracks'][$track_on][$type][$number] = array('minutes'=>intval($minutes), 'seconds'=>intval($seconds), 'frames'=>intval($frames));				break;			case 'pregap':			case 'postgap':				$this->cuesheet['tracks'][$track_on][$type]          = array('minutes'=>intval($minutes), 'seconds'=>intval($seconds), 'frames'=>intval($frames));				break;		}	}	/**	 * @param string $line	 * @param int    $track_on	 */	public function parseString($line, $track_on)	{		$category = strtolower(substr($line, 0, strpos($line, ' ')));		$line     =            substr($line, strpos($line, ' ') + 1);		//get rid of the quotes		$line = trim($line, '"');		switch ($category)		{			case 'catalog':			case 'cdtextfile':			case 'isrc':			case 'performer':			case 'songwriter':			case 'title':				if ($track_on == -1)				{					$this->cuesheet[$category] = $line;				}				else				{					$this->cuesheet['tracks'][$track_on][$category] = $line;				}				break;			default:				break;		}	}	/**	 * Parses the TRACK command.	 *	 * @param string  $line - The line in the cue file that contains the TRACK command.	 * @param integer $track_on - The track currently processing.	 */	public function parseTrack($line, $track_on)	{		$line = substr($line, strpos($line, ' ') + 1);		$track = ltrim(substr($line, 0, strpos($line, ' ')), '0');		//find the data type.		$datatype = strtolower(substr($line, strpos($line, ' ') + 1));		$this->cuesheet['tracks'][$track_on] = array('track_number'=>$track, 'datatype'=>$datatype);	}}
 |