= $maxencodingprocesses)
{
addlog("Error: Cannot create sesssion, too much sessions already encoding");
return "";
}
// Get a free session
$i=0;
for ($i=0; $i<1000; $i++)
{
$session = "session" .$i;
if (!file_exists('../ram/' .$session))
break;
}
if ($i == 1000)
{
addlog("Error: Cannot find a new session name");
return "";
}
// Default
$qparams = $quality['3g'];
// Get parameters
foreach ($quality as $qn => $qp)
{
if ($qn == $mode)
{
$qparams = $qp;
break;
}
}
// Create session
addlog("Creating new session dir ram/" .$session);
exec('mkdir ../ram/' .$session);
// Extract $channame if needed
switch ($type)
{
case 'tv':
$urlarray = explode("/", $url);
$channum = $urlarray[count($urlarray)-1];
$channame = vdrgetchanname($channum);
break;
case 'rec':
list($channame, $title, $desc, $recorded) = vdrgetrecinfo($url);
break;
default:
$channame = "";
break;
}
// Create logo
if ($type == 'vid')
generatelogo($type, $url, '../ram/' .$session .'/thumb.png');
else
generatelogo($type, $channame, '../ram/' .$session .'/thumb.png');
// FFMPEG debug
if ($ffmpegdebug)
$ffdbg = $ffmpegdebugfile;
else
$ffdbg = "";
// Start encoding
$url = str_replace("\\'", "'", $url);
switch ($type)
{
case 'tv':
$cmd = "./istream.sh \"" .$url ."\" " .$qparams ." " .$httppath ." 2 " .$ffmpegpath ." " .$segmenterpath ." " .$session ." \"" .$ffdbg ."\" \"\" >/dev/null 2>&1 &";
break;
case 'rec':
$cmd = "./istream.sh - " .$qparams ." " .$httppath ." 1260 " .$ffmpegpath ." " .$segmenterpath ." " .$session ." \"" .$ffdbg ."\" \"" .$url ."/0* \" >/dev/null 2>&1 &";
break;
case 'vid':
$cmd = "./istream.sh \"" .$url ."\" " .$qparams ." " .$httppath ." 1260 " .$ffmpegpath ." " .$segmenterpath ." " .$session ." \"" .$ffdbg ."\" \"\" >/dev/null 2>&1 &";
break;
default:
$cmd = "";
}
addlog("Sending encoding command: " .$cmd);
$cmd = str_replace('%', '%%', $cmd);
exec ($cmd);
// Give the time to the scrip to create pids
exec ("sleep 2");
// Write streaminfo
writeinfostream($session, $type, $mode, $url, $channame);
return $session;
}
function sessiondelete($session)
{
$ret = array();
if ($session == 'all')
{
$dir_handle = @opendir('../ram/');
if ($dir_handle)
{
while ($session = readdir($dir_handle))
{
if($session == "." || $session == ".." || $session == 'lost+found')
continue;
if (!is_dir('../ram/' .$session))
continue;
// Get info
list($type, $mode, $url, $channame) = readinfostream($session);
if ($type != "none")
sessiondeletesingle($session);
}
}
}
else
sessiondeletesingle($session);
$ret['status'] = "ok";
$ret['message'] = "Successfully stopped broadcast";
return $ret;
}
function sessiongetinfo($session)
{
$info = array();
addlog("Getting info for session " .$session);
// Get some info
list($type, $mode, $url, $channame) = readinfostream($session);
// Fill common info
$info['session'] = $session;
$info['type'] = $type;
$info['mode'] = $mode;
// Get info
$getid3 = new getID3;
$fileinfo = $getid3->analyze('../ram/' .$session .'/thumb.png');
$info['thumbwidth'] = $fileinfo['video']['resolution_x'];
$info['thumbheight'] = $fileinfo['video']['resolution_y'];
// Type info
switch ($type)
{
case 'tv':
$info['name'] = $channame;
$channum = vdrgetchannum($channame);
list($date, $info['now_time'], $info['now_title'], $info['now_desc']) = vdrgetepgat($channum, "now");
list($date, $info['next_time'], $info['next_title'], $info['next_desc']) = vdrgetepgat($channum, "next");
break;
case 'rec':
$info['channel'] = $channame;
list($channame, $info['name'], $info['desc'], $info['recorded']) = vdrgetrecinfo($url);
break;
case 'vid':
$infovid = mediagetinfostream($url);
$info['name'] = basename($url);
$info['desc'] = $infovid['desc'];
$info['duration'] = $infovid['duration'];
$info['format'] = $infovid['format'];
$info['video'] = $infovid['video'];
$info['audio'] = $infovid['audio'];
$info['resolution'] = $infovid['resolution'];
break;
}
return $info;
}
function sessiondeletesingle($session)
{
addlog("Deleting session " .$session);
$ram = "../ram/" .$session ."/";
$cmd = "";
// First kill ffmpeg
if (is_pid_running($ram ."ffmpeg.pid"))
$cmd .= " kill `cat " .$ram ."ffmpeg.pid`; rm " .$ram ."ffmpeg.pid; ";
// Then kill segmenter
if (is_pid_running($ram ."segmenter.pid"))
$cmd .= " kill `cat " .$ram ."segmenter.pid`; rm " .$ram ."segmenter.pid; ";
addlog("Sending session kill command: " .$cmd);
$cmd .= "rm -rf " .$ram;
exec ($cmd);
}
function getstreamingstatus($session)
{
global $maxencodingprocesses, $httppath;
$status = array();
$path = '../ram/' .$session;
// Check that session exists
if (!count(glob($path)))
{
$status['status'] = "error";
$nbencprocess = exec("find ../ram/ -name segmenter.pid | wc | awk '{ print $1 }'");
if ($nbencprocess >= $maxencodingprocesses)
$status['message'] = "Error: too much sessions";
else
$status['message'] = "Error: could not create session folder";
}
else
{
// Get stream info
list($type, $mode, $url, $channame) = readinfostream($session);
if (count(glob($path . '/*.ts')) < 2)
{
if (!is_pid_running($path .'/ffmpeg.pid') || !is_pid_running($path .'/segmenter.pid'))
{
$status['status'] = "error";
$status['message'] = "Error: streaming could not start correclty";
}
else
{
$status['status'] = "wait";
switch ($type)
{
case 'tv':
$status['message'] = "Live: requesting " .$channame ."";
break;
case 'rec':
$status['message'] = "Rec: requesting " .$channame ."";
break;
case 'vid':
$status['message'] = "Vid: requesting " .$url ."";
break;
}
}
$status['message'] .= "
";
$status['message'] .= "
* FFmpeg: ";
if (is_pid_running($path .'/ffmpeg.pid'))
$status['message'] .= "running";
else
$status['message'] .= "stopped";
$status['message'] .= "
* Segmenter: ";
if (is_pid_running($path .'/segmenter.pid'))
{
$status['message'] .= "running (";
$status['message'] .= count(glob($path . '/*.ts')) ."/2)";
}
else
$status['message'] .= "stopped";
}
else
{
$status['status'] = "ready";
$status['message'] = "Broadcast ready
";
$status['message'] .= "
* Quality: " .$mode ."";
$status['message'] .= "
* Status: ";
if (is_pid_running($path .'/segmenter.pid'))
$status['message'] .= "encoding...";
else
$status['message'] .= "fully encoded";
$status['url'] = $httppath ."ram/" .$session ."/stream.m3u8";
}
}
return $status;
}
function sessiongetstatus($session, $prevmsg)
{
$time = time();
// Check if we need to timeout on the sesssion creation */
$checkstart = preg_match("/requesting/", $prevmsg);
while((time() - $time) < 29)
{
// Get current status
$status = getstreamingstatus($session);
// Alway return ready
if ($status['status'] == "ready")
{
addlog("Returning status: " .$status['message']);
return $status;
}
// Status change
if ($status['message'] != $prevmsg)
{
addlog("Returning status: " .$status['message']);
return $status;
}
// Check session creation timeout
if ($checkstart && ((time() - $time) >= 10))
{
$status['status'] = "error";
$status['message'] = "Error: session could not start";
$status['message'] .= "
";
$status['message'] .= "
* FFmpeg: ";
if (is_pid_running('../ram/' .$session .'/ffmpeg.pid'))
$status['message'] .= "running";
else
$status['message'] .= "stopped";
$status['message'] .= "
* Segmenter: ";
if (is_pid_running('../ram/' .$session .'/segmenter.pid'))
{
$status['message'] .= "running (";
$status['message'] .= count(glob('../ram/' .$session .'/*.ts')) ."/2)";
}
else
$status['message'] .= "stopped";
addlog("Returning status: " .$status['message']);
return $status;
}
usleep(10000);
}
/* Time out */
$status['status'] = "wait";
$status['message'] = $prevmsg;
addlog("Returning status: " .$status['message']);
return $status;
}
function sessiongetlist()
{
$sessions = array();
addlog("Listing sessions");
$dir_handle = @opendir('../ram/');
if ($dir_handle)
{
while ($session = readdir($dir_handle))
{
if($session == "." || $session == ".." || $session == 'lost+found')
continue;
if (!is_dir('../ram/' .$session))
continue;
// Get info
list($type, $mode, $url, $channame) = readinfostream($session);
if ($type == "none")
continue;
// Get status
$status = getstreamingstatus($session);
$newsession = array();
$newsession['session'] = substr($session, strlen("session"));
$newsession['type'] = $type;
if ($type == "vid")
$newsession['name'] = basename($url);
else
$newsession['name'] = $channame;
if ($status['status'] == "error")
$newsession['name'] = "Error: " .$newsession['name'];
// Check if encoding
if (is_pid_running('../ram/' .$session .'/segmenter.pid') && ($status['status'] != "error"))
$newsession['encoding'] = 1;
else
$newsession['encoding'] = 0;
$sessions[] = $newsession;
}
}
return $sessions;
}
function streammusic($path, $file)
{
global $httppath;
addlog("Streaming music from path \"" .$path ."\"");
if (!isurlvalid($path, "media"))
return array();
$files = array();
// Create all symlinks
exec('mkdir ../playlist');
exec('rm ../playlist/*');
exec('ln -s ' .addcslashes(quotemeta($path), " &'") .'/* ../playlist');
// Generate files
// Get listing
$filelisting = filesgetlisting($path);
$addfiles = 0;
foreach ($filelisting as $f)
{
if ($f['type'] != 'audio')
continue;
if ($f['name'] == $file)
$addfiles = 1;
if ($addfiles)
{
$newfile = array();
$newfile['file'] = $httppath ."playlist/" . $f['name'];
$files[] = $newfile;
}
}
return $files;
}
?>