$maj) return 1;
if ((getClientVerMaj() == $maj) && (getClientVerMin() >= $min)) return 1;
return 0;
}
function logXml($str)
{
if (!defined("ZM_XML_DEBUG")) define ( "ZM_XML_DEBUG", "0" );
if (ZM_XML_DEBUG == 1) trigger_error("XML_LOG: ".$str, E_USER_NOTICE);
}
/* Returns defval if varname is not set, otherwise return varname */
function getset($varname, $defval)
{
if (isset($_GET[$varname])) return $_GET[$varname];
return $defval;
}
function xml_header()
{
header ("content-type: text/xml");
echo "";
}
function xml_tag_val($tag, $val)
{
echo "<".$tag.">".$val."".$tag.">";
//echo "<".$tag.">".$val."</".$tag.">
";
}
function xml_tag_sec($tag, $open)
{
if ($open) $tok = "<";
else $tok = "";
echo $tok.$tag.">";
}
function xhtmlHeaders( $file, $title )
{
?>
/dev/null | grep libx264");
if ($res == "") {
logXml("FFMPEG doesn't support libx264");
return 0;
}
logXml("Determined can stream for H264");
return 1;
}
/** Return FFMPEG parameters for H264 encoding */
function getFfmpeg264Str($width, $height, $br, $fin, $fout)
{
$ffparms = "-f mpegts -analyzeduration 0 -acodec copy -s 320x240";
$ffparms .= " -vcodec libx264 -b ".$br;
$ffparms .= " -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8";
$ffparms .= " -subq 5 -trellis 1 -refs 1 -coder 0 -me_range 16 -keyint_min 25";
$ffparms .= " -sc_threshold 40 -i_qfactor 0.71 -bt 200k -maxrate ";
$ffparms .= $br." -bufsize ".$br." -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6";
$ffparms .= " -qmin 10 -qmax 51 -qdiff 4 -level 30";
$ffparms .= " -g 30 -analyzeduration 0 -async 2 ".$fout.(ZM_XML_DEBUG?"":" 2> /dev/null");
$ffstr = "ffmpeg -t ".ZM_XML_H264_MAX_DURATION." -analyzeduration 0 -i ";
$ffstr .= $fin." ".$ffparms;
return $ffstr;
}
/** Returns the width and height of a monitor */
function getMonitorDims($monitor)
{
$query = "select Width,Height from Monitors where Id = ".$monitor;
$res = dbFetchOne($query);
return $res;
}
/** Returns the temp directory for H264 encoding */
function getTempDir()
{
/* Assume that the directory structure is /skins/xml/views */
return dirname(__FILE__)."/../../../temp";
}
/** Returns the name of the m3u8 playlist based on monitor */
function m3u8fname($monitor) {
return "stream_".$monitor.".m3u8";
}
/** Erases the M3u8 and TS file names for a given monitor */
function eraseH264Files($monitor) {
/* Remove wdir/.m3u8 and wdir/sample_*.ts */
shell_exec("rm -f ".getTempDir()."/".m3u8fname($monitor)." ".getTempDir()."/sample_".$monitor."*.ts");
}
function kill264proc($monitor) {
$pid = trim(shell_exec("pgrep -f -x \"zmstreamer -m ".$monitor."\""));
if ($pid == "") {
logXml("No PID found for ZMStreamer to kill");
} else {
shell_exec("kill -9 ".$pid);
logXml("Killed process ".$pid." for Monitor ".$monitor);
}
}
/** Return the command-line shell function to setup H264 stream */
function stream264fn ($mid, $width, $height, $br) {
$cdir = "./temp";
$zmstrm = "zmstreamer -m ".$mid.(ZM_XML_DEBUG?"":" 2> /dev/null");
$ffstr = getFfmpeg264Str($width, $height, $br, "-", "-");
$seg = "segmenter - ".ZM_XML_SEG_DURATION." ".$cdir."/sample_".$mid." ".$cdir."/".m3u8fname($mid)." ../".(ZM_XML_DEBUG?"":" 2> /dev/null");
$url = $zmstrm . " | ".$ffstr." | " . $seg;
return "nohup ".$url." & echo $!";
}
/** Generate the web-page presented to the viewer when using H264 */
function h264vidHtml($width, $height, $monitor, $br) {
$ajaxUrl = "?view=actions&action=spawn264&&monitor=".$monitor."&br=".$br;
/* Call these two directly to bypass server blocking issues */
$ajax2Url = "./skins/xml/views/actions.php?action=chk264&monitor=".$monitor;
$ajax2Url .= "&timeout=".ZM_XML_H264_TIMEOUT;
$ajax3Url = "./skins/xml/views/actions.php?action=kill264&monitor=".$monitor;
?>
\n";
?>
Initializing H264 Stream ()...