$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.""; //echo "<".$tag.">".$val."</".$tag.">
"; } function xml_tag_sec($tag, $open) { if ($open) $tok = "<"; else $tok = ""; } 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; ?>
Initializing H264 Stream ()...