/web/skins/xml/includes/functions.php
PHP | 455 lines | 428 code | 3 blank | 24 comment | 30 complexity | cebd0cf37ef0e7355bc5f8bddb95c330 MD5 | raw file
Possible License(s): GPL-2.0
- <?php
- /*
- * functions.php is created by Jai Dhar, FPS-Tech, for use with eyeZm
- * iPhone application. This is not intended for use with any other applications,
- * although source-code is provided under GPL.
- *
- * For questions, please email support@eyezm.com (http://www.eyezm.com)
- *
- */
- /* These functions are taken from functions.php */
- function validInteger( $input )
- {
- return( preg_replace( '/\D/', '', $input ) );
- }
- function validString( $input )
- {
- return( strip_tags( $input ) );
- }
- /*
- * Escape an SQL string, with optional parameters for max. length
- */
- function escapeSql($str, $maxlen = 0) {
- if (!$maxlen) $maxlen = 512;
- $string = substr($str, 0, $maxlen);
- return (get_magic_quotes_gpc())?mysql_real_escape_string(stripslashes($string)):mysql_real_escape_string($string);
- }
- /* There appears to be some discrepancy btw. 1.24.1/2 and .3 for EventPaths, to escape them here */
- function getEventPathSafe($event)
- {
- if (ZM_USE_DEEP_STORAGE) {
- $ret = ZM_DIR_EVENTS."/".$event['MonitorId'].'/'.strftime( "%y/%m/%d/%H/%M/%S", strtotime($event['StartTime']) );
- } else {
- $ret = ZM_DIR_EVENTS."/".$event['MonitorId']."/".$event['Id'];
- }
- return $ret;
- }
- function updateClientVer()
- {
- $str = $_SERVER['HTTP_USER_AGENT'];
- /* Check if it starts with eyeZm */
- if (!strcmp(substr($str, 0, 5),"eyeZm")) {
- /* Found eyeZm */
- $ver = substr($str, 6);
- $verarray = explode(".", $ver);
- $_SESSION['vermaj']=$verarray[0];
- $_SESSION['vermin']=$verarray[1];
- $_SESSION['verbuild']=$verarray[2];
- }
- logXml("(".$_SERVER['REMOTE_ADDR'].") GET: ".$_SERVER['REQUEST_URI']." - eyeZm ".getClientVerMaj().".".getClientVerMin());
- }
- function getClientVerMaj()
- {
- if (isset($_SESSION['vermaj'])) return $_SESSION['vermaj'];
- return "0";
- }
- function getClientVerMin()
- {
- if (isset($_SESSION['vermin'])) return $_SESSION['vermin'];
- return "0";
- }
- function requireVer($maj, $min)
- {
- if (getClientVerMaj() > $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 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
- }
- function xml_tag_val($tag, $val)
- {
- echo "<".$tag.">".$val."</".$tag.">";
- }
- function xml_tag_sec($tag, $open)
- {
- if ($open) $tok = "<";
- else $tok = "</";
- echo $tok.$tag.">";
- }
- function xhtmlHeaders( $file, $title )
- {
- ?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <style type="text/css">
- body {
- border: 0px solid;
- margin: 0px;
- padding: 0px;
- }
- </style>
- <script type="text/javascript">
- </script>
- </head>
- <?php
- }
- /** Returns whether necessary components for H264 streaming
- * are present */
- function canStream264($sup = 0) {
- if (!ffmpegSupportsCodec("libx264")) {
- if (!$sup) logXmlErr("FFMPEG not installed, accessible in path/ZM_PATH_FFMPEG, or doesn't support libx264");
- return FALSE;
- }
- /* Make sure segmenter exists */
- if (!exeExists(shell_exec("which segmenter"))) {
- if (!$sup) logXmlErr("HTTP segmenter not installed or not accessible in path");
- return FALSE;
- }
- /* Check for zmstreamer */
- if (!exeExists(shell_exec("which zmstreamer"))) {
- if (!$sup) logXmlErr("ZMSTREAMER not installed or not accessible in path");
- return FALSE;
- }
- return TRUE;
- }
- /* Returns the path of ffmpeg by using define */
- function getFfmpegPath()
- {
- if (defined("ZM_PATH_FFMPEG")) {
- return ZM_PATH_FFMPEG;
- } else {
- /* Not defined, get it from using 'which' */
- return shell_exec("which ffmpeg");
- }
- }
- /* Returns whether ffmpeg supports a given codec. Takes into account
- * whether FFMPEG exists or not */
- function ffmpegSupportsCodec($codec)
- {
- if (!ffmpegExists()) return FALSE;
- /* FFMPEG exists */
- if (preg_match("/\b".$codec."\b/", shell_exec(getFfmpegPath()." -codecs 2> /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 = ".$monitor;
- $res = dbFetchOne(escapeSql($query));
- 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 = ".$monitor;
- $res = dbFetchOne(escapeSql($query));
- return $res;
- }
- /** Returns the temp directory for H264 encoding */
- function getTempDir()
- {
- /* Assume that the directory structure is <base>/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_<mon>*.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...<br>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;
- ?>
- <html>
- <head>
- <script type="text/javascript">
- /* Called when paused or done is pressed */
- function vidAbort() {
- document.getElementById('viddiv').style.display = 'none';
- var pElement = document.getElementsByTagName('video')[0];
- var ajaxKill = new AjaxConnection("<?php echo $ajax3Url;?>");
- ajaxKill.connect("cbKilled");
- pElement.stop();
- pElement.src="";
-
- }
- function reloadStreamImage() {
- var obj = document.getElementById('liveStream');
- var src = obj.src;
- var date = new Date();
- obj.src = src + '&vrand=' + date.getTime();
- return false;
- }
- /* Callback when spawn264 process is ended */
- function cbVidLoad()
- {
- reloadStreamImage();
- <?php
- printTermLink();
- ?>
- }
- function vidLoaded() {
- window.setTimeout("startVid()", 500);
- }
- function bindListeners()
- {
- var pElement = document.getElementsByTagName('video')[0];
- /* Bind abort */
- pElement.addEventListener('abort', vidAbort, false);
- pElement.addEventListener('done', vidAbort, false);
- pElement.addEventListener('ended', vidAbort, false);
- pElement.addEventListener('pause', vidAbort, false);
- pElement.addEventListener('loadstart', vidLoaded, false);
- }
- /* Callback when kill264 process is ended */
- function cbKilled()
- {
- <?php printTermLink(); ?>
- }
- /* Called after an interval from cbFileExists() */
- function loadVid()
- {
- var pElement = document.getElementById("vidcontainer");
- <?php
- echo "pElement.src=\"./temp/".m3u8fname($monitor)."\"\n";
- ?>
- pElement.load();
- }
- function startVid()
- {
- document.getElementById('viddiv').style.display = 'block';
- var pElement = document.getElementById("vidcontainer");
- pElement.play();
- }
- /* Callback when stream is active and ready to be played */
- function cbFileExists()
- {
- window.setTimeout("loadVid()", 500);
- }
- /* On-load triggers two requests immediately: spawn264 and chk264 */
- window.onload = function() {
- bindListeners();
- var ajax1 = new AjaxConnection("<?php echo "$ajaxUrl";?>");
- var ajax2 = new AjaxConnection("<?php echo "$ajax2Url";?>");
- ajax1.connect("cbVidLoad");
- /* Don't initiate file-exists since eyeZm will */
- /*ajax2.connect("cbFileExists");*/
- }
- function AjaxConnection(url) {
- this.connect = connect;
- this.url = url;
- }
- function connect(return_func) {
- this.x = new XMLHttpRequest();
- this.x.open("GET", this.url, true);
- var self = this;
- this.x.onreadystatechange = function() {
- if (self.x.readyState != 4)
- return;
- eval(return_func + '()');
- delete self.x;
- }
- this.x.send(null);
- }
- </script>
- <style type="text/css">
- body {
- border: 0px solid;
- margin: 0px;
- padding: 0px;
- background-color: black;
- width: <?php echo $width ?>px;
- height: <?php echo $height ?>px;
- }
- .textcl {
- text-align: center;
- font-family: Arial;
- font-size: larger;
- width: 100%;
- <?php echo "padding-top: ".(($height/2)-100)."px;"; ?>
- <?php echo "padding-bottom: ".(($height/2)-100)."px;"; ?>
- z-index: 2;
- position: absolute;
- top: 0px;
- left: 0px;
- height: 100%;
- }
- .textcl2 {
- width: auto;
- height: auto;
- background-color: black;
- padding: 5px 5px;
- margin-left: 10px;
- margin-right: 10px;
- opacity: 0.7;
- }
- .textcl3 {
- width: auto;
- height: auto;
- padding: 2px 2px;
- margin: auto;
- color: white;
- }
- .imgdiv {
- position: absolute;
- padding: 0px;
- background-color: black;
- top: 0px;
- left: 0px;
- margin: 0px;
- width: <?php echo $width ?>px;
- height: <?php echo $height ?>px;
- z-index: 1;
- opacity: 0.7;
- }
- </style>
- </head>
- <body>
- <div id="viddiv" style="display: none;">
- <?php
- echo "<video id=\"vidcontainer\" width='".$width."' height='".$height."' />\n";
- ?>
- </div>
- <div id="loaddiv2" class="textcl"><div id="loaddiv3" class="textcl2">
- <div id="loaddiv" class="textcl3">
- Initializing H264 Stream (<?php echo($br); ?>)...<br>
- <span style="font-size: small;"><i>This may take a few seconds</i></span>
- </div>
- </div></div>
- <div class="imgdiv" id="imagediv">
- <?php outputImageStream("liveStream", $thumbsrc, $width, $height, "stream"); ?>
- </div>
- </body>
- </html>
- <?php
- }
- ?>