Files
tlib/oversampling/WDL/sc_bounce/stream.php
2024-05-24 13:28:31 +02:00

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);
?>