From cd1d2e17218c84a1f03b251bbae938b55e5b5ee3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 22 Nov 2017 01:18:07 -0500 Subject: [PATCH] lots more debugging. re-add status update command on failure --- db/zm_create.sql.in | 6 ++- db/zm_update-1.31.11.sql | 1 + db/zm_update-1.31.13.sql | 26 +++++++++ scripts/zmaudit.pl.in | 2 +- src/zm_monitorstream.cpp | 11 ++-- src/zm_stream.cpp | 3 ++ web/includes/functions.php | 25 ++++----- web/skins/classic/js/skin.js | 2 +- web/skins/classic/views/_monitor_filters.php | 8 +-- web/skins/classic/views/console.php | 7 ++- web/skins/classic/views/js/montage.js | 55 +++++++++++++------- 11 files changed, 102 insertions(+), 44 deletions(-) create mode 100644 db/zm_update-1.31.13.sql diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 1ca81553f..91089ff2d 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -195,6 +195,7 @@ CREATE TABLE `Events` ( `Frames` int(10) unsigned default NULL, `AlarmFrames` int(10) unsigned default NULL, `DefaultVideo` VARCHAR( 64 ) DEFAULT '' NOT NULL, + `SaveJPEGs` TINYINT, `TotScore` int(10) unsigned NOT NULL default '0', `AvgScore` smallint(5) unsigned default '0', `MaxScore` smallint(5) unsigned default '0', @@ -384,6 +385,8 @@ CREATE TABLE `Monitors` ( `Deinterlacing` int(10) unsigned NOT NULL default '0', `SaveJPEGs` TINYINT NOT NULL DEFAULT '3' , `VideoWriter` TINYINT NOT NULL DEFAULT '0', + `OutputCodec` enum('h264','mjpeg','mpeg1','mpeg2'), + `OutputContainer` enum('auto','mp4','mkv'), `EncoderParameters` TEXT, `RecordAudio` TINYINT NOT NULL DEFAULT '0', `RTSPDescribe` tinyint(1) unsigned, @@ -606,13 +609,14 @@ CREATE TABLE `Storage` ( `Path` varchar(64) NOT NULL default '', `Name` varchar(64) NOT NULL default '', `Type` enum('local','s3fs') NOT NULL default 'local', + `DiskSpace` bigint unsigned default NULL, PRIMARY KEY (`Id`) ) ENGINE=@ZM_MYSQL_ENGINE@; -- -- Create a default storage location -- -insert into Storage VALUES (NULL, '/var/cache/zoneminder/events', 'Default', 'local' ); +insert into Storage VALUES (NULL, '/var/cache/zoneminder/events', 'Default', 'local', NULL ); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; diff --git a/db/zm_update-1.31.11.sql b/db/zm_update-1.31.11.sql index de17d85d9..e0772cef4 100644 --- a/db/zm_update-1.31.11.sql +++ b/db/zm_update-1.31.11.sql @@ -67,3 +67,4 @@ SET @s = (SELECT IF( PREPARE stmt FROM @s; EXECUTE stmt; + diff --git a/db/zm_update-1.31.13.sql b/db/zm_update-1.31.13.sql new file mode 100644 index 000000000..dd63b347a --- /dev/null +++ b/db/zm_update-1.31.13.sql @@ -0,0 +1,26 @@ +ALTER TABLE `Monitors` MODIFY `OutputCodec` enum('h264','mjpeg','mpeg1','mpeg2') default 'h264'; +ALTER TABLE `Monitors` MODIFY `OutputContainer` enum('auto','mp4','mkv') default 'auto'; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Events' + AND column_name = 'SaveJPEGs' + ) > 0, +"SELECT 'Column SaveJPEGs already exists in Events'", +"ALTER TABLE `Events` ADD `SaveJPEGs` TINYINT AFTER `DefaultVideo`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Storage' + AND column_name = 'DiskSpace' + ) > 0, +"SELECT 'Column DiskSpace already exists in Events'", +"ALTER TABLE `Storage` ADD `DiskSpace` bigint unsigned default NULL AFTER `Type`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index ae08e27a2..1593777b4 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -53,7 +53,7 @@ use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|) ? $Config{ZM_DIR_EVENTS} : ($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS}) ; -use constant ZM_AUDIT_PID => $Config{ZM_RUNDIR}.'/zm.pid' +use constant ZM_AUDIT_PID => '@ZM_RUNDIR@/zmaudit.pid'; $| = 1; diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index d33d84107..ed8009f84 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -579,7 +579,7 @@ void MonitorStream::runStream() { gettimeofday( &now, NULL ); if ( connkey ) { -//Debug(2, "checking command Queue for connkey: %d", connkey ); +Debug(2, "checking command Queue for connkey: %d", connkey ); while(checkCommandQueue()) { Debug(2, "Have checking command Queue for connkey: %d", connkey ); got_command = true; @@ -664,7 +664,7 @@ Debug(2, "Have checking command Queue for connkey: %d", connkey ); if ( last_read_index != monitor->shared_data->last_write_index ) { int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; // % shouldn't be neccessary last_read_index = monitor->shared_data->last_write_index; - //Debug( 1, "index: %d: frame_mod: %d frame count: %d", index, frame_mod, frame_count ); + Debug( 1, "index: %d: frame_mod: %d frame count: %d", index, frame_mod, frame_count ); if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) { if ( !paused && !delayed ) { // Send the next frame @@ -681,7 +681,8 @@ Debug(2, "Have checking command Queue for connkey: %d", connkey ); temp_read_index = temp_write_index; } - } + } // end if should send frame + if ( buffered_playback ) { if ( monitor->shared_data->valid ) { if ( monitor->image_buffer[index].timestamp->tv_sec ) { @@ -711,10 +712,12 @@ Debug(2, "Have checking command Queue for connkey: %d", connkey ); } } // end if buffered playback frame_count++; + } else { + Debug(2,"Waiting for capture"); } // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index ) unsigned long sleep_time = (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2))); - Debug(4, "Sleeping for (%d)", sleep_time); + Debug(2, "Sleeping for (%d)", sleep_time); usleep( sleep_time ); if ( ttl ) { if ( (now.tv_sec - stream_start_time) > ttl ) { diff --git a/src/zm_stream.cpp b/src/zm_stream.cpp index 70d06c026..87fbf07b2 100644 --- a/src/zm_stream.cpp +++ b/src/zm_stream.cpp @@ -75,6 +75,7 @@ void StreamBase::updateFrameRate( double fps ) { bool StreamBase::checkCommandQueue() { if ( sd >= 0 ) { + Debug(2, "sd is (%d)", sd ); CmdMsg msg; memset( &msg, 0, sizeof(msg) ); int nbytes = recvfrom( sd, &msg, sizeof(msg), MSG_DONTWAIT, 0, 0 ); @@ -92,6 +93,8 @@ Debug(2, "Message length is (%d)", nbytes ); processCommand( &msg ); return( true ); } + } else { + Error("sd is < 0"); } return( false ); } diff --git a/web/includes/functions.php b/web/includes/functions.php index e0c82b7d3..7bd3df7e9 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -28,13 +28,13 @@ if ( version_compare( phpversion(), '4.3.0', '<') ) { } # We are requiring these because this file is getting included from the api, which hasn't already included them. -require_once( 'logger.php' ); -require_once( 'database.php' ); +require_once('logger.php'); +require_once('database.php'); function userLogin( $username, $password='', $passwordHashed=false ) { global $user, $cookies; - $sql = 'SELECT * FROM Users WHERE Enabled = 1'; + $sql = 'SELECT * FROM Users WHERE Enabled=1'; $sql_values = NULL; if ( ZM_AUTH_TYPE == 'builtin' ) { if ( $passwordHashed ) { @@ -44,7 +44,7 @@ function userLogin( $username, $password='', $passwordHashed=false ) { } $sql_values = array( $username, $password ); } else { - $sql .= ' AND Username = ?'; + $sql .= ' AND Username=?'; $sql_values = array( $username ); } $_SESSION['username'] = $username; @@ -138,26 +138,27 @@ function getAuthUser( $auth ) { $authHash = md5( $authKey ); if ( $auth == $authHash ) { - return( $user ); + return $user; } } // end foreach hour } // end foreach user } // end if using auth hash Error( "Unable to authenticate user from auth hash '$auth'" ); return( false ); -} +} // end getAuthUser($auth) function generateAuthHash( $useRemoteAddr ) { if ( ZM_OPT_USE_AUTH and ZM_AUTH_RELAY == 'hashed' and isset($_SESSION['username']) and $_SESSION['passwordHash'] ) { # regenerate a hash at half the liftetime of a hash, an hour is 3600 so half is 1800 - if ( ( ! isset($_SESSION['AuthHash']) ) or ( $_SESSION['AuthHashGeneratedAt'] < time() - ( ZM_AUTH_HASH_TTL * 1800 ) ) ) { + $time = time(); + if ( ( ! isset($_SESSION['AuthHash']) ) or ( $_SESSION['AuthHashGeneratedAt'] < ( $time - ( ZM_AUTH_HASH_TTL * 1800 ) ) ) ) { # Don't both regenerating Auth Hash if an hour hasn't gone by yet - $time = localtime(); + $local_time = localtime(); $authKey = ''; if ( $useRemoteAddr ) { - $authKey = ZM_AUTH_HASH_SECRET.$_SESSION['username'].$_SESSION['passwordHash'].$_SESSION['remoteAddr'].$time[2].$time[3].$time[4].$time[5]; + $authKey = ZM_AUTH_HASH_SECRET.$_SESSION['username'].$_SESSION['passwordHash'].$_SESSION['remoteAddr'].$local_time[2].$local_time[3].$local_time[4].$local_time[5]; } else { - $authKey = ZM_AUTH_HASH_SECRET.$_SESSION['username'].$_SESSION['passwordHash'].$time[2].$time[3].$time[4].$time[5]; + $authKey = ZM_AUTH_HASH_SECRET.$_SESSION['username'].$_SESSION['passwordHash'].$local_time[2].$local_time[3].$local_time[4].$local_time[5]; } $auth = md5( $authKey ); if ( session_status() == PHP_SESSION_NONE ) { @@ -167,10 +168,10 @@ function generateAuthHash( $useRemoteAddr ) { Warning("Session is not active. AuthHash will not be cached. called from $file:$line"); } $_SESSION['AuthHash'] = $auth; - $_SESSION['AuthHashGeneratedAt'] = time(); + $_SESSION['AuthHashGeneratedAt'] = $time; Logger::Debug("Generated new auth $auth at " . $_SESSION['AuthHashGeneratedAt']. " using $authKey" ); } else { - Logger::Debug( "Using cached auth " . $_SESSION['AuthHash'] ); + Logger::Debug( "Using cached auth " . $_SESSION['AuthHash'] ." beacuse " . $_SESSION['AuthHashGeneratedAt'] . ' < '. $time . ' - ' . ZM_AUTH_HASH_TTL . ' * 1800 = '.( $time - (ZM_AUTH_HASH_TTL * 1800) )); } # end if AuthHash is not cached return $_SESSION['AuthHash']; } else { diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index 7f770b1cb..c3d225aa8 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -326,7 +326,7 @@ function changeGroup( e, depth ) { } function changeMonitor( e ) { var monitor_id = e.value; - Cookie.write( 'zmMonitorId', monitor_id, { duration: 10*365 } ); + Cookie.write( 'MonitorId', monitor_id, { duration: 10*365 } ); window.location = window.location; } function changeFilter( e ) { diff --git a/web/skins/classic/views/_monitor_filters.php b/web/skins/classic/views/_monitor_filters.php index c8607f845..b81634fd4 100644 --- a/web/skins/classic/views/_monitor_filters.php +++ b/web/skins/classic/views/_monitor_filters.php @@ -98,23 +98,23 @@ $groupSql = Group::get_group_sql( $group_id ); if ( $monitors[$i]['Id'] == $monitor_id ) { $found_selected_monitor = true; } - } + } // end foreach monitor if ( ! $found_selected_monitor ) { $monitor_id = ''; } - } + } // end if a monitor was specified + for ( $i = 0; $i < count($monitors); $i++ ) { if ( !visibleMonitor( $monitors[$i]['Id'] ) ) { continue; } - $monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name']; if ( $monitor_id and ( $monitors[$i]['Id'] != $monitor_id ) ) { continue; } $displayMonitors[] = $monitors[$i]; } - echo htmlSelect( 'MonitorId', $monitors_dropdown, $monitor_id, array('onchange'=>'changeMonitor(this);') ); + echo htmlSelect( 'MonitorId', $monitors_dropdown, $monitor_id, array('onchange'=>'changeFilter(this);') ); ?> - '.translate('Fn'.$monitor['Function']).( empty($monitor['Enabled']) ? ', disabled' : '' ) .'', canEdit( 'Monitors' ) ) ?> + + '.translate('Fn'.$monitor['Function']).( empty($monitor['Enabled']) ? ', disabled' : '' ) .'', canEdit( 'Monitors' ) ) ?>
+ + Name(); ?> @@ -267,7 +270,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { - + diff --git a/web/skins/classic/views/js/montage.js b/web/skins/classic/views/js/montage.js index 87e55c149..d77959b64 100644 --- a/web/skins/classic/views/js/montage.js +++ b/web/skins/classic/views/js/montage.js @@ -1,4 +1,4 @@ -var requestQueue = new Request.Queue( { concurrent: 2 } ); +var requestQueue = new Request.Queue( { concurrent: 2, stopOnFailure: false } ); function Monitor( monitorData ) { this.id = monitorData.id; @@ -29,6 +29,26 @@ function Monitor( monitorData ) { } }; + this.onError = function( text, error ) { + console.log('onerror: ' + text + ' error:'+error); + // Requeue, but want to wait a while. + var streamCmdTimeout = 1000*statusRefreshTimeout; + this.streamCmdTimer = this.streamCmdQuery.delay( streamCmdTimeout, this ); + }; + this.onFailure = function( xhr ) { + console.log('onFailure: ' + this.connKey); + console.log(xhr ); + requestQueue.addRequest( "cmdReq"+this.id, this.streamCmdReq ); + if ( 0 ) { + // Requeue, but want to wait a while. + if ( this.streamCmdTimer ) + this.streamCmdTimer = clearTimeout( this.streamCmdTimer ); + var streamCmdTimeout = 1000*statusRefreshTimeout; + this.streamCmdTimer = this.streamCmdQuery.delay( streamCmdTimeout, this, true ); + requestQueue.resume(); + } + }; + this.getStreamCmdResponse = function( respObj, respText ) { if ( this.streamCmdTimer ) this.streamCmdTimer = clearTimeout( this.streamCmdTimer ); @@ -110,21 +130,12 @@ function Monitor( monitorData ) { }; this.streamCmdQuery = function( resent ) { - if ( resent ) - console.log( this.connKey+": Resending" ); - //this.streamCmdReq.cancel(); + if ( resent ) { + console.log( this.connKey+": Resending" ); + this.streamCmdReq.cancel(); + } this.streamCmdReq.send( this.streamCmdParms+"&command="+CMD_QUERY ); }; - this.onError = function( text, error ) { - console.log('onerror: ' + text + ' error:'+error); - }; - this.onFailure = function( xhr ) { - console.log('onFailure: ' ); - console.log(xhr ); - // Requeue - var streamCmdTimeout = statusRefreshTimeout; - this.streamCmdTimer = this.streamCmdQuery.delay( streamCmdTimeout, this ); - }; this.streamCmdReq = new Request.JSON( { url: this.server_url, @@ -193,10 +204,11 @@ function selectLayout( element ) { if ( streamImg ) { if ( streamImg.nodeName == 'IMG' ) { var src = streamImg.src; - streamImg.src=''; src = src.replace(/width=[\.\d]+/i,'width=0' ); - src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) )); - streamImg.src = src; + if ( src != streamImg.src ) { + streamImg.src=''; + streamImg.src = src; + } } else if ( streamImg.nodeName == 'APPLET' || streamImg.nodeName == 'OBJECT' ) { // APPLET's and OBJECTS need to be re-initialized } @@ -363,12 +375,17 @@ function cancel_layout(button) { var monitors = new Array(); function initPage() { + for ( var i = 0; i < monitorData.length; i++ ) { monitors[i] = new Monitor(monitorData[i]); - var delay = Math.round( (Math.random()+0.75)*statusRefreshTimeout ); - monitors[i].start(delay); } selectLayout('#zmMontageLayout'); + + for ( var i = 0; i < monitorData.length; i++ ) { + var delay = Math.round( (Math.random()+0.75)*statusRefreshTimeout ); + console.log("Delay for monitor " + monitorData[i].id + " is " + delay ); + monitors[i].start(delay); + } } // Kick everything off window.addEvent( 'domready', initPage );