Location: PHPKode > scripts > ID > id3/ID3.class.php
<?php
/**
* Retrieves ID3v2 tag information from MP3 files.
*
* Changelog:
* 1.0 base done by Tadeu.
* 1.1 added ability to retrieve more information i.e attached picture, 
* mood, comments and so on.
* 2.0 Rebuilt, cleaned up the class so it fits PHP5 standards and 
* fine OOP. ;)
* 
* @author Tadeu Oliveira <tadeu.fo ( at ) gmail.com>, Ronald Pompa <pompa ( at ) kth.se>
* @version 2.0
**/

class ID3 { 

	// instance vars
	private $file_name;
	private $tags;   
	private $tags_count; 
	// constants
	const DEBUG	= false;

	/**
	* Constructor reads in a file location of an mp3 file.
	* 
	* @param $file_name		An mp3 file.
	**/
	public function __construct($file_name)
	{ 
		$this->file_name = $file_name;
		$this->tags = array();
		$this->tags_count = 0;
		$this->getInfo();
	}
	
	/**
	* Destructor removes all pointers to data that were used in 
	* the instance variables.
	*
	*/
	public function __destruct()
	{
		$this->tags = NULL;
		$this->tags_count = 0;
		$this->file_name = "";
	}
	
	/**
	* Converts hex data to binary.
	*
	* @return $data 	Returns data as binary.
	**/
	private function hex2bin($data) 
	{ 
		$len = strlen($data); 
		for($i=0;$i<$len;$i+=2) { 
			$data .= pack("C",hexdec(substr($data,$i,2))); 
		} 
		return $data; 
	} 
    
	/**
	* Gets the frame size.
	*
	* @return $total 	the total of the frame size.
	**/
	private function get_frame_size($fourBytes)
	{ 
		$tamanho[0] = str_pad(base_convert(substr($fourBytes,0,2),16,2),7,0,STR_PAD_LEFT); 
		$tamanho[1] = str_pad(base_convert(substr($fourBytes,2,2),16,2),7,0,STR_PAD_LEFT); 
		$tamanho[2] = str_pad(base_convert(substr($fourBytes,4,2),16,2),7,0,STR_PAD_LEFT); 
		$tamanho[3] = str_pad(base_convert(substr($fourBytes,6,2),16,2),7,0,STR_PAD_LEFT); 
		$total =    $tamanho[0].$tamanho[1].$tamanho[2].$tamanho[3]; 
		
		$tamanho[0] = substr($total,0,8); 
		$tamanho[1] = substr($total,8,8); 
		$tamanho[2] = substr($total,16,8); 
		$tamanho[3] = substr($total,24,8); 
		$total =    $tamanho[0].$tamanho[1].$tamanho[2].$tamanho[3]; 
		
		$total = base_convert($total,2,10); 
		
		return $total; 
	} 
	
	/**
	* Retrieves tags from the ID3 header.
	*
	* @param $text	Binary safe data from an mp3 file.
	* @param $tags	An array to put your retrieved data in. 
	**/
	private function extractTags($text, &$tags)
	{ 
		$size = -1;
		while ((strlen($text) != 0) and ($size != 0)) { 
			$ID    = substr($text,0,4); 
			$aux   = substr($text,4,4); 
			$aux   = bin2hex($aux); 
			$size  = $this->get_frame_size($aux); 
			$flags = substr($text,8,2); 
			$info  = substr($text,11,$size-1); 
			if ($size != 0){ 
				$tags[$ID] = $info; 
				$this->tags_count++; 
			} 
			$text = substr($text,10+$size,strlen($text)); 
		} 
	} 

	/**
	* Gets the necessary data from an mp3 file.
	*
	* @return true if no errors occurs.
	**/
	private function getInfo()
	{ 
		//TODO check for mp3 ext.
		if ($this->file_name != "") { 
			$mp3 = @fopen($this->file_name,"rb"); 
			$header = @fread($mp3,10); 
			
			if (!$header) { 
				if (self::DEBUG)
					printf("Unable to open MP3 file.\n");

				return false; 
			} 
			
			if (substr($header,0,3) != "ID3") { 
				if (self::DEBUG)
					printf("ID3v2 Tag not found on this file.\n");

				return false;  
			}
 
			$header = bin2hex($header); 
			$version = base_convert(substr($header,6,2),16,10) . "." . 
				base_convert(substr($header,8,2),16,10); 
			$flags = base_convert(substr($header,10,2),16,2); 
			$flags = str_pad($flags,8,0,STR_PAD_LEFT); 

			// no func really. Just interesting to see.
			if (self::DEBUG) {
				if ($flags[7] == 1){ 
					printf("with Unsynchronisation\n"); 
				}	 
				else if ($flags[6] == 1){ 
					printf("with Extended header\n");
				} 
			}
			
			
			if ($flags[5] == 1){
				if (self::DEBUG)
					printf("TAG not Supported.");

				return false; 
			} 
	
			$total = $this->get_frame_size(substr($header,12,8)); 
			$text = @fread($mp3,$total); 
			fclose($mp3); 
			$this->extractTags($text, $this->tags); 
		} else { 
			if (self::DEBUG)
				printf("Parameter missing in constructor, please put in a filename!\n");

			return false; 
		} 
			
		return true; 
	} 

	/**
	* Retrieves information based on what frame you assign it to. 
	* More info found on http://www.id3.org/id3v2.4.0-frames-
	*
	* The most common are: TIT2 (title), TPE1 (artist), TRCK (track), 
	* TALB (album), APIC (attached picture).
	*
	* @param $frame		An ID3 frame tag. 
	* @return Returns the information if tag found, else false.
	**/
	public function getFrame($frame)
	{ 	
		if (array_key_exists($frame, $this->tags)){ 
			return $this->tags[$frame]; 
		} else { 
			if (self::DEBUG)
				printf($frame . " was not found in the file.");
				
			return false; 
		} 
	} 
}
?> 
Return current item: ID