245 lines
6.8 KiB
PHP
245 lines
6.8 KiB
PHP
<?php
|
|
|
|
// Copyright (C) 2009-2015, Cockos Incorporated
|
|
// License: GPL
|
|
// do not edit this file -- edit stream-config.php
|
|
|
|
// to broadcast:
|
|
// use latest reaper_shoutcast, and use http://server/stream.php?stream=streamname for the server
|
|
// to stream:
|
|
// in Winamp or VLC or whatnot, use http://server/stream.php?stream=streamname
|
|
// (you can optionally append &file.nsv or &file.mp3 to force the file type for the receiving app)
|
|
|
|
include("stream-config.php");
|
|
|
|
function write_session_file($fn, $curfn, $session, $name, $title)
|
|
{
|
|
$fp = @fopen($fn,"w");
|
|
if ($fp)
|
|
{
|
|
flock($fp,LOCK_EX);
|
|
fwrite($fp,$curfn . "\n" . $session . "\n" . $name . "\n" . $title . "\n");
|
|
flock($fp,LOCK_UN);
|
|
fclose($fp);
|
|
}
|
|
}
|
|
|
|
function read_session_file($fn)
|
|
{
|
|
$ret = array();
|
|
$ret["curfn"] = $ret["session"] = $ret["name"] = $ret["title"] = "";
|
|
$fp = @fopen($fn,"r");
|
|
if ($fp)
|
|
{
|
|
flock($fp,LOCK_SH);
|
|
$ret["curfn"] = rtrim(fgets($fp,1024));
|
|
$ret["session"] = rtrim(fgets($fp,1024));
|
|
$ret["name"] = rtrim(fgets($fp,1024));
|
|
$ret["title"] = rtrim(fgets($fp,1024));
|
|
flock($fp,LOCK_UN);
|
|
fclose($fp);
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
function update_log($rdfilename, $str)
|
|
{
|
|
$fp = @fopen($rdfilename . ".log","a");
|
|
if ($fp) {
|
|
fwrite($fp,$str . " " . time() . "\n");
|
|
fclose($fp);
|
|
}
|
|
}
|
|
|
|
|
|
// validate stream
|
|
$stream_name = trim($_REQUEST['stream']);
|
|
if ($stream_name=="") $stream_name = $config_default_stream;
|
|
|
|
if ($stream_name == "" || !isset($config_streams[$stream_name]))
|
|
{
|
|
header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Stream");
|
|
die("invalid stream specified");
|
|
}
|
|
$this_stream = $config_streams[$stream_name];
|
|
$leadpath = isset($this_stream["path"]) && $this_stream["path"] != "" ? $this_stream["path"] : $stream_name;
|
|
$timeout = isset($this_stream["session_timeout"]) && $this_stream["session_timeout"] > 5 ?
|
|
$this_stream["session_timeout"] : $config_session_timeout;
|
|
$presend = (isset($this_stream["presend"]) && $this_stream["presend"] > 0 ? $this_stream["presend"] : $config_presend)|0;
|
|
if ($presend < 1) $presend = 1;
|
|
|
|
$keep_files = isset($this_stream["keep_files"]) ? $this_stream["keep_files"] : $config_keep_files;
|
|
|
|
$sessfn = $leadpath . "/" . $stream_name . "_session.txt";
|
|
|
|
$now = time();
|
|
$is_bc = (trim($_POST['broadcast']) != "");
|
|
|
|
clearstatcache();
|
|
|
|
if ($is_bc)
|
|
{
|
|
if (trim($_POST['broadcast']) != $this_stream["password"])
|
|
{
|
|
header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Password");
|
|
die("invalid password");
|
|
}
|
|
|
|
if (!$_FILES || !($file = $_FILES["file"])) die("no file sent");
|
|
|
|
if (!is_dir($leadpath)) @mkdir($leadpath,0775);
|
|
|
|
$sessinfo = read_session_file($sessfn);
|
|
|
|
$last_file = $sessinfo["curfn"];
|
|
$last_sess = $sessinfo["session"];
|
|
$this_sess = filter_var($_REQUEST['session'],FILTER_SANITIZE_NUMBER_INT);
|
|
|
|
if ($last_sess != $this_sess ||
|
|
$last_file == "" ||
|
|
abs(@filemtime($leadpath . "/" . $last_file) - time()) > $timeout)
|
|
{
|
|
if (!$keep_files && $last_file != "")
|
|
{
|
|
@unlink($leadpath . "/" . $last_file);
|
|
@unlink($leadpath . "/" . $last_file . ".log");
|
|
}
|
|
|
|
$sessinfo["curfn"] = $stream_name . "_" . date("ymd_His") . ".mp3";
|
|
}
|
|
|
|
if ($last_file != $sessinfo["curfn"] ||
|
|
rtrim($_REQUEST['name']) != $sessinfo["name"] ||
|
|
rtrim($_REQUEST['title']) != $sessinfo["title"])
|
|
{
|
|
write_session_file($sessfn,$sessinfo["curfn"], $this_sess,$_REQUEST['name'],$_REQUEST['title']);
|
|
update_log($leadpath . "/" . $sessinfo["curfn"],"BEGIN");
|
|
}
|
|
|
|
if (is_uploaded_file($file["tmp_name"]))
|
|
{
|
|
$fp = @fopen($file["tmp_name"],"rb");
|
|
$fpo = @fopen($leadpath . "/" . $sessinfo["curfn"],"ab");
|
|
if ($fp && $fpo) while (($x = fread($fp,4096))) fwrite($fpo,$x);
|
|
if ($fp) fclose($fp);
|
|
if ($fpo) fclose($fpo);
|
|
unlink($file["tmp_name"]);
|
|
}
|
|
|
|
die;
|
|
}
|
|
|
|
// stream, validate password if set
|
|
if ($this_stream["listen_password"] != "" &&
|
|
$this_stream["listen_password"] != trim($_REQUEST["password"]))
|
|
{
|
|
header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Stream Password");
|
|
die("invalid password");
|
|
}
|
|
|
|
|
|
$sessinfo = read_session_file($sessfn);
|
|
$sesslasttime = filemtime($sessfn);
|
|
$rdfilename = $leadpath . "/" . $sessinfo["curfn"];
|
|
|
|
if ($sessinfo["curfn"] == "" || abs(@filemtime($rdfilename) - time()) > $timeout)
|
|
{
|
|
header($_SERVER["SERVER_PROTOCOL"] . " 403 Stream Inactive");
|
|
die("stream inactive");
|
|
}
|
|
|
|
if ($_REQUEST['get'] == "info") die($sessinfo["name"] . "\n" . $sessinfo["title"]);
|
|
if ($_REQUEST['get'] == "title") die($sessinfo["title"]);
|
|
|
|
$fp = @fopen($rdfilename,"rb");
|
|
if (!$fp)
|
|
{
|
|
header($_SERVER["SERVER_PROTOCOL"] . " 403 Stream Inactive");
|
|
die("stream error");
|
|
}
|
|
@fseek($fp,-$presend,SEEK_END);
|
|
|
|
set_time_limit(3600*3);
|
|
header("Content-type: audio/mpeg");
|
|
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
|
|
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
|
|
$streamname = trim($sessinfo["name"]);
|
|
if ($streamname != "") header("icy-name: $streamname");
|
|
|
|
$want_title = rtrim($sessinfo["title"]);
|
|
if ($want_title == '') $want_title = NULL;
|
|
|
|
$meta_int=$meta_pos=0;
|
|
|
|
if ((int)$_SERVER['HTTP_ICY_METADATA'] > 0)
|
|
{
|
|
$meta_int = 32000;
|
|
header("icy-metaint: $meta_int");
|
|
if ($_SERVER["SERVER_PROTOCOL"] != "HTTP/1.0")
|
|
{
|
|
// VLC requires an invalid content-length to prevent chunked mode
|
|
if (strstr($_SERVER["HTTP_USER_AGENT"],"VLC")) header("Content-length:-1");
|
|
}
|
|
}
|
|
|
|
$logfile = $rdfilename . ".log";
|
|
$log_ident = $_SERVER["REMOTE_ADDR"] . "_" . time();
|
|
update_log($rdfilename, "CONNECT $log_ident");
|
|
$next_log_update = time() + 30;
|
|
while (!connection_aborted())
|
|
{
|
|
if (time() > $next_log_update)
|
|
{
|
|
$next_log_update = time() + 30;
|
|
update_log($rdfilename,"UPDATE $log_ident");
|
|
}
|
|
$rdamt = 4096;
|
|
if ($meta_int > 0 && $rdamt > ($meta_int-$meta_pos)) $rdamt = ($meta_int - $meta_pos);
|
|
$buf = fread($fp,$rdamt);
|
|
if ($buf === FALSE)
|
|
{
|
|
usleep(500*1000);
|
|
clearstatcache();
|
|
if (abs(@filemtime($rdfile) - time()) > $timeout)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
echo $buf;
|
|
if ($meta_int > 0)
|
|
{
|
|
$meta_pos += strlen($buf);
|
|
if ($meta_pos >= $meta_int)
|
|
{
|
|
$meta_pos=0;
|
|
clearstatcache();
|
|
$sesstime = filemtime($sessfn);
|
|
if ($sesstime != $sesslasttime)
|
|
{
|
|
$sessinfo = read_session_file($sessfn);
|
|
$sesslasttime = $sesstime;
|
|
$title = rtrim($sessinfo["title"]);
|
|
if ($title !== $want_title) $want_title=$title;
|
|
}
|
|
|
|
if ($want_title !== NULL)
|
|
{
|
|
$want_title = "StreamTitle='" . str_replace("'","",$want_title) . "';";
|
|
$tb=(int) (((strlen($want_title) + 1 + 15)/16));
|
|
echo chr($tb);
|
|
echo $want_title;
|
|
$tb = $tb*16 - strlen($want_title);
|
|
while ($tb-- > 0) echo chr(0);
|
|
$want_title=NULL;
|
|
}
|
|
else echo chr(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
update_log($rdfilename, "DISCONNECT $log_ident");
|
|
if ($fp) fclose($fp);
|
|
?>
|