summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPliable Pixels <pliablepixels@gmail.com>2020-01-29 11:19:22 -0500
committerPliable Pixels <pliablepixels@gmail.com>2020-01-29 11:19:22 -0500
commit148560ba1fbcbe7fb951b540eb749f9ee067808f (patch)
tree0267379eda0f51fa888d2dedfa1bab52e4f929dd
parentc50b6a6bd8eded731afacb880e48defca747e566 (diff)
#894 implement monitor query status and recover
-rw-r--r--config.xml2
-rw-r--r--package.json4
-rw-r--r--www/js/MonitorModalCtrl.js80
-rw-r--r--www/js/MontageCtrl.js102
-rw-r--r--www/js/NVR.js2
-rwxr-xr-xwww/js/app.js8
-rw-r--r--www/templates/monitors-modal.html6
-rw-r--r--www/templates/montage.html1
8 files changed, 194 insertions, 11 deletions
diff --git a/config.xml b/config.xml
index 89d55cdd..96c01f21 100644
--- a/config.xml
+++ b/config.xml
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
-<widget android-packageName="com.pliablepixels.zmninja_pro" id="com.pliablepixels.zmninja_pro" ios-CFBundleIdentifier="com.pliablepixels.zmninja-pro" version="1.3.087" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+<widget android-packageName="com.pliablepixels.zmninja_pro" id="com.pliablepixels.zmninja_pro" ios-CFBundleIdentifier="com.pliablepixels.zmninja-pro" version="1.3.088" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>zmNinja</name>
<description>
High performance ZoneMinder client
diff --git a/package.json b/package.json
index 7516ba6e..3dea9938 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "zmninjapro",
"description": "Home security mobile app for ZoneMinder",
- "version":"1.3.087",
+ "version": "1.3.087",
"displayName": "zmNinja",
"author": "Pliable Pixels",
"license": "custom see LICENSE.md",
@@ -213,4 +213,4 @@
]
}
}
-}
+} \ No newline at end of file
diff --git a/www/js/MonitorModalCtrl.js b/www/js/MonitorModalCtrl.js
index 732f02b0..2d4d3bca 100644
--- a/www/js/MonitorModalCtrl.js
+++ b/www/js/MonitorModalCtrl.js
@@ -11,6 +11,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
$scope.isModalActive = true;
var intervalModalHandle;
var cycleHandle;
+ var intervalStreamQueryHandle;
var ld = NVR.getLogin();
$scope.svgReady = false;
$scope.zoneArray = [];
@@ -20,7 +21,8 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
var targetID = "";
$scope.imageZoomable = true;
$scope.ptzButtonsShown = true;
-
+ var streamQueryTimer = zm.streamQueryTimer;
+
var streamState = {
SNAPSHOT: 1,
@@ -34,8 +36,8 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
// incase imageload is never called
$timeout (function () {
- if (currentStreamState != streamState.SNAPSHOT) {
- currentStreamState = streamState.SNAPSHOT;
+ if (currentStreamState != streamState.ACTIVE) {
+ currentStreamState = streamState.ACTIVE;
NVR.debug ('Forcing stream to regular quality, imageLoaded() was never called');
}
@@ -51,9 +53,13 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
NVR.debug("MonitorModalCtrl called from " + $ionicHistory.currentStateName());
+ streamQueryTimer = (NVR.getBandwidth() == 'lowbw') ? zm.streamQueryStatusTimeLowBW: zm.streamQueryStatusTime;
+ NVR.debug ('Setting streamQuery timer to '+streamQueryTimer);
+
$interval.cancel(intervalModalHandle);
$interval.cancel(cycleHandle);
+ $interval.cancel(intervalStreamQueryHandle);
intervalModalHandle = $interval(function () {
loadModalNotifications();
@@ -61,6 +67,12 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
}.bind(this), zm.alarmStatusTime);
+ intervalStreamQueryHandle = $interval(function () {
+ loadStreamQuery();
+ // console.log ("Refreshing Image...");
+ }.bind(this), streamQueryTimer);
+
+
if ($rootScope.platformOS == 'desktop') {
@@ -370,6 +382,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
function onPause() {
NVR.debug("ModalCtrl: onpause called");
$interval.cancel(intervalModalHandle);
+ $interval.cancel(intervalStreamQueryHandle);
$interval.cancel(cycleHandle);
NVR.debug("Killing single stream...");
@@ -391,6 +404,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
NVR.log("ModalCtrl: Restarting Modal timer on resume");
$interval.cancel(intervalModalHandle);
+ $interval.cancel(intervalStreamQueryHandle);
$interval.cancel(cycleHandle);
var ld = NVR.getLogin();
@@ -399,6 +413,11 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
loadModalNotifications();
}.bind(this), zm.alarmStatusTime);
+ intervalStreamQueryHandle = $interval(function () {
+ loadStreamQuery();
+ // console.log ("Refreshing Image...");
+ }.bind(this), streamQueryTimer);
+
if (ld.cycleMonitors) {
NVR.debug("Cycling enabled at " + ld.cycleMonitorsInterval);
@@ -552,7 +571,12 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
$scope.isZoneEdit = false;
};
+ $scope.imageError = function() {
+ console.log ("*** IMAGE LOAD ERROR ");
+ };
+
$scope.imageLoaded = function () {
+ console.log ("**** SINGLE IMAGE LOADED");
imageLoaded();
};
@@ -690,7 +714,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
// this is a good time to calculate scaled zone points
function imageLoaded() {
- currentStreamState = streamState.SNAPSHOT;
+ currentStreamState = streamState.ACTIVE;
if ($scope.animationInProgress) return;
/*
@@ -1349,6 +1373,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
$scope.isModalActive = false;
$interval.cancel(intervalModalHandle);
$interval.cancel(cycleHandle);
+ $interval.cancel(intervalStreamQueryHandle);
});
$scope.$on('$ionicView.beforeLeave', function () {
@@ -1367,6 +1392,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
$scope.isModalActive = false;
$interval.cancel(intervalModalHandle);
+ $interval.cancel(intervalStreamQueryHandle);
$interval.cance(cycleHandle);
});
@@ -1403,6 +1429,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
//console.log("**MODAL REMOVED: Stopping modal timer");
$interval.cancel(intervalModalHandle);
+ $interval.cancel(intervalStreamQueryHandle);
$interval.cancel(cycleHandle);
// NVR.debug("Modal removed - killing connkey");
@@ -1411,6 +1438,51 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
// Execute action
});
+ function loadStreamQuery() {
+
+ function appendConnKey(ck) {
+ return "&connkey=" + ck;
+ }
+
+ function checkValidConnkey(query,i) {
+ $http.get(query)
+ .then (function (succ) {
+
+ //console.log ("SUCCESS="+JSON.stringify(succ.data));
+
+ if (succ.data && succ.data.result && succ.data.result == "Error") {
+
+ NVR.log ("Single view: regenerating Connkey as Failed:"+query);
+ $scope.connKey = (Math.floor((Math.random() * 999999) + 1)).toString();
+ $scope.isStreamGood = 'bad';
+
+
+ }
+ else if (succ.data && succ.data.result && succ.data.result == "Ok") {
+ $scope.isStreamGood = 'good';
+ }
+
+ },
+ function (err) {
+ NVR.log ("Single View: Stream Query ERR="+JSON.stringify(err));
+ });
+
+ }
+
+ //console.log (currentStreamState);
+ if (currentStreamState != streamState.ACTIVE) return;
+
+ NVR.debug ('Single view: stream status check');
+
+ var ld = NVR.getLogin();
+ var query;
+ query = ld.url+'/index.php?view=request&request=stream&command=99';
+ query= query + $rootScope.authSession;
+ query+= appendConnKey($scope.connKey);
+ checkValidConnkey(query,i);
+
+ }
+
//-------------------------------------------------------------
// called to kill connkey, not sure if we really need it
// I think we are calling window.stop() which is a hammer
diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js
index 6841bb1c..4fba4ea0 100644
--- a/www/js/MontageCtrl.js
+++ b/www/js/MontageCtrl.js
@@ -17,6 +17,7 @@ angular.module('zmApp.controllers')
var intervalHandleMontageCycle;
var intervalHandleReloadPage;
var intervalHandleEventStatus;
+ var intervalHandleStreamQuery;
var gridcontainer;
@@ -33,6 +34,7 @@ angular.module('zmApp.controllers')
var randToAvoidCacheMem;
var beforeReorderPositions=[];
+ var streamQueryTimer;
var streamState = {
SNAPSHOT: 1,
@@ -79,11 +81,22 @@ angular.module('zmApp.controllers')
NVR.displayBanner('net', [ds]);
var ld = NVR.getLogin();
refreshSec = (NVR.getBandwidth() == 'lowbw') ? ld.refreshSecLowBW : ld.refreshSec;
+ streamQueryTimer = (NVR.getBandwidth() == 'lowbw') ? zm.streamQueryStatusTimeLowBW: zm.streamQueryStatusTime;
+
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleReloadPage);
+ $interval.cancel(intervalHandleStreamQuery);
+ if (simulStreaming){
+
+ intervalHandleStreamQuery = $interval(function () {
+ loadStreamQueryStatus();
+ // console.log ("Refreshing Image...");
+ }.bind(this), streamQueryTimer);
+
+ }
intervalHandleMontage = $interval(function () {
loadNotifications();
@@ -1020,6 +1033,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleStreamQuery);
$interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
@@ -1077,6 +1091,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage); //we will renew on reload
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleStreamQuery);
$interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
@@ -1271,8 +1286,7 @@ angular.module('zmApp.controllers')
$scope.openModal = function (mid, controllable, controlid, connKey, monitor) {
- currentStreamState = streamState.PAUSED;
- $scope.isModalStreamPaused = true; // we stop montage and start modal stream in snapshot first
+
$timeout(function () { // after render
@@ -1280,6 +1294,8 @@ angular.module('zmApp.controllers')
var ld = NVR.getLogin();
if (ld.pauseStreams) {
+ currentStreamState = streamState.PAUSED;
+ $scope.isModalStreamPaused = true; // we stop montage and start modal stream in snapshot first
NVR.debug("Pausing all streams in montage to save memory/nw...");
for (var i = 0; i < $scope.MontageMonitors.length; i++) {
if ($scope.MontageMonitors[i].Monitor.listDisplay == 'show') NVR.pauseLiveStream($scope.MontageMonitors[i].Monitor.connKey, $scope.MontageMonitors[i].Monitor.controlURL, $scope.MontageMonitors[i].Monitor.Name);
@@ -1315,6 +1331,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleStreamQuery);
$interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
@@ -1380,6 +1397,9 @@ angular.module('zmApp.controllers')
if (simulStreaming){
randEachTime();
NVR.debug ('rand each time:'+randToAvoidCacheMem);
+
+
+
}
NVR.log("Restarting montage timers...");
@@ -1387,6 +1407,7 @@ angular.module('zmApp.controllers')
// console.log ("closeModal: Cancelling timer");
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleStreamQuery);
$interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleReloadPage);
@@ -1402,6 +1423,15 @@ angular.module('zmApp.controllers')
// console.log ("Refreshing Image...");
}.bind(this), zm.alarmStatusTime);
+ if (simulStreaming){
+
+ intervalHandleStreamQuery = $interval(function () {
+ loadStreamQueryStatus();
+ //console.log ("Restarting Query Timer...");
+ }.bind(this), streamQueryTimer);
+
+ }
+
loadEventStatus(ld.showMontageSidebars);
intervalHandleEventStatus = $interval(function () {
loadEventStatus();
@@ -1435,6 +1465,7 @@ angular.module('zmApp.controllers')
for (var i = 0; i < $scope.MontageMonitors.length; i++) {
if ($scope.MontageMonitors[i].Monitor.listDisplay == 'show') NVR.resumeLiveStream($scope.MontageMonitors[i].Monitor.connKey, $scope.MontageMonitors[i].Monitor.controlURL, $scope.MontageMonitors[i].Monitor.Name);
}
+ currentStreamState = streamState.ACTIVE;
} else {
NVR.debug ("Not resuming streams as pauseStreams is off");
}
@@ -1488,6 +1519,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleStreamQuery);
$interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
if (pckry) pckry.destroy();
@@ -1971,6 +2003,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleStreamQuery);
$interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
@@ -2050,6 +2083,58 @@ angular.module('zmApp.controllers')
};
+ function loadStreamQueryStatus () {
+
+ function checkValidConnkey(query,i) {
+ $http.get(query)
+ .then (function (succ) {
+
+ //console.log ("SUCCESS="+JSON.stringify(succ.data));
+
+ if (succ.data && succ.data.result && succ.data.result == "Error") {
+
+ $scope.MontageMonitors[i].Monitor.isStreamGood = 'bad';
+ NVR.log ("Montage View: Regenerating Connkey as Failed:"+query);
+ $scope.MontageMonitors[i].Monitor.connKey = (Math.floor((Math.random() * 999999) + 1)).toString();
+
+
+ }
+ else if (succ.data && succ.data.result && succ.data.result == "Ok"){
+ $scope.MontageMonitors[i].Monitor.isStreamGood = 'good';
+ }
+
+ },
+ function (err) {
+ NVR.log ("Stream Query ERR="+JSON.stringify(err));
+ });
+
+ }
+ //console.log ("MONTAGE: "+currentStreamState);
+ if (currentStreamState != streamState.ACTIVE || !simulStreaming) return;
+
+ NVR.debug ('Montage View: Stream Status check');
+ var ld = NVR.getLogin();
+
+ var query;
+ for (var i = 0; i < $scope.MontageMonitors.length; i++) {
+ if (($scope.MontageMonitors[i].Monitor.Function == 'None') ||
+ ($scope.MontageMonitors[i].Monitor.Enabled == '0') ||
+ ($scope.MontageMonitors[i].Monitor.listDisplay == 'noshow')) {
+ continue;
+ }
+ query = ld.url+'/index.php?view=request&request=stream&command=99';
+ query= query + $rootScope.authSession;
+ query+= appendConnKey($scope.MontageMonitors[i].Monitor.connKey);
+ //if (query) query += NVR.insertSpecialTokens();
+ //console.log ("QUERY="+query);
+ checkValidConnkey(query,i);
+
+
+
+ }
+
+ }
+
$scope.constructStream = function (monitor) {
var stream;
@@ -2191,6 +2276,9 @@ angular.module('zmApp.controllers')
//avoid bogus scale error
$scope.LoginData = NVR.getLogin();
+ streamQueryTimer = (NVR.getBandwidth() == 'lowbw') ? zm.streamQueryStatusTimeLowBW: zm.streamQueryStatusTime;
+ NVR.debug ('Setting streamQuery timer to '+streamQueryTimer);
+
$scope.toggleTimeType = function () {
if (NVR.isTzSupported()) {
if ($scope.iconTimeNow == 'server') {
@@ -2260,6 +2348,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleStreamQuery);
$interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
@@ -2280,6 +2369,15 @@ angular.module('zmApp.controllers')
// console.log ("Refreshing Image...");
}.bind(this), zm.alarmStatusTime);
+ if (simulStreaming){
+
+ intervalHandleStreamQuery = $interval(function () {
+ loadStreamQueryStatus();
+ // console.log ("Refreshing Image...");
+ }.bind(this), streamQueryTimer);
+
+ }
+
loadEventStatus(ld.showMontageSidebars);
intervalHandleEventStatus = $interval(function () {
loadEventStatus();
diff --git a/www/js/NVR.js b/www/js/NVR.js
index 8b2d17c0..67710aac 100644
--- a/www/js/NVR.js
+++ b/www/js/NVR.js
@@ -1623,7 +1623,7 @@ angular.module('zmApp.controllers')
loginData.canSwipeMonitors = true;
loginData.forceImageModePath = false;
loginData.enableBlog = true;
- loginData.pauseStreams = false;
+ loginData.pauseStreams = true;
}
diff --git a/www/js/app.js b/www/js/app.js
index 966c1875..2f2746ec 100755
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -99,6 +99,8 @@ angular.module('zmApp', [
//forceMontageReloadDelay: 10000, // testing 10s
thumbWidth: 200,
alarmStatusTime: 10000, // 10 sec
+ streamQueryStatusTime: 10000, //10 sec
+ streamQueryStatusTimeLowBW: 30000, // 30 sec
eventCheckTime: 30000, // 30 seconds
eventServerErrorDelay: 5000, // time to wait till I report initial connect errors
zmVersionCheckNag: 60 * 24, // in hrs
@@ -581,6 +583,12 @@ angular.module('zmApp', [
if ($attributes.imageSpinnerLoader) {
//console.log ("DIRECTIVE: IMAGE LOADED");
loader.remove();
+
+ if ($attributes.imageonload) {
+ console.log (">>>> IMAGE LOADED CBK");
+ $scope.$apply($attributes.imageonload);
+ // fn($scope, {});
+ }
//imageLoadingDataShare.set(0);
//console.log ("rendered");
diff --git a/www/templates/monitors-modal.html b/www/templates/monitors-modal.html
index 68b0beef..88d29574 100644
--- a/www/templates/monitors-modal.html
+++ b/www/templates/monitors-modal.html
@@ -13,12 +13,15 @@
<div ng-if="!animationInProgress">
<!--<span style="color:white">{{currentStreamMode}}</span>-->
+
+
<img id="singlemonitor" style="width:100vw; height:100vh;" image-spinner-loader="lines"
image-spinner-src="{{constructSingleStream()}}" ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}"
on-swipe-left="onSwipe(monitorId,1)" on-swipe-right="onSwipe(monitorId,-1)" on-double-tap="closeModal();"
on-tap="showHideControls();"
- imageonload="imageLoaded()" />
+ imageonload="imageLoaded();" />
+
</div>
<div ng-if="animationInProgress">
<img style="width:100vw; height:100vh" ng-src="img/noimage.png" class="object-fit_contain" />
@@ -140,6 +143,7 @@
</ul>
</div>
<div ng-if="!showPTZ && displayControls" class="monitor-modal-text">{{monitorName}} &nbsp;
+ <i ng-if="isStreamGood=='bad'" class="animated infinite flash ion-alert-circled assertive"></i>
<span ng-style="{'background-color':stateColor()}">&nbsp;{{monStatus}}&nbsp;</span>
</div>
</div>
diff --git a/www/templates/montage.html b/www/templates/montage.html
index b2dbd13b..02e4fd30 100644
--- a/www/templates/montage.html
+++ b/www/templates/montage.html
@@ -159,6 +159,7 @@
<span ng-if="monitor.Monitor.isStamp && isDragabillyOn">
<i class="animated infinite flash ion-pin"></i>&nbsp;</span>
+ <i ng-if="monitor.Monitor.isStreamGood=='bad'" class="animated infinite flash ion-alert-circled assertive"></i>
<i class="ion-ios-videocam"></i>&nbsp; {{monitor.Monitor.Name}}&nbsp;
</figcaption>