Location: PHPKode > scripts > PHPCast > phpcast.php
<?
// PHPCast 0.0.2
// Mp3 streamer in PHP
//
// Original code and idea from Jordan Waeles (hide@address.com )
//

// Details of the stream
$stream['name']    = "PHPCast Stream"; /* Name of the stream */
$stream['genre']   = "various"; /* Genre of the stream */
$stream['url']     = "http://phpcast.sourceforge.net"; /* URL of the site hosting phpcast */
$stream['public']  = "1"; /* Set to 0 to make the server private */
$stream['bitrate'] = "128"; /* Set this to the bitrate of your mp3 files */
$stream['path']    = "data"; /* Path to the mp3 files. Relative or absolute */

// Configuration of the cache
$cache['active'] = true; /* Set to false to disable cache (up to 3x slower for tags extraction ) */
$cache['type'] 	 = gdbm; /* Type of cache (gdbm, ndbm, db2, db3, db4)
depending on your php compile option */
$cache['directory'] = "cache"; /* Relative or absolute path to save cache files (beware of chmod) */

// Size of shoutcast frames
$taille = 8192;

/* You won't have to touch below for a normal setup */

@ini_set("max_execution_time", "0");
require_once'getid3/getid3.php';
require_once 'getid3/extension.cache.dbm.php';

// headers shoutcast
header("icy-notice1:This is a WINAMP ShoutCast Stream");
header("icy-notice2:You will only see binary data, please press STOP button");
header("icy-name:".$stream['name']);
header("icy-genre:".$stream['genre']);
header("icy-url:".$stream['url']);
if ($stream['public'] == "1") {
	header("icy-pub:1");
}
else {
	header("icy-pub:0");
}

header("icy-br:".$stream['bitrate']);
header("icy-metaint:".$taille);


// Function that alternates mp3 / data while keeping good sync
// (example 8192 bytes of mp3 - X bytes of meta data)
function streamfile($file, $randombegin=false, $offset=0)
{
	GLOBAL $taille;
	GLOBAL $debug;
	GLOBAL $cache;
	/* We start caching support (or not) */
	if($cache['active'] == "true") {
		$getID3 = new getID3_cached_dbm($cache['type'], $cache['directory']."/id3.dbm", $cache['directory']."/id3.lock");
	}
	else {
		$getID3 = new getID3();
	}
	$fp = fopen($file,"rb");
	if(!$fp)
	die("Access denied for $file");
	
	// number of bytes left to stream
	$taillefichier = filesize($file);
	
	// we begin in the middle of the mp3
	if($randombegin)
	{
		$random = rand()%$taillefichier;
		$taillefichier -= $random;
		fseek($fp,$random);
	}
	
	// Title of current mp3 file
	// Depending of ID3 tag version
	$fileInfo = $getID3->analyze("$file");
	
	if($fileInfo['id3v2']['comments']['title']) {
		$title = "StreamTitle='".$fileInfo['id3v2']['comments']['title'][0]." - ".$fileInfo['id3v2']['comments']['artist'][0]."';StreamUrl='".$stream['url']."';\n\0";
	}
	elseif($fileInfo['id3v1']['title'])	{
		$title = "StreamTitle='".$fileInfo['id3v1']['title'][0]." - ".$fileInfo['id3v1']['artist'][0]."';StreamUrl='".$stream['url']."';\n\0";
	}
	else {
		$title = "StreamTitle='".addslashes($file)."';StreamUrl='".$stream['url']."';\n\0";
	}
	
	// generating appropriate header
	$tailletitre = strlen($title);
	$headersize = ceil( (float)$tailletitre / 16.0 );
	$headerbyte = chr($headersize);
	
	// while we aren't at the end of the file
	while(!feof($fp))
	{
		// we read $taille data( except if we begin with
		// the end of an other file )
		$meuh = fread($fp,$taille-$offset);
		
		if(!$debug)
		{
			// mpeg stream
			echo $meuh;
		}
		
		// we finished the file
		if(feof($fp))
		{
			// we might have to add data to have
			//  8192 bytes of mpeg
			$offset = $taillefichier;
		}
		else
		{
			// and we count what has already been streamed
			$taillefichier -= $taille;
			// delay is cancelled for next turn,
			// packets are $taille now !
			$offset = 0;
			
			if(!$debug)
			{
				// the first byte is title length / 16 ,
				// then if the titre is 64 bytes long, we'll have 4  (0x04)
				echo $headerbyte;
				// the title
				echo $title;
				// if it doesn't fill $headerbyte * 16 bytes,
				// we put random data for the byte to be the
				// right length ( ici un A, ca marche avec un espace aussi ,
				// meme s'il est recommandé de le faire avec des 0 binaires
				// ( 0x00 ) mais je ne sais pas comment php l'interprete ,
				// et ca semble marcher ainsi )
				for($i=$tailletitre;$i<($headersize*16);$i++)echo chr(65);
			}
		}
		
	}
	fclose($fp);
	
	// We keep the delay for the next frame
	$offset %= $taille;
	if($offset < 0)$offset += $taille;
	
	return $offset;
}

// Little ereg, that compares an string with
// *aster*is*ques with a normal string
function match($pattern, $string)
{
	$stucks = explode("*",$pattern);
	$str = $string;
	for($i=0;$i<count($stucks);$i++)
	{
		$stuck = $stucks[$i];
		if(empty($stuck))continue;
		
		$pos = strpos($str,$stuck);
		$str = stristr($str,$stuck);
		if(($i==0)&&($pos != 0))return false;
		if(!is_string($str))return false;
	}
	return true;
}


// initialisation of the random number generator
srand((float) microtime()*1000000);

// find all files in the mp3 folder
if ($handle = opendir($stream['path']))
{
	// for each file
	while (false !== ($file = readdir($handle)))
	{
		// if it's a read file ( no shortcut / directory )
		if(is_file($stream['path']."/".$file))
		{
			// and that its name ends with .mp3 (case insensitive)
			if(match("*.mp3",strtolower($file)))
			{
				// we put it in the playlist
				$playlist[] = $stream['path']."/".$file;
			}
		}
	}
	// end !
	closedir($handle);
}
else
die("Unable to open mp3 library  !");

if(empty($playlist))
die("There aren't any mp3 files in this diretory !");

// don't touch !
$offset = 0;

// if it's true, we begin at a random position in the file
// User will have the feeling of listening to a real stream
$firstfile = true;

// infinite loop
while(true)
{
	reset($playlist);
	shuffle($playlist);
	
	foreach($playlist as $item)
	{
		$offset = StreamFile($item, $firstfile, $offset);
		if($debug)
		{
			echo $item."<br>";
			echo "offset vaut maintenant $offset<br>";
		}
		// After the first song, we don't begin in the middle
		$firstfile = false;
	}
	if($debug)
	echo "--------- ended !!<br>";
}


?>
Return current item: PHPCast