Create FUNDING.yml
[wdl/wdl-ol.git] / WDL / sc_bounce / stream.php
blob4f226ca3c54fc2ead7d26dcb7332cba529e751cc
1 <?php
3 // Copyright (C) 2009-2015, Cockos Incorporated
4 // License: GPL
5 // do not edit this file -- edit stream-config.php
7 // to broadcast:
8 // use latest reaper_shoutcast, and use http://server/stream.php?stream=streamname for the server
9 // to stream:
10 // in Winamp or VLC or whatnot, use http://server/stream.php?stream=streamname
11 // (you can optionally append &file.nsv or &file.mp3 to force the file type for the receiving app)
13 include("stream-config.php");
15 function write_session_file($fn, $curfn, $session, $name, $title)
17 $fp = @fopen($fn,"w");
18 if ($fp)
20 flock($fp,LOCK_EX);
21 fwrite($fp,$curfn . "\n" . $session . "\n" . $name . "\n" . $title . "\n");
22 flock($fp,LOCK_UN);
23 fclose($fp);
27 function read_session_file($fn)
29 $ret = array();
30 $ret["curfn"] = $ret["session"] = $ret["name"] = $ret["title"] = "";
31 $fp = @fopen($fn,"r");
32 if ($fp)
34 flock($fp,LOCK_SH);
35 $ret["curfn"] = rtrim(fgets($fp,1024));
36 $ret["session"] = rtrim(fgets($fp,1024));
37 $ret["name"] = rtrim(fgets($fp,1024));
38 $ret["title"] = rtrim(fgets($fp,1024));
39 flock($fp,LOCK_UN);
40 fclose($fp);
42 return $ret;
45 function update_log($rdfilename, $str)
47 $fp = @fopen($rdfilename . ".log","a");
48 if ($fp) {
49 fwrite($fp,$str . " " . time() . "\n");
50 fclose($fp);
55 // validate stream
56 $stream_name = trim($_REQUEST['stream']);
57 if ($stream_name=="") $stream_name = $config_default_stream;
59 if ($stream_name == "" || !isset($config_streams[$stream_name]))
61 header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Stream");
62 die("invalid stream specified");
64 $this_stream = $config_streams[$stream_name];
65 $leadpath = isset($this_stream["path"]) && $this_stream["path"] != "" ? $this_stream["path"] : $stream_name;
66 $timeout = isset($this_stream["session_timeout"]) && $this_stream["session_timeout"] > 5 ?
67 $this_stream["session_timeout"] : $config_session_timeout;
68 $presend = (isset($this_stream["presend"]) && $this_stream["presend"] > 0 ? $this_stream["presend"] : $config_presend)|0;
69 if ($presend < 1) $presend = 1;
71 $keep_files = isset($this_stream["keep_files"]) ? $this_stream["keep_files"] : $config_keep_files;
73 $sessfn = $leadpath . "/" . $stream_name . "_session.txt";
75 $now = time();
76 $is_bc = (trim($_POST['broadcast']) != "");
78 clearstatcache();
80 if ($is_bc)
82 if (trim($_POST['broadcast']) != $this_stream["password"])
84 header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Password");
85 die("invalid password");
88 if (!$_FILES || !($file = $_FILES["file"])) die("no file sent");
90 if (!is_dir($leadpath)) @mkdir($leadpath,0775);
92 $sessinfo = read_session_file($sessfn);
94 $last_file = $sessinfo["curfn"];
95 $last_sess = $sessinfo["session"];
96 $this_sess = filter_var($_REQUEST['session'],FILTER_SANITIZE_NUMBER_INT);
98 if ($last_sess != $this_sess ||
99 $last_file == "" ||
100 abs(@filemtime($leadpath . "/" . $last_file) - time()) > $timeout)
102 if (!$keep_files && $last_file != "")
104 @unlink($leadpath . "/" . $last_file);
105 @unlink($leadpath . "/" . $last_file . ".log");
108 $sessinfo["curfn"] = $stream_name . "_" . date("ymd_His") . ".mp3";
111 if ($last_file != $sessinfo["curfn"] ||
112 rtrim($_REQUEST['name']) != $sessinfo["name"] ||
113 rtrim($_REQUEST['title']) != $sessinfo["title"])
115 write_session_file($sessfn,$sessinfo["curfn"], $this_sess,$_REQUEST['name'],$_REQUEST['title']);
116 update_log($leadpath . "/" . $sessinfo["curfn"],"BEGIN");
119 if (is_uploaded_file($file["tmp_name"]))
121 $fp = @fopen($file["tmp_name"],"rb");
122 $fpo = @fopen($leadpath . "/" . $sessinfo["curfn"],"ab");
123 if ($fp && $fpo) while (($x = fread($fp,4096))) fwrite($fpo,$x);
124 if ($fp) fclose($fp);
125 if ($fpo) fclose($fpo);
126 unlink($file["tmp_name"]);
129 die;
132 // stream, validate password if set
133 if ($this_stream["listen_password"] != "" &&
134 $this_stream["listen_password"] != trim($_REQUEST["password"]))
136 header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Stream Password");
137 die("invalid password");
141 $sessinfo = read_session_file($sessfn);
142 $sesslasttime = filemtime($sessfn);
143 $rdfilename = $leadpath . "/" . $sessinfo["curfn"];
145 if ($sessinfo["curfn"] == "" || abs(@filemtime($rdfilename) - time()) > $timeout)
147 header($_SERVER["SERVER_PROTOCOL"] . " 403 Stream Inactive");
148 die("stream inactive");
151 if ($_REQUEST['get'] == "info") die($sessinfo["name"] . "\n" . $sessinfo["title"]);
152 if ($_REQUEST['get'] == "title") die($sessinfo["title"]);
154 $fp = @fopen($rdfilename,"rb");
155 if (!$fp)
157 header($_SERVER["SERVER_PROTOCOL"] . " 403 Stream Inactive");
158 die("stream error");
160 @fseek($fp,-$presend,SEEK_END);
162 set_time_limit(3600*3);
163 header("Content-type: audio/mpeg");
164 header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
165 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
166 $streamname = trim($sessinfo["name"]);
167 if ($streamname != "") header("icy-name: $streamname");
169 $want_title = rtrim($sessinfo["title"]);
170 if ($want_title == '') $want_title = NULL;
172 $meta_int=$meta_pos=0;
174 if ((int)$_SERVER['HTTP_ICY_METADATA'] > 0)
176 $meta_int = 32000;
177 header("icy-metaint: $meta_int");
178 if ($_SERVER["SERVER_PROTOCOL"] != "HTTP/1.0")
180 // VLC requires an invalid content-length to prevent chunked mode
181 if (strstr($_SERVER["HTTP_USER_AGENT"],"VLC")) header("Content-length:-1");
185 $logfile = $rdfilename . ".log";
186 $log_ident = $_SERVER["REMOTE_ADDR"] . "_" . time();
187 update_log($rdfilename, "CONNECT $log_ident");
188 $next_log_update = time() + 30;
189 while (!connection_aborted())
191 if (time() > $next_log_update)
193 $next_log_update = time() + 30;
194 update_log($rdfilename,"UPDATE $log_ident");
196 $rdamt = 4096;
197 if ($meta_int > 0 && $rdamt > ($meta_int-$meta_pos)) $rdamt = ($meta_int - $meta_pos);
198 $buf = fread($fp,$rdamt);
199 if ($buf === FALSE)
201 usleep(500*1000);
202 clearstatcache();
203 if (abs(@filemtime($rdfile) - time()) > $timeout)
205 break;
208 else
210 echo $buf;
211 if ($meta_int > 0)
213 $meta_pos += strlen($buf);
214 if ($meta_pos >= $meta_int)
216 $meta_pos=0;
217 clearstatcache();
218 $sesstime = filemtime($sessfn);
219 if ($sesstime != $sesslasttime)
221 $sessinfo = read_session_file($sessfn);
222 $sesslasttime = $sesstime;
223 $title = rtrim($sessinfo["title"]);
224 if ($title !== $want_title) $want_title=$title;
227 if ($want_title !== NULL)
229 $want_title = "StreamTitle='" . str_replace("'","",$want_title) . "';";
230 $tb=(int) (((strlen($want_title) + 1 + 15)/16));
231 echo chr($tb);
232 echo $want_title;
233 $tb = $tb*16 - strlen($want_title);
234 while ($tb-- > 0) echo chr(0);
235 $want_title=NULL;
237 else echo chr(0);
242 update_log($rdfilename, "DISCONNECT $log_ident");
243 if ($fp) fclose($fp);