type = $type;
$this->songs = $song_ids;
$this->web_path = Config::get('web_path');
$this->user_id = $GLOBALS['user']->id;
if (Config::get('force_http_play')) {
$this->web_path = preg_replace("/https/", "http",$this->web_path);
}
// Generate the session ID
$this->session = md5(uniqid(rand(), true));;
} // Constructor
/**
* start
*runs this and depending on the type passed it will
*call the correct function
*/
public function start() {
if (!is_array($this->songs)) {
debug_event('stream','Error: No Songs Passed on ' . $this->type . ' stream','2');
return false;
}
// We're starting insert the session into session_stream
if (!$this->insert_session()) {
debug_event('stream','Session Insertion failure, aboring','3');
return false;
}
$methods = get_class_methods('Stream');
$create_function = "create_" . $this->type;
// If in the class, call it
if (in_array($create_function,$methods)) {
$this->{$create_function}();
}
// Assume M3u incase they've pooched the type
else {
$this->create_m3u();
}
} // start
/**
* manual_url_add
* This manually adds a URL to the stream object for passing
* to whatever, this is an exception for when we don't actually
* have a object_id but instead a weird or special URL
*/
public function manual_url_add($url) {
$this->urls[] = $url;
} // manual_url_add
/**
* insert_session
* This inserts a row into the session_stream table
*/
private function insert_session() {
$expire = time() + Config::get('stream_length');
$sql = "INSERT INTO `session_stream` (`id`,`expire`,`user`) " .
"VALUES('$this->session','$expire','$this->user_id')";
$db_results = Dba::query($sql);
if (!$db_results) { return false; }
return true;
} // insert_session
/**
* session_exists
* This checks to see if the passed stream session exists and is valid
*/
public static function session_exists($sid) {
$sid = Dba::escape($sid);
$time = time();
$sql = "SELECT * FROM `session_stream` WHERE `id`='$sid' AND `expire` > '$time'";
$db_results = Dba::query($sql);
if ($row = Dba::fetch_assoc($db_results)) {
return true;
}
return false;
} // session_exists
/**
* gc_session
* This function performes the garbage collection stuff, run on extend and on now playing refresh
*/
public static function gc_session($ip='',$agent='',$uid='',$sid='') {
$time = time();
$sql = "DELETE FROM `session_stream` WHERE `expire` < '$time'";
$db_results = Dba::query($sql);
// We need all of this to run this query
if ($ip AND $agent AND $uid AND $sid) {
$sql = "DELETE FROM `session_stream` WHERE `ip`='$ip' AND `agent`='$agent' AND `user`='$uid' AND `id` != '$sid'";
$db_results = Dba::query($sql);
}
} // gc_session
/**
* extend_session
* This takes the passed sid and does a replace into also setting the user
* agent and IP also do a little GC in this function
*/
public static function extend_session($sid,$uid) {
$expire = time() + Config::get('stream_length');
$sid = Dba::escape($sid);
$agent = Dba::escape($_SERVER['HTTP_USER_AGENT']);
$ip = ip2int($_SERVER['REMOTE_ADDR']);
$uid = Dba::escape($uid);
$sql = "UPDATE `session_stream` SET `expire`='$expire', `agent`='$agent', `ip`='$ip' " .
"WHERE `id`='$sid'";
$db_results = Dba::query($sql);
self::gc_session($ip,$agent,$uid,$sid);
return true;
} // extend_session
/**
* create_simplem3u
* this creates a simple m3u without any of the extended information
*/
public function create_simple_m3u() {
header("Cache-control: public");
header("Content-Disposition: filename=playlist.m3u");
header("Content-Type: audio/x-mpegurl;");
// Flip for the poping!
asort($this->urls);
/* Foreach songs */
foreach ($this->songs as $song_id) {
// If it's a place-holder
if ($song_id == '-1') {
echo array_pop($this->urls) . "\n";
continue;
}
$song = new Song($song_id);
if ($song->type == ".flac") { $song->type = ".ogg"; }
if ($GLOBALS['user']->prefs['play_type'] == 'downsample') {
$ds = $GLOBALS['user']->prefs['sample_rate'];
}
echo $song->get_url($this->session);
} // end foreach
/* Foreach the additional URLs */
foreach ($this->urls as $url) {
echo "$url\n";
}
} // simple_m3u
/**
* create_m3u
* creates an m3u file, this includes the EXTINFO and as such can be
* large with very long playlsits
*/
public public function create_m3u() {
// Send the client an m3u playlist
header("Cache-control: public");
header("Content-Disposition: filename=ampache_playlist.m3u");
header("Content-Type: audio/x-mpegurl;");
echo "#EXTM3U\n";
// Flip for the popping
asort($this->urls);
// Foreach the songs in this stream object
foreach ($this->songs as $song_id) {
if ($song_id == '-1') {
echo "#EXTINF: URL-Add\n";
echo array_pop($this->urls) . "\n";
continue;
}
$song = new Song($song_id);
$song->format();
echo "#EXTINF:$song->time," . $song->f_artist_full . " - " . $song->title . "\n";
echo $song->get_url($this->session) . "\n";
} // end foreach
/* Foreach URLS */
foreach ($this->urls as $url) {
echo "#EXTINF: URL-Add\n";
echo $url . "\n";
}
} // create_m3u
/*!
@function create_pls
@discussion creates a pls file
*/
function create_pls() {
/* Count entries */
$total_entries = count($this->songs) + count($this->urls);
// Send the client a pls playlist
header("Cache-control: public");
header("Content-Disposition: filename=ampache-playlist.pls");
header("Content-Type: audio/x-scpls;");
echo "[Playlist]\n";
echo "NumberOfEntries=$total_entries\n";
foreach ($this->songs as $song_id) {
$i++;
$song = new Song($song_id);
$song->format();
$song_name = $song->f_artist_full . " - " . $song->title . "." . $song->type;
$song_url = $song->get_url($this->session);
echo "File" . $i . "=$song_url\n";
echo "Title" . $i . "=$song_name\n";
echo "Length" . $i . "=$song->time\n";
} // end foreach songs
/* Foreach Additional URLs */
foreach ($this->urls as $url) {
$i++;
echo "File" . $i ."=$url\n";
echo "Title". $i . "=AddedURL\n";
echo "Length" . $i . "=-1\n";
} // end foreach urls
echo "Version=2\n";
} // create_pls
/*!
@function create_asx
@discussion creates an ASZ playlist (Thx Samir Kuthiala)
*/
function create_asx() {
header("Cache-control: public");
header("Content-Disposition: filename=playlist.asx");
header("Content-Type: video/x-ms-asf;");
echo "