$maj) return 1; if ((getClientVerMaj() == $maj) && (getClientVerMin() >= $min)) return 1; return 0; } function logXmlErr($str) { logXml($str, 1); } function logXml($str, $err = 0) { if (!defined("ZM_EYEZM_DEBUG")) { /* Check session variable */ if (isset($_SESSION['xml_debug'])) define("ZM_EYEZM_DEBUG", $_SESSION['xml_debug']); else define ("ZM_EYEZM_DEBUG", "0"); } if (!defined("ZM_EYEZM_LOG_TO_FILE")) { /* Check session variable */ if (isset($_SESSION['xml_log_to_file'])) define("ZM_EYEZM_LOG_TO_FILE", $_SESSION['xml_log_to_file']); else define ("ZM_EYEZM_LOG_TO_FILE", "1"); } if (!defined("ZM_EYEZM_LOG_FILE")) { /* Check session variable */ if (isset($_SESSION['xml_log_file'])) define("ZM_EYEZM_LOG_FILE", $_SESSION['xml_log_file']); else define ("ZM_EYEZM_LOG_FILE", "/tmp/zm_xml.log"); } /* Only log if debug is enabled */ if (ZM_EYEZM_DEBUG == 0) return; /* Logging is enabled, set log string */ $logstr = "XML_LOG (".($err?"ERROR":"NOTICE")."): ".$str.(ZM_EYEZM_LOG_TO_FILE?"\n":""); if (ZM_EYEZM_LOG_TO_FILE) { error_log("[".date("r")."] ".$logstr, 3, ZM_EYEZM_LOG_FILE); } else { error_log($logstr); } } /* 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.""; } function xml_tag_sec($tag, $open) { if ($open) $tok = "<"; else $tok = ""; } function xhtmlHeaders( $file, $title ) { ?> /dev/null")) > 0) { /* More than one match */ return TRUE; } else { /* Check -formats tag also if we fail -codecs */ if (preg_match("/\b".$codec."\b/", shell_exec(getFfmpegPath()." -formats 2> /dev/null")) > 0) return TRUE; return FALSE; } } function exeExists($exepath) { $path = trim($exepath); return (file_exists($path) && is_readable($path) && ($path != "")); } /* Returns whether ffmpeg exists or not */ function ffmpegExists() { return exeExists(getFfmpegPath()); } /* Returns with PHP-GD exists */ function gdExists() { if (extension_loaded('gd') && function_exists('gd_info')) { return TRUE; } return FALSE; } function getFfmpeg264FoutParms($br, $fout) { $ffparms = "-analyzeduration 0 -acodec copy"; $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 16k"; $ffparms .= " -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." 2> /dev/null"; return $ffparms; } /** Return FFMPEG parameters for H264 streaming */ function getFfmpeg264Str($width, $height, $br, $fin, $fout) { $ffparms = getFfmpeg264FoutParms($br, $fout); $ffstr = getFfmpegPath()." -t ".ZM_EYEZM_H264_MAX_DURATION." -analyzeduration 0 -i "; $ffstr .= $fin." -f mpegts ".$ffparms; return $ffstr; } /** Returns true when monitor exists */ function isMonitor($monitor) { $query = "select Id from Monitors where Id = ?"; $res = dbFetchOne($query, NULL, array($monitor)); if ($res) return TRUE; logXml("Monitor ID ".$monitor." does not exist"); return FALSE; } /** Returns the width and height of a monitor */ function getMonitorDims($monitor) { $query = "select Width,Height from Monitors where Id = ?"; $res = dbFetchOne($query, NULL, array( $monitor ) ); 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) { /** NOTE: This command executes an 'rm' command, so $monitor parameter * should be properly validated before executing */ /* Remove wdir/.m3u8 and wdir/sample_*.ts */ shell_exec("rm -f ".getTempDir()."/".m3u8fname($monitor)." ".getTempDir()."/sample_".$monitor."*.ts"); } function kill264proc($monitor) { /** NOTE: This command executes an 'kill' command, so $monitor parameter * should be properly validated before executing */ $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." 2> /dev/null"; $ffstr = getFfmpeg264Str($width, $height, $br, "-", "-"); $seg = "segmenter - ".ZM_EYEZM_SEG_DURATION." ".$cdir."/sample_".$mid." ".$cdir."/".m3u8fname($mid)." ../ 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, $thumbsrc) { function printTermLink() { $str = "H264 Streaming Launching...
Tap to re-load if stream fails"; $str2 = "document.getElementById(\"loaddiv\").innerHTML = \"".$str."\";"; echo $str2; } $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_EYEZM_H264_TIMEOUT; $ajax3Url = "./skins/xml/views/actions.php?action=kill264&monitor=".$monitor; ?>
Initializing H264 Stream ()...
This may take a few seconds