From aa157bfd78c0704bf9c11b419cff44bc1f5c9317 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 11 Oct 2020 09:56:35 -0400 Subject: [PATCH 001/174] AddManufacturerId and ModelId to Monitors --- db/manufacturers.sql | 24 ++++++++++++++++++++ db/zm_create.sql.in | 2 ++ db/zm_update-1.35.10.sql | 47 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 db/manufacturers.sql create mode 100644 db/zm_update-1.35.10.sql diff --git a/db/manufacturers.sql b/db/manufacturers.sql new file mode 100644 index 000000000..be15f9c01 --- /dev/null +++ b/db/manufacturers.sql @@ -0,0 +1,24 @@ +INSERT INTO Manufacturers VALUES (1, 'Acti'); +INSERT INTO Manufacturers VALUES (2, 'Amcrest'); +INSERT INTO Manufacturers VALUES (3, 'Airlink101'); +INSERT INTO Manufacturers VALUES (4, 'Arecont Vision'); +INSERT INTO Manufacturers VALUES (5, 'Axis'); +INSERT INTO Manufacturers VALUES (6, 'Dahua'); +INSERT INTO Manufacturers VALUES (7, 'D-Link'); +INSERT INTO Manufacturers VALUES (8, 'Edimax'); +INSERT INTO Manufacturers VALUES (9, 'Foscam'); +INSERT INTO Manufacturers VALUES (10, 'Gadspot'); +INSERT INTO Manufacturers VALUES (11, 'GrandStream'); +INSERT INTO Manufacturers VALUES (12, 'HikVision'); +INSERT INTO Manufacturers VALUES (13, 'JVC'); +INSERT INTO Manufacturers VALUES (14, 'Maginon'); +INSERT INTO Manufacturers VALUES (15, 'Mobotix'); +INSERT INTO Manufacturers VALUES (16, 'Oncam Grandeye'); +INSERT INTO Manufacturers VALUES (17, 'Panasonic'); +INSERT INTO Manufacturers VALUES (18, 'Pelco'); +INSERT INTO Manufacturers VALUES (19, 'Sony'); +INSERT INTO Manufacturers VALUES (20, 'TP-Link'); +INSERT INTO Manufacturers VALUES (21, 'Trendnet'); +INSERT INTO Manufacturers VALUES (22, 'VisionTek'); +INSERT INTO Manufacturers VALUES (23, 'Vivotek'); +INSERT INTO Manufacturers VALUES (24, 'Wansview'); diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index af6a17182..af4e37136 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -441,6 +441,8 @@ CREATE TABLE `Monitors` ( `Notes` TEXT, `ServerId` int(10) unsigned, `StorageId` smallint(5) unsigned default 0, + `ManufacturerId` int unsigned, FOREIGN KEY (`ManufacturerId`) REFERENCES `Manufacturers` (Id), + `ModelId` int unsigned, FOREIGN KEY (`ModelId`) REFERENCES `Models` (Id), `Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL','WebSite','NVSocket','VNC') NOT NULL default 'Local', `Function` enum('None','Monitor','Modect','Record','Mocord','Nodect') NOT NULL default 'Monitor', `Enabled` tinyint(3) unsigned NOT NULL default '1', diff --git a/db/zm_update-1.35.10.sql b/db/zm_update-1.35.10.sql new file mode 100644 index 000000000..341c5e162 --- /dev/null +++ b/db/zm_update-1.35.10.sql @@ -0,0 +1,47 @@ +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ManufacturerId' + ) > 0, +"SELECT 'Column ManufacturerId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ManufacturerId` int(10) unsigned AFTER `StorageId`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ManufacturerId' + ) > 0, +"SELECT 'FOREIGN KEY for ManufacturerId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD FOREIGN KEY (`ManufacturerId`) REFERENCES `Manufacturers` (Id)" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ModelId' + ) > 0, +"SELECT 'Column ModelId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ModelId` int(10) unsigned AFTER `ManufacturerId`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ModelId' + ) > 0, +"SELECT 'FOREIGN KEY for ModelId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD FOREIGN KEY (`ModelId`) REFERENCES `Models` (Id)" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; From a6de3e15f4eb0e9bed6682a6521f26a3b2c77947 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 11 Oct 2020 09:57:08 -0400 Subject: [PATCH 002/174] AddManufacturerId and ModelId to Monitor view --- web/skins/classic/views/monitor.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index d64880dff..13ec55633 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -462,7 +462,9 @@ if ( $tab != 'general' ) { ?> - + + + GroupIds() as $group_id ) { @@ -627,6 +629,24 @@ switch ( $tab ) { + + + ManufacturerId(), array('class'=>'chosen')); +?> + + + + + $monitor->ManufacturerId())); +echo htmlSelect('newMonitor[ModelId]', $models, $monitor->ModelId(), array('class'=>'chosen')); +?> + + Date: Sun, 11 Oct 2020 09:57:51 -0400 Subject: [PATCH 003/174] Add object classes for Manufacturer and Model --- web/includes/Manufacturer.php | 23 +++++++++++++++++++++++ web/includes/Model.php | 22 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 web/includes/Manufacturer.php create mode 100644 web/includes/Model.php diff --git a/web/includes/Manufacturer.php b/web/includes/Manufacturer.php new file mode 100644 index 000000000..73c46ad6b --- /dev/null +++ b/web/includes/Manufacturer.php @@ -0,0 +1,23 @@ + null, + 'Name' => '', + ); + + public static function find( $parameters = array(), $options = array() ) { + return ZM_Object::_find(get_class(), $parameters, $options); + } + + public static function find_one( $parameters = array(), $options = array() ) { + return ZM_Object::_find_one(get_class(), $parameters, $options); + } +} # end class Manufacturer +?> diff --git a/web/includes/Model.php b/web/includes/Model.php new file mode 100644 index 000000000..c9b22db8c --- /dev/null +++ b/web/includes/Model.php @@ -0,0 +1,22 @@ + null, + 'Name' => '', + ); + + public static function find( $parameters = array(), $options = array() ) { + return ZM_Object::_find(get_class(), $parameters, $options); + } + + public static function find_one( $parameters = array(), $options = array() ) { + return ZM_Object::_find_one(get_class(), $parameters, $options); + } +} # end class Model +?> From cc486beed50d12a1513db8d8312af4edfe825bb4 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 7 Jul 2021 09:45:23 -0400 Subject: [PATCH 004/174] Add some Acti models --- db/manufacturers.sql | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/db/manufacturers.sql b/db/manufacturers.sql index be15f9c01..eaee2630c 100644 --- a/db/manufacturers.sql +++ b/db/manufacturers.sql @@ -1,4 +1,23 @@ INSERT INTO Manufacturers VALUES (1, 'Acti'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A21'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A23'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A24'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A28'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A31'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A310'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A311'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A32'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A41'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A415'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A416'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A418'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A42'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A421'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A43'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A45'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A46'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A48'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A74'); INSERT INTO Manufacturers VALUES (2, 'Amcrest'); INSERT INTO Manufacturers VALUES (3, 'Airlink101'); INSERT INTO Manufacturers VALUES (4, 'Arecont Vision'); From 8df915e7a47c0b739d0ac39e3e5e7d2dff55d973 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 7 Jul 2021 09:45:53 -0400 Subject: [PATCH 005/174] Fix merge. --- db/zm_update-1.35.29.sql | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/db/zm_update-1.35.29.sql b/db/zm_update-1.35.29.sql index 9030e5863..341c5e162 100644 --- a/db/zm_update-1.35.29.sql +++ b/db/zm_update-1.35.29.sql @@ -1,4 +1,3 @@ -<<<<<<< HEAD SET @s = (SELECT IF( (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() AND table_name = 'Monitors' @@ -42,19 +41,6 @@ SET @s = (SELECT IF( ) > 0, "SELECT 'FOREIGN KEY for ModelId already exists in Monitors'", "ALTER TABLE `Monitors` ADD FOREIGN KEY (`ModelId`) REFERENCES `Models` (Id)" -======= --- --- Add AutoUnarchive action to Filters --- - -SET @s = (SELECT IF( - (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() - AND table_name = 'Filters' - AND column_name = 'AutoUnarchive' - ) > 0, -"SELECT 'Column AutoUunarchive already exists in Filters'", -"ALTER TABLE Filters ADD `AutoUnarchive` tinyint(3) unsigned NOT NULL default '0' AFTER `AutoArchive`" ->>>>>>> master )); PREPARE stmt FROM @s; From 24a77d7fb365768c200559cc3353343e2b57a8e6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 7 Jul 2021 09:46:12 -0400 Subject: [PATCH 006/174] Add ManufacturerId to Model --- web/includes/Model.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/includes/Model.php b/web/includes/Model.php index c9b22db8c..35562f9f9 100644 --- a/web/includes/Model.php +++ b/web/includes/Model.php @@ -9,6 +9,7 @@ class Model extends ZM_Object { protected $defaults = array( 'Id' => null, 'Name' => '', + 'ManufacturerId' => null, ); public static function find( $parameters = array(), $options = array() ) { From 3bb2b804b3a69f158e54149dc9e707a96cd611b0 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 7 Jul 2021 09:46:36 -0400 Subject: [PATCH 007/174] Include Model and Manufacturer to includes in Monitor.php --- web/includes/Monitor.php | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index ad3e95a0d..4f9450a3d 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -1,11 +1,13 @@ AlarmCommand('disable'); } + function Model() { + if (!$this->{'Model'}) { + $this->{'Model'} = Model::find_one(array('Id'=>$this->ModelId())); + if (!$this->{'Model'}) $this->{'Model'} = new Model(); + } + return $this->{'Model'}; + } + function Manufacturer() { + if (!$this->{'Manufacturer'}) { + $this->{'Manufacturer'} = Manufacturer::find_one(array('Id'=>$this->ManufacturerId())); + if (!$this->{'Manufacturer'}) $this->{'Manufacturer'} = new Manufacturer(); + } + return $this->{'Manufacturer'}; + } } // end class Monitor ?> From c6209ce460e4b942d42e9c0a84c10e6f06f38ab5 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 7 Jul 2021 09:47:00 -0400 Subject: [PATCH 008/174] Store new Model and Manufacturer when saving Monitor --- web/includes/actions/monitor.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/web/includes/actions/monitor.php b/web/includes/actions/monitor.php index 1c6e1f72f..3fafb0f82 100644 --- a/web/includes/actions/monitor.php +++ b/web/includes/actions/monitor.php @@ -45,6 +45,25 @@ if ( $action == 'save' ) { $x10Monitor = array(); } } + if ( !$_REQUEST['newMonitor[ManufacturerId'] and ($_REQUEST['newMonitor[Manufacturer'] != '') ) { + # Need to add a new Manufacturer entry + $newManufacturer = ZM\Manufacturer::find_one(array('Name'=>$_REQUEST['newMonitor[Manufacturer'])); + if (!$newManufacturer) { + $newManufacturer = new ZM\Manufacturer(); + $newManufacturer->save(array('Name'=>$_REQUEST['newMonitor[Manufacturer'])); + } + $_REQUEST['newMonitor[ManufacturerId'] = $newManufacturer->Id(); + } + + if ( !$_REQUEST['newMonitor[ModelId'] and ($_REQUEST['newMonitor[Model'] != '') ) { + # Need to add a new Model entry + $newModel = ZM\Model::find_one(array('Name'=>$_REQUEST['newMonitor[Model'])); + if (!$newModel) { + $newModel = new ZM\Model(); + $newMdoel->save(array('Name'=>$_REQUEST['newMonitor[Model'], 'ManufacturerId'=>$_REQUEST['newMonitor[ManufacturerId'])); + } + $_REQUEST['newMonitor[ModelId'] = $newModel->Id(); + } $monitor = new ZM\Monitor($mid); From 54f676a501b63bec148b2e951011b50bd0ae1592 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 7 Jul 2021 09:47:32 -0400 Subject: [PATCH 009/174] Add ManufacturerId_onchange and ModelId_onchange to hide/show the text input for custom entry --- web/skins/classic/views/js/monitor.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/monitor.js b/web/skins/classic/views/js/monitor.js index 4b41d8dd2..d28d21bf5 100644 --- a/web/skins/classic/views/js/monitor.js +++ b/web/skins/classic/views/js/monitor.js @@ -323,7 +323,6 @@ function update_estimated_ram_use() { var max_buffer_count = parseInt(document.querySelectorAll('input[name="newMonitor[MaxImageBufferCount]"]')[0].value); if (max_buffer_count) { var max_buffer_size = (min_buffer_count + max_buffer_count) * width * height * colours; - console.log(max_buffer_size); document.getElementById('estimated_ram_use').innerHTML += ' Max: ' + human_filesize(max_buffer_size); } else { document.getElementById('estimated_ram_use').innerHTML += ' Max: Unlimited'; @@ -345,4 +344,17 @@ function getLocation() { } } +function ManufacturerId_onchange(ManufacturerId_select) { + if (ManufacturerId_select.value()) + $j('newMonitor[Manufacturer]').hide(); + else + $j('newMonitor[Manufacturer]').show(); +} +function ModelId_onchange(ModelId_select) { + if (ModelId_select.value()) + $j('newMonitor[Model]').hide(); + else + $j('newMonitor[Model]').show(); +} + window.addEventListener('DOMContentLoaded', initPage); From 4ff4e1f7807d650b009384758487527ffc8c7ec5 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 7 Jul 2021 09:47:55 -0400 Subject: [PATCH 010/174] add Manufacturer and Model dropdown/text inputs to monitor edit view --- web/skins/classic/views/monitor.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 5e30db969..e6645dec5 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -492,18 +492,25 @@ switch ( $name ) { ManufacturerId(), array('class'=>'chosen')); +$manufacturers = array_merge( + array(''=>translate('unknown')), + ZM\Manufacturer::find()); +echo htmlSelect('newMonitor[ManufacturerId]', $manufacturers, $monitor->ManufacturerId(), array('class'=>'chosen','data-on-change-this'=>'ManufacturerId_onchange')); ?> + $monitor->ManufacturerId())); -echo htmlSelect('newMonitor[ModelId]', $models, $monitor->ModelId(), array('class'=>'chosen')); +$models = array_merge( + array(''=>translate('unknown')), + ZM\Model::find(array('ManufacturerId'=>$monitor->ManufacturerId())) +); +echo htmlSelect('newMonitor[ModelId]', $models, $monitor->ModelId(), array('class'=>'chosen', 'data-on-change-this'=>'ModelId_onchange')); ?> + From 413ac984eb3e1f496b38c08eecfda3104e56e8f3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 7 Jul 2021 09:48:24 -0400 Subject: [PATCH 011/174] add models.sql --- db/models.sql | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 db/models.sql diff --git a/db/models.sql b/db/models.sql new file mode 100644 index 000000000..b7150d816 --- /dev/null +++ b/db/models.sql @@ -0,0 +1,45 @@ +/* INSERT INTO Manufacturers VALUES (1, 'Acti'); */ +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A21'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A23'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A24'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A28'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A31'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A310'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A311'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A32'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A41'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A415'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A416'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A418'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A42'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A421'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A43'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A45'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A46'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A48'); +INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A74'); +/* +INSERT INTO Manufacturers VALUES (2, 'Amcrest'); +INSERT INTO Manufacturers VALUES (3, 'Airlink101'); +INSERT INTO Manufacturers VALUES (4, 'Arecont Vision'); +INSERT INTO Manufacturers VALUES (5, 'Axis'); +INSERT INTO Manufacturers VALUES (6, 'Dahua'); +INSERT INTO Manufacturers VALUES (7, 'D-Link'); +INSERT INTO Manufacturers VALUES (8, 'Edimax'); +INSERT INTO Manufacturers VALUES (9, 'Foscam'); +INSERT INTO Manufacturers VALUES (10, 'Gadspot'); +INSERT INTO Manufacturers VALUES (11, 'GrandStream'); +INSERT INTO Manufacturers VALUES (12, 'HikVision'); +INSERT INTO Manufacturers VALUES (13, 'JVC'); +INSERT INTO Manufacturers VALUES (14, 'Maginon'); +INSERT INTO Manufacturers VALUES (15, 'Mobotix'); +INSERT INTO Manufacturers VALUES (16, 'Oncam Grandeye'); +INSERT INTO Manufacturers VALUES (17, 'Panasonic'); +INSERT INTO Manufacturers VALUES (18, 'Pelco'); +INSERT INTO Manufacturers VALUES (19, 'Sony'); +INSERT INTO Manufacturers VALUES (20, 'TP-Link'); +INSERT INTO Manufacturers VALUES (21, 'Trendnet'); +INSERT INTO Manufacturers VALUES (22, 'VisionTek'); +INSERT INTO Manufacturers VALUES (23, 'Vivotek'); +INSERT INTO Manufacturers VALUES (24, 'Wansview'); +*/ From 7ca7d40b6fb94333c6d06a11f03aaf632b8c96cc Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 10:32:04 -0400 Subject: [PATCH 012/174] Add defaults for ModelId and ManufacturerId. Fixes the methods for loading them --- web/includes/Monitor.php | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index 54bf605cb..bd9987b2c 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -49,6 +49,8 @@ class Monitor extends ZM_Object { 'Notes' => '', 'ServerId' => 0, 'StorageId' => 0, + 'ManufacturerId' => null, + 'ModelId' => null, 'Type' => 'Ffmpeg', 'Function' => 'Mocord', 'Enabled' => array('type'=>'boolean','default'=>1), @@ -685,16 +687,26 @@ class Monitor extends ZM_Object { $output = $this->AlarmCommand('disable'); } function Model() { - if (!$this->{'Model'}) { - $this->{'Model'} = Model::find_one(array('Id'=>$this->ModelId())); - if (!$this->{'Model'}) $this->{'Model'} = new Model(); + if (!property_exists($this, 'Model')) { + if ($this->{'ModelId'}) { + $this->{'Model'} = Model::find_one(array('Id'=>$this->ModelId())); + if (!$this->{'Model'}) + $this->{'Model'} = new Model(); + } else { + $this->{'Model'} = new Model(); + } } return $this->{'Model'}; } function Manufacturer() { - if (!$this->{'Manufacturer'}) { - $this->{'Manufacturer'} = Manufacturer::find_one(array('Id'=>$this->ManufacturerId())); - if (!$this->{'Manufacturer'}) $this->{'Manufacturer'} = new Manufacturer(); + if (!property_exists($this, 'Manufacturer')) { + if ($this->{'ManufacturerId'}) { + $this->{'Manufacturer'} = Manufacturer::find_one(array('Id'=>$this->ManufacturerId())); + if (!$this->{'Manufacturer'}) + $this->{'Manufacturer'} = new Manufacturer(); + } else { + $this->{'Manufacturer'} = new Manufacturer(); + } } return $this->{'Manufacturer'}; } From 2f12615f088f8026bba909cb16e874947c353d9c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 10:33:16 -0400 Subject: [PATCH 013/174] assign REQUEST['newMonitor'] to a variable to simplify code. Fixup ModelId and ManufacturerId saving. --- web/includes/actions/monitor.php | 68 +++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/web/includes/actions/monitor.php b/web/includes/actions/monitor.php index 3fafb0f82..f6cbeca5f 100644 --- a/web/includes/actions/monitor.php +++ b/web/includes/actions/monitor.php @@ -45,24 +45,31 @@ if ( $action == 'save' ) { $x10Monitor = array(); } } - if ( !$_REQUEST['newMonitor[ManufacturerId'] and ($_REQUEST['newMonitor[Manufacturer'] != '') ) { + + # For convenience + $newMonitor = $_REQUEST['newMonitor']; + + if ( !$newMonitor['ManufacturerId'] and ($newMonitor['Manufacturer'] != '') ) { # Need to add a new Manufacturer entry - $newManufacturer = ZM\Manufacturer::find_one(array('Name'=>$_REQUEST['newMonitor[Manufacturer'])); + $newManufacturer = ZM\Manufacturer::find_one(array('Name'=>$newMonitor['Manufacturer'])); if (!$newManufacturer) { $newManufacturer = new ZM\Manufacturer(); - $newManufacturer->save(array('Name'=>$_REQUEST['newMonitor[Manufacturer'])); + $newManufacturer->save(array('Name'=>$newMonitor['Manufacturer'])); } - $_REQUEST['newMonitor[ManufacturerId'] = $newManufacturer->Id(); + $newMonitor['ManufacturerId'] = $newManufacturer->Id(); } - if ( !$_REQUEST['newMonitor[ModelId'] and ($_REQUEST['newMonitor[Model'] != '') ) { + if ( !$newMonitor['ModelId'] and ($newMonitor['Model'] != '') ) { # Need to add a new Model entry - $newModel = ZM\Model::find_one(array('Name'=>$_REQUEST['newMonitor[Model'])); + $newModel = ZM\Model::find_one(array('Name'=>$newMonitor['Model'])); if (!$newModel) { $newModel = new ZM\Model(); - $newMdoel->save(array('Name'=>$_REQUEST['newMonitor[Model'], 'ManufacturerId'=>$_REQUEST['newMonitor[ManufacturerId'])); + $newModel->save(array( + 'Name'=>$newMonitor['Model'], + 'ManufacturerId'=>$newMonitor['ManufacturerId'] + )); } - $_REQUEST['newMonitor[ModelId'] = $newModel->Id(); + $newMonitor['ModelId'] = $newModel->Id(); } $monitor = new ZM\Monitor($mid); @@ -88,22 +95,22 @@ if ( $action == 'save' ) { # Checkboxes don't return an element in the POST data, so won't be present in newMonitor. # So force a value for these fields foreach ( $types as $field => $value ) { - if ( ! isset($_REQUEST['newMonitor'][$field] ) ) { - $_REQUEST['newMonitor'][$field] = $value; + if ( ! isset($newMonitor[$field] ) ) { + $newMonitor[$field] = $value; } } # end foreach type - if ( $_REQUEST['newMonitor']['ServerId'] == 'auto' ) { - $_REQUEST['newMonitor']['ServerId'] = dbFetchOne( + if ( $newMonitor['ServerId'] == 'auto' ) { + $newMonitor['ServerId'] = dbFetchOne( 'SELECT Id FROM Servers WHERE Status=\'Running\' ORDER BY FreeMem DESC, CpuLoad ASC LIMIT 1', 'Id'); - ZM\Debug('Auto selecting server: Got ' . $_REQUEST['newMonitor']['ServerId']); - if ( ( !$_REQUEST['newMonitor'] ) and defined('ZM_SERVER_ID') ) { - $_REQUEST['newMonitor']['ServerId'] = ZM_SERVER_ID; + ZM\Debug('Auto selecting server: Got ' . $newMonitor['ServerId']); + if ((!$newMonitor['ServerId']) and defined('ZM_SERVER_ID')) { + $newMonitor['ServerId'] = ZM_SERVER_ID; ZM\Debug('Auto selecting server to ' . ZM_SERVER_ID); } } - $changes = $monitor->changes($_REQUEST['newMonitor']); + $changes = $monitor->changes($newMonitor); $restart = false; if ( count($changes) ) { @@ -134,13 +141,13 @@ if ( $action == 'save' ) { if ( file_exists($OldStorage->Path().'/'.$saferOldName) ) unlink($OldStorage->Path().'/'.$saferOldName); - $NewStorage = new ZM\Storage($_REQUEST['newMonitor']['StorageId']); + $NewStorage = new ZM\Storage($newMonitor['StorageId']); if ( !file_exists($NewStorage->Path().'/'.$mid) ) { if ( !mkdir($NewStorage->Path().'/'.$mid, 0755) ) { ZM\Error('Unable to mkdir ' . $NewStorage->Path().'/'.$mid); } } - $saferNewName = basename($_REQUEST['newMonitor']['Name']); + $saferNewName = basename($newMonitor['Name']); $link_path = $NewStorage->Path().'/'.$saferNewName; // Use a relative path for the target so the link continues to work from backups or directory changes. if ( !symlink($mid, $link_path) ) { @@ -151,8 +158,8 @@ if ( $action == 'save' ) { } // end if Name or Storage Area Change if ( isset($changes['Width']) || isset($changes['Height']) ) { - $newW = $_REQUEST['newMonitor']['Width']; - $newH = $_REQUEST['newMonitor']['Height']; + $newW = $newMonitor['Width']; + $newH = $newMonitor['Height']; $zones = dbFetchAll('SELECT * FROM Zones WHERE MonitorId=?', NULL, array($mid)); @@ -236,14 +243,27 @@ if ( $action == 'save' ) { if ( $monitor->insert($changes) ) { $mid = $monitor->Id(); - $zoneArea = $_REQUEST['newMonitor']['Width'] * $_REQUEST['newMonitor']['Height']; - dbQuery("INSERT INTO Zones SET MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, sprintf( "%d,%d %d,%d %d,%d %d,%d", 0, 0, $_REQUEST['newMonitor']['Width']-1, 0, $_REQUEST['newMonitor']['Width']-1, $_REQUEST['newMonitor']['Height']-1, 0, $_REQUEST['newMonitor']['Height']-1 ), $zoneArea, intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*2)/100) ) ); - //$view = 'none'; + $zoneArea = $newMonitor['Width'] * $newMonitor['Height']; + dbQuery("INSERT INTO Zones SET MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, + sprintf( '%d,%d %d,%d %d,%d %d,%d', 0, 0, + $newMonitor['Width']-1, + 0, + $newMonitor['Width']-1, + $newMonitor['Height']-1, + 0, + $newMonitor['Height']-1), + $zoneArea, + intval(($zoneArea*3)/100), + intval(($zoneArea*75)/100), + intval(($zoneArea*3)/100), + intval(($zoneArea*75)/100), + intval(($zoneArea*2)/100) + )); $Storage = $monitor->Storage(); error_reporting(0); mkdir($Storage->Path().'/'.$mid, 0755); - $saferName = basename($_REQUEST['newMonitor']['Name']); + $saferName = basename($newMonitor['Name']); symlink($mid, $Storage->Path().'/'.$saferName); } else { From 12783f6edfe71dee6b8bf8a92e2c4fcf71404297 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 20:43:53 -0400 Subject: [PATCH 014/174] Add manufacturers, models and servers routes --- web/api/app/Config/routes.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/api/app/Config/routes.php b/web/api/app/Config/routes.php index 8dd2c1f63..6b3314d09 100644 --- a/web/api/app/Config/routes.php +++ b/web/api/app/Config/routes.php @@ -23,8 +23,6 @@ /** * Load the API / REST routes */ - /* Add new API to retrieve camera controls - for PTZ */ - /* refer to https://github.com/ZoneMinder/ZoneMinder/issues/799#issuecomment-105233112 */ Router::mapResources('configs'); Router::mapResources('controls'); Router::mapResources('events'); @@ -32,7 +30,10 @@ Router::mapResources('groups'); Router::mapResources('host'); Router::mapResources('logs'); + Router::mapResources('manufacturers'); + Router::mapResources('models'); Router::mapResources('monitors'); + Router::mapResources('servers'); Router::mapResources('states'); Router::mapResources('users'); Router::mapResources('zonepresets'); From 34d9f87d6dee2916f7ada7edb7f4ef791c1fbe62 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 20:44:16 -0400 Subject: [PATCH 015/174] remove cruft from ServersController.php --- web/api/app/Controller/ServersController.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/web/api/app/Controller/ServersController.php b/web/api/app/Controller/ServersController.php index c3ac6fad7..bbde27fae 100644 --- a/web/api/app/Controller/ServersController.php +++ b/web/api/app/Controller/ServersController.php @@ -89,8 +89,6 @@ class ServersController extends AppController { $this->Server->create(); if ( $this->Server->save($this->request->data) ) { - # Might be nice to send it a start request - #$this->daemonControl($this->Server->id, 'start', $this->request->data); return $this->flash(__('The server has been saved.'), array('action' => 'index')); } } @@ -126,8 +124,6 @@ class ServersController extends AppController { 'message' => $message, '_serialize' => array('message') )); - // - restart this server after change - #$this->daemonControl($this->Server->id, 'restart', $this->request->data); } /** @@ -151,8 +147,6 @@ class ServersController extends AppController { } $this->request->allowMethod('post', 'delete'); - #$this->daemonControl($this->Server->id, 'stop'); - if ( $this->Server->delete() ) { return $this->flash(__('The server has been deleted.'), array('action' => 'index')); } else { From fe72056d73d84f527437c09dfdfd1c68841a4c47 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 20:48:14 -0400 Subject: [PATCH 016/174] fixup populating Models dropdown after Manufacturer select --- web/skins/classic/views/js/monitor.js | 53 ++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/web/skins/classic/views/js/monitor.js b/web/skins/classic/views/js/monitor.js index c32b66a0b..44bcddb5b 100644 --- a/web/skins/classic/views/js/monitor.js +++ b/web/skins/classic/views/js/monitor.js @@ -345,17 +345,52 @@ function getLocation() { } } -function ManufacturerId_onchange(ManufacturerId_select) { - if (ManufacturerId_select.value()) - $j('newMonitor[Manufacturer]').hide(); - else - $j('newMonitor[Manufacturer]').show(); +function populate_models(ManufacturerId) { + let dropdown = $j('[name="newMonitor[ModelId]"]'); + if (!dropdown.length) { + console.log("No element found for ModelId"); + return; + } + + dropdown.empty(); + dropdown.append(''); + dropdown.prop('selectedIndex', 0); + + // Populate dropdown with list of provinces + $j.getJSON(thisUrl+'?request=models&ManufacturerId='+ManufacturerId, function (data) { + if (data.result == 'Ok') { + $j.each(data.models, function (key, entry) { + dropdown.append($j('').attr('value', entry.Id).text(entry.Name)); + }); + dropdown.chosen("destroy"); + dropdown.chosen(); + } else { + alert(data.result); + } + }); } + +function ManufacturerId_onchange(ManufacturerId_select) { + if (ManufacturerId_select.value) { + ManufacturerId_select.form.elements['newMonitor[Manufacturer]'].style['display'] = 'none'; + populate_models(ManufacturerId_select.value); + } else { + ManufacturerId_select.form.elements['newMonitor[Manufacturer]'].style['display'] = 'inline'; + // Set models dropdown to Unknown, text area visible + let ModelId_dropdown = $j('[name="newMonitor[ModelId]"]'); + ModelId_dropdown.empty(); + ModelId_dropdown.append(''); + ModelId_dropdown.prop('selectedIndex', 0); + $j('[name="newMonitor[Model]"]').show(); + } +} + function ModelId_onchange(ModelId_select) { - if (ModelId_select.value()) - $j('newMonitor[Model]').hide(); - else - $j('newMonitor[Model]').show(); + if (parseInt(ModelId_select.value)) { + $j('[name="newMonitor[Model]"]').hide(); + } else { + $j('[name="newMonitor[Model]"]').show(); + } } window.addEventListener('DOMContentLoaded', initPage); From d98d20958ce11244d0775b3b987c51b11ee662dc Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 20:48:43 -0400 Subject: [PATCH 017/174] fixup the Manufacturer and Model ddms and text inputs --- web/skins/classic/views/monitor.php | 40 ++++++++++++++++++----------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index fa4b3ba4f..327de5def 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -457,27 +457,37 @@ switch ( $name ) { - translate('unknown')), - ZM\Manufacturer::find()); -echo htmlSelect('newMonitor[ManufacturerId]', $manufacturers, $monitor->ManufacturerId(), array('class'=>'chosen','data-on-change-this'=>'ManufacturerId_onchange')); + +translate('unknown')); + foreach ( ZM\Manufacturer::find( null, array('order'=>'lower(Name)')) as $Manufacturer ) { + $manufacturers[$Manufacturer->Id()] = $Manufacturer->Name(); + } + echo htmlSelect('newMonitor[ManufacturerId]', $manufacturers, $monitor->ManufacturerId(), + array('class'=>'chosen','data-on-change-this'=>'ManufacturerId_onchange')); ?> - + ManufacturerId() ? ' style="display:none"' : '' ?> + /> - translate('unknown')), - ZM\Model::find(array('ManufacturerId'=>$monitor->ManufacturerId())) -); -echo htmlSelect('newMonitor[ModelId]', $models, $monitor->ModelId(), array('class'=>'chosen', 'data-on-change-this'=>'ModelId_onchange')); + +translate('unknown')); + foreach ( ZM\Model::find(array('ManufacturerId'=>$monitor->ManufacturerId()), array('order'=>'lower(Name)')) as $Model ) { + $models[$Model->Id()] = $Model->Name(); + } + echo htmlSelect('newMonitor[ModelId]', $models, $monitor->ModelId(), + array('class'=>'chosen', 'data-on-change-this'=>'ModelId_onchange')); ?> - + ModelId() ? ' style="display:none"':'' ?>/> From c66489fb303de460fac00c33aeb659f84635db49 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 20:49:30 -0400 Subject: [PATCH 018/174] rough in api support for Models and Manufacturers --- .../app/Controller/CameraModelsController.php | 156 +++++++++++++++++ .../Controller/ManufacturersController.php | 162 ++++++++++++++++++ web/api/app/Model/CameraModel.php | 70 ++++++++ web/api/app/Model/Manufacturer.php | 77 +++++++++ web/api/app/View/Manufacturers/json/edit.ctp | 2 + web/api/app/View/Manufacturers/json/index.ctp | 1 + web/api/app/View/Manufacturers/json/view.ctp | 1 + web/api/app/View/Manufacturers/xml/edit.ctp | 2 + web/api/app/View/Manufacturers/xml/index.ctp | 2 + web/api/app/View/Manufacturers/xml/view.ctp | 2 + 10 files changed, 475 insertions(+) create mode 100644 web/api/app/Controller/CameraModelsController.php create mode 100644 web/api/app/Controller/ManufacturersController.php create mode 100644 web/api/app/Model/CameraModel.php create mode 100644 web/api/app/Model/Manufacturer.php create mode 100644 web/api/app/View/Manufacturers/json/edit.ctp create mode 100644 web/api/app/View/Manufacturers/json/index.ctp create mode 100644 web/api/app/View/Manufacturers/json/view.ctp create mode 100644 web/api/app/View/Manufacturers/xml/edit.ctp create mode 100644 web/api/app/View/Manufacturers/xml/index.ctp create mode 100644 web/api/app/View/Manufacturers/xml/view.ctp diff --git a/web/api/app/Controller/CameraModelsController.php b/web/api/app/Controller/CameraModelsController.php new file mode 100644 index 000000000..691fd0767 --- /dev/null +++ b/web/api/app/Controller/CameraModelsController.php @@ -0,0 +1,156 @@ +CameraModel->recursive = 0; + + $options = ''; + $models = $this->CameraModel->find('all', $options); + $this->set(array( + 'models' => $models, + '_serialize' => array('models') + )); + } + +/** + * view method + * + * @throws NotFoundException + * @param string $id + * @return void + */ + public function view($id = null) { + $this->CameraModel->recursive = 0; + if ( !$this->CameraModel->exists($id) ) { + throw new NotFoundException(__('Invalid model')); + } + $restricted = ''; + + $options = array('conditions' => array( + array('CameraModel.'.$this->CameraModel->primaryKey => $id), + $restricted + ) + ); + $model = $this->CameraModel->find('first', $options); + $this->set(array( + 'model' => $model, + '_serialize' => array('model') + )); + } + +/** + * add method + * + * @return void + */ + public function add() { + if ($this->request->is('post')) { + + global $user; + $canEdit = (!$user) || ($user['System'] == 'Edit'); + if (!$canEdit) { + throw new UnauthorizedException(__('Insufficient privileges')); + return; + } + + $this->CameraModel->create(); + if ($this->CameraModel->save($this->request->data)) { + return $this->flash(__('The model has been saved.'), array('action' => 'index')); + } + } + } + +/** + * edit method + * + * @throws NotFoundException + * @param string $id + * @return void + */ + public function edit($id = null) { + $this->CameraModel->id = $id; + + global $user; + $canEdit = (!$user) || ($user['System'] == 'Edit'); + if (!$canEdit) { + throw new UnauthorizedException(__('Insufficient privileges')); + return; + } + + if (!$this->CameraModel->exists($id)) { + throw new NotFoundException(__('Invalid model')); + } + if ($this->CameraModel->save($this->request->data)) { + $message = 'Saved'; + } else { + $message = 'Error'; + } + + $this->set(array( + 'message' => $message, + '_serialize' => array('message') + )); + } + +/** + * delete method + * + * @throws NotFoundException + * @param string $id + * @return void + */ + public function delete($id = null) { + global $user; + $canEdit = (!$user) || ($user['System'] == 'Edit'); + if (!$canEdit) { + throw new UnauthorizedException(__('Insufficient privileges')); + return; + } + + $this->CameraModel->id = $id; + if (!$this->CameraModel->exists()) { + throw new NotFoundException(__('Invalid model')); + } + $this->request->allowMethod('post', 'delete'); + + if ($this->CameraModel->delete()) { + return $this->flash(__('The model has been deleted.'), array('action' => 'index')); + } else { + return $this->flash(__('The model could not be deleted. Please, try again.'), array('action' => 'index')); + } + } +} diff --git a/web/api/app/Controller/ManufacturersController.php b/web/api/app/Controller/ManufacturersController.php new file mode 100644 index 000000000..0249af6af --- /dev/null +++ b/web/api/app/Controller/ManufacturersController.php @@ -0,0 +1,162 @@ +Manufacturer->recursive = 0; + + $options = ''; + $manufacturers = $this->Manufacturer->find('all', $options); + $this->set(array( + 'manufacturers' => $manufacturers, + '_serialize' => array('manufacturers') + )); + } + +/** + * view method + * + * @throws NotFoundException + * @param string $id + * @return void + */ + public function view($id = null) { + $this->Manufacturer->recursive = 0; + if ( !$this->Manufacturer->exists($id) ) { + throw new NotFoundException(__('Invalid manufacturer')); + } + $restricted = ''; + + $options = array('conditions' => array( + array('Manufacturer.'.$this->Manufacturer->primaryKey => $id), + $restricted + ) + ); + $manufacturer = $this->Manufacturer->find('first', $options); + $this->set(array( + 'manufacturer' => $manufacturer, + '_serialize' => array('manufacturer') + )); + } + +/** + * add method + * + * @return void + */ + public function add() { + if ( $this->request->is('post') ) { + + global $user; + $canEdit = (!$user) || ($user['System'] == 'Edit'); + if ( !$canEdit ) { + throw new UnauthorizedException(__('Insufficient privileges')); + return; + } + + $this->Manufacturer->create(); + if ( $this->Manufacturer->save($this->request->data) ) { + # Might be nice to send it a start request + #$this->daemonControl($this->Manufacturer->id, 'start', $this->request->data); + return $this->flash(__('The manufacturer has been saved.'), array('action' => 'index')); + } + } + } + +/** + * edit method + * + * @throws NotFoundException + * @param string $id + * @return void + */ + public function edit($id = null) { + $this->Manufacturer->id = $id; + + global $user; + $canEdit = (!$user) || ($user['System'] == 'Edit'); + if ( !$canEdit ) { + throw new UnauthorizedException(__('Insufficient privileges')); + return; + } + + if ( !$this->Manufacturer->exists($id) ) { + throw new NotFoundException(__('Invalid manufacturer')); + } + if ( $this->Manufacturer->save($this->request->data) ) { + $message = 'Saved'; + } else { + $message = 'Error'; + } + + $this->set(array( + 'message' => $message, + '_serialize' => array('message') + )); + // - restart this manufacturer after change + #$this->daemonControl($this->Manufacturer->id, 'restart', $this->request->data); + } + +/** + * delete method + * + * @throws NotFoundException + * @param string $id + * @return void + */ + public function delete($id = null) { + global $user; + $canEdit = (!$user) || ($user['System'] == 'Edit'); + if ( !$canEdit ) { + throw new UnauthorizedException(__('Insufficient privileges')); + return; + } + + $this->Manufacturer->id = $id; + if ( !$this->Manufacturer->exists() ) { + throw new NotFoundException(__('Invalid manufacturer')); + } + $this->request->allowMethod('post', 'delete'); + + #$this->daemonControl($this->Manufacturer->id, 'stop'); + + if ( $this->Manufacturer->delete() ) { + return $this->flash(__('The manufacturer has been deleted.'), array('action' => 'index')); + } else { + return $this->flash(__('The manufacturer could not be deleted. Please, try again.'), array('action' => 'index')); + } + } +} diff --git a/web/api/app/Model/CameraModel.php b/web/api/app/Model/CameraModel.php new file mode 100644 index 000000000..e953b5db8 --- /dev/null +++ b/web/api/app/Model/CameraModel.php @@ -0,0 +1,70 @@ + array( + 'notBlank' => array( + 'rule' => array('notBlank'))), + 'Id' => array( + 'numeric' => array( + 'rule' => array('numeric'), + //'message' => 'Your custom message here', + //'allowEmpty' => false, + //'required' => false, + //'last' => false, // Stop validation after this rule + //'on' => 'create', // Limit validation to 'create' or 'update' operations + ), + ), + ); + + //The Associations below have been created with all possible keys, those that are not needed can be removed + +/** + * hasMany associations + * + * @var array + */ + public $hasOne = array( + 'Manufacturer' => array( + 'className' => 'Manufacturer', + 'joinTable' => 'Manufacturers', + 'foreignKey' => 'Id', + ), + ); + //var $actsAs = array( 'Containable' ); +} diff --git a/web/api/app/Model/Manufacturer.php b/web/api/app/Model/Manufacturer.php new file mode 100644 index 000000000..34a6c88c0 --- /dev/null +++ b/web/api/app/Model/Manufacturer.php @@ -0,0 +1,77 @@ + array( + 'numeric' => array( + 'rule' => array('numeric'), + //'message' => 'Your custom message here', + //'allowEmpty' => false, + //'required' => false, + //'last' => false, // Stop validation after this rule + //'on' => 'create', // Limit validation to 'create' or 'update' operations + ), + ), + 'Name' => array( + 'notBlank' => array( + 'rule' => array('notBlank'))), + ); + + //The Associations below have been created with all possible keys, those that are not needed can be removed + +/** + * hasMany associations + * + * @var array + */ + public $hasMany = array( + 'Model' => array( + 'className' => 'Model', + 'foreignKey' => 'ManufacturerId', + 'dependent' => false, + 'conditions' => '', + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'exclusive' => '', + 'finderQuery' => '', + 'counterQuery' => '' + ) + ); +} diff --git a/web/api/app/View/Manufacturers/json/edit.ctp b/web/api/app/View/Manufacturers/json/edit.ctp new file mode 100644 index 000000000..a32d9cfad --- /dev/null +++ b/web/api/app/View/Manufacturers/json/edit.ctp @@ -0,0 +1,2 @@ +echo json_encode($message); +echo json_encode($manufacturer); diff --git a/web/api/app/View/Manufacturers/json/index.ctp b/web/api/app/View/Manufacturers/json/index.ctp new file mode 100644 index 000000000..4c54bdf95 --- /dev/null +++ b/web/api/app/View/Manufacturers/json/index.ctp @@ -0,0 +1 @@ +echo json_encode($manufacturers); diff --git a/web/api/app/View/Manufacturers/json/view.ctp b/web/api/app/View/Manufacturers/json/view.ctp new file mode 100644 index 000000000..4e0a14ae6 --- /dev/null +++ b/web/api/app/View/Manufacturers/json/view.ctp @@ -0,0 +1 @@ +echo json_encode($manufacturer); diff --git a/web/api/app/View/Manufacturers/xml/edit.ctp b/web/api/app/View/Manufacturers/xml/edit.ctp new file mode 100644 index 000000000..09fb8979a --- /dev/null +++ b/web/api/app/View/Manufacturers/xml/edit.ctp @@ -0,0 +1,2 @@ +$xml = Xml::fromArray(array('response' => $message)); +echo $xml->asXML(); diff --git a/web/api/app/View/Manufacturers/xml/index.ctp b/web/api/app/View/Manufacturers/xml/index.ctp new file mode 100644 index 000000000..9bb514fff --- /dev/null +++ b/web/api/app/View/Manufacturers/xml/index.ctp @@ -0,0 +1,2 @@ +$xml = Xml::fromArray(array('response' => $servers)); +echo $xml->asXML(); diff --git a/web/api/app/View/Manufacturers/xml/view.ctp b/web/api/app/View/Manufacturers/xml/view.ctp new file mode 100644 index 000000000..3b2a3fdad --- /dev/null +++ b/web/api/app/View/Manufacturers/xml/view.ctp @@ -0,0 +1,2 @@ +$xml = Xml::fromArray(array('response' => $server)); +echo $xml->asXML(); From 292b3c1d3767fb9c57ccc2778f20d9e269c31754 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 20:49:53 -0400 Subject: [PATCH 019/174] add an ajax request for querying the available models --- web/ajax/models.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 web/ajax/models.php diff --git a/web/ajax/models.php b/web/ajax/models.php new file mode 100644 index 000000000..3a4f54c5b --- /dev/null +++ b/web/ajax/models.php @@ -0,0 +1,24 @@ +$_REQUEST['ManufacturerId']), array('order'=>'lower(Name)')); +ajaxResponse(array('models'=>$models)); +?> From 93c5ad0939df10685fe6042a7c8c13a0cf17213f Mon Sep 17 00:00:00 2001 From: Peter Keresztes Schmidt Date: Sun, 12 Sep 2021 11:28:57 +0200 Subject: [PATCH 020/174] Image: Fix Wclobbered warnings From C99 spec: [...] objects of automatic storage duration that are local to the function containing the invocation of the corresponding setjmp macro that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate Remove the variables in question or pass them as const refs. --- src/zm_image.cpp | 104 +++++++++++++++++++++++------------------------ src/zm_image.h | 2 +- 2 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/zm_image.cpp b/src/zm_image.cpp index a837138bc..f0d94a542 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -935,14 +935,13 @@ bool Image::WriteRaw(const char *filename) const { bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsigned int p_subpixelorder) { unsigned int new_width, new_height, new_colours, new_subpixelorder; - struct jpeg_decompress_struct *cinfo = readjpg_dcinfo; - if ( !cinfo ) { - cinfo = readjpg_dcinfo = new jpeg_decompress_struct; - cinfo->err = jpeg_std_error(&jpg_err.pub); + if ( !readjpg_dcinfo ) { + readjpg_dcinfo = new jpeg_decompress_struct; + readjpg_dcinfo->err = jpeg_std_error(&jpg_err.pub); jpg_err.pub.error_exit = zm_jpeg_error_exit; jpg_err.pub.emit_message = zm_jpeg_emit_message; - jpeg_create_decompress(cinfo); + jpeg_create_decompress(readjpg_dcinfo); } FILE *infile; @@ -952,30 +951,30 @@ bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsign } if ( setjmp(jpg_err.setjmp_buffer) ) { - jpeg_abort_decompress(cinfo); + jpeg_abort_decompress(readjpg_dcinfo); fclose(infile); return false; } - jpeg_stdio_src(cinfo, infile); + jpeg_stdio_src(readjpg_dcinfo, infile); - jpeg_read_header(cinfo, TRUE); + jpeg_read_header(readjpg_dcinfo, TRUE); - if ( (cinfo->num_components != 1) && (cinfo->num_components != 3) ) { + if ( (readjpg_dcinfo->num_components != 1) && (readjpg_dcinfo->num_components != 3) ) { Error("Unexpected colours when reading jpeg image: %d", colours); - jpeg_abort_decompress(cinfo); + jpeg_abort_decompress(readjpg_dcinfo); fclose(infile); return false; } /* Check if the image has at least one huffman table defined. If not, use the standard ones */ /* This is required for the MJPEG capture palette of USB devices */ - if ( cinfo->dc_huff_tbl_ptrs[0] == nullptr ) { - zm_use_std_huff_tables(cinfo); + if ( readjpg_dcinfo->dc_huff_tbl_ptrs[0] == nullptr ) { + zm_use_std_huff_tables(readjpg_dcinfo); } - new_width = cinfo->image_width; - new_height = cinfo->image_height; + new_width = readjpg_dcinfo->image_width; + new_height = readjpg_dcinfo->image_height; if ( (width != new_width) || (height != new_height) ) { Debug(9, "Image dimensions differ. Old: %ux%u New: %ux%u", width, height, new_width, new_height); @@ -983,7 +982,7 @@ bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsign switch ( p_colours ) { case ZM_COLOUR_GRAY8: - cinfo->out_color_space = JCS_GRAYSCALE; + readjpg_dcinfo->out_color_space = JCS_GRAYSCALE; new_colours = ZM_COLOUR_GRAY8; new_subpixelorder = ZM_SUBPIX_ORDER_NONE; break; @@ -991,17 +990,17 @@ bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsign #ifdef JCS_EXTENSIONS new_colours = ZM_COLOUR_RGB32; if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGRA ) { - cinfo->out_color_space = JCS_EXT_BGRX; + readjpg_dcinfo->out_color_space = JCS_EXT_BGRX; new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ARGB ) { - cinfo->out_color_space = JCS_EXT_XRGB; + readjpg_dcinfo->out_color_space = JCS_EXT_XRGB; new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ABGR ) { - cinfo->out_color_space = JCS_EXT_XBGR; + readjpg_dcinfo->out_color_space = JCS_EXT_XBGR; new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; } else { /* Assume RGBA */ - cinfo->out_color_space = JCS_EXT_RGBX; + readjpg_dcinfo->out_color_space = JCS_EXT_RGBX; new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; } break; @@ -1013,7 +1012,7 @@ bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsign new_colours = ZM_COLOUR_RGB24; if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGR ) { #ifdef JCS_EXTENSIONS - cinfo->out_color_space = JCS_EXT_BGR; + readjpg_dcinfo->out_color_space = JCS_EXT_BGR; new_subpixelorder = ZM_SUBPIX_ORDER_BGR; #else Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); @@ -1029,7 +1028,7 @@ cinfo->out_color_space = JCS_EXT_RGB; cinfo->out_color_space = JCS_RGB; #endif */ - cinfo->out_color_space = JCS_RGB; + readjpg_dcinfo->out_color_space = JCS_RGB; new_subpixelorder = ZM_SUBPIX_ORDER_RGB; } break; @@ -1037,20 +1036,20 @@ cinfo->out_color_space = JCS_RGB; if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr ) { Error("Failed requesting writeable buffer for reading JPEG image."); - jpeg_abort_decompress(cinfo); + jpeg_abort_decompress(readjpg_dcinfo); fclose(infile); return false; } - jpeg_start_decompress(cinfo); + jpeg_start_decompress(readjpg_dcinfo); JSAMPROW row_pointer = buffer; - while ( cinfo->output_scanline < cinfo->output_height ) { - jpeg_read_scanlines(cinfo, &row_pointer, 1); + while ( readjpg_dcinfo->output_scanline < readjpg_dcinfo->output_height ) { + jpeg_read_scanlines(readjpg_dcinfo, &row_pointer, 1); row_pointer += linesize; } - jpeg_finish_decompress(cinfo); + jpeg_finish_decompress(readjpg_dcinfo); fclose(infile); @@ -1078,7 +1077,7 @@ bool Image::WriteJpeg(const std::string &filename, int quality_override, SystemT } bool Image::WriteJpeg(const std::string &filename, - int quality_override, + const int &quality_override, SystemTimePoint timestamp, bool on_blocking_abort) const { if ( config.colour_jpeg_files && (colours == ZM_COLOUR_GRAY8) ) { @@ -1247,39 +1246,38 @@ bool Image::DecodeJpeg( unsigned int p_subpixelorder) { unsigned int new_width, new_height, new_colours, new_subpixelorder; - struct jpeg_decompress_struct *cinfo = decodejpg_dcinfo; - if ( !cinfo ) { - cinfo = decodejpg_dcinfo = new jpeg_decompress_struct; - cinfo->err = jpeg_std_error( &jpg_err.pub ); + if ( !decodejpg_dcinfo ) { + decodejpg_dcinfo = new jpeg_decompress_struct; + decodejpg_dcinfo->err = jpeg_std_error( &jpg_err.pub ); jpg_err.pub.error_exit = zm_jpeg_error_exit; jpg_err.pub.emit_message = zm_jpeg_emit_message; - jpeg_create_decompress( cinfo ); + jpeg_create_decompress( decodejpg_dcinfo ); } if ( setjmp(jpg_err.setjmp_buffer) ) { - jpeg_abort_decompress(cinfo); + jpeg_abort_decompress(decodejpg_dcinfo); return false; } - zm_jpeg_mem_src(cinfo, inbuffer, inbuffer_size); + zm_jpeg_mem_src(decodejpg_dcinfo, inbuffer, inbuffer_size); - jpeg_read_header(cinfo, TRUE); + jpeg_read_header(decodejpg_dcinfo, TRUE); - if ( (cinfo->num_components != 1) && (cinfo->num_components != 3) ) { + if ( (decodejpg_dcinfo->num_components != 1) && (decodejpg_dcinfo->num_components != 3) ) { Error("Unexpected colours when reading jpeg image: %d", colours); - jpeg_abort_decompress(cinfo); + jpeg_abort_decompress(decodejpg_dcinfo); return false; } /* Check if the image has at least one huffman table defined. If not, use the standard ones */ /* This is required for the MJPEG capture palette of USB devices */ - if ( cinfo->dc_huff_tbl_ptrs[0] == nullptr ) { - zm_use_std_huff_tables(cinfo); + if ( decodejpg_dcinfo->dc_huff_tbl_ptrs[0] == nullptr ) { + zm_use_std_huff_tables(decodejpg_dcinfo); } - new_width = cinfo->image_width; - new_height = cinfo->image_height; + new_width = decodejpg_dcinfo->image_width; + new_height = decodejpg_dcinfo->image_height; if ( (width != new_width) || (height != new_height) ) { Debug(9, "Image dimensions differ. Old: %ux%u New: %ux%u", @@ -1288,7 +1286,7 @@ bool Image::DecodeJpeg( switch (p_colours) { case ZM_COLOUR_GRAY8: - cinfo->out_color_space = JCS_GRAYSCALE; + decodejpg_dcinfo->out_color_space = JCS_GRAYSCALE; new_colours = ZM_COLOUR_GRAY8; new_subpixelorder = ZM_SUBPIX_ORDER_NONE; break; @@ -1296,17 +1294,17 @@ bool Image::DecodeJpeg( #ifdef JCS_EXTENSIONS new_colours = ZM_COLOUR_RGB32; if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGRA ) { - cinfo->out_color_space = JCS_EXT_BGRX; + decodejpg_dcinfo->out_color_space = JCS_EXT_BGRX; new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ARGB ) { - cinfo->out_color_space = JCS_EXT_XRGB; + decodejpg_dcinfo->out_color_space = JCS_EXT_XRGB; new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ABGR ) { - cinfo->out_color_space = JCS_EXT_XBGR; + decodejpg_dcinfo->out_color_space = JCS_EXT_XBGR; new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; } else { /* Assume RGBA */ - cinfo->out_color_space = JCS_EXT_RGBX; + decodejpg_dcinfo->out_color_space = JCS_EXT_RGBX; new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; } break; @@ -1318,7 +1316,7 @@ bool Image::DecodeJpeg( new_colours = ZM_COLOUR_RGB24; if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGR ) { #ifdef JCS_EXTENSIONS - cinfo->out_color_space = JCS_EXT_BGR; + decodejpg_dcinfo->out_color_space = JCS_EXT_BGR; new_subpixelorder = ZM_SUBPIX_ORDER_BGR; #else Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); @@ -1334,7 +1332,7 @@ cinfo->out_color_space = JCS_EXT_RGB; cinfo->out_color_space = JCS_RGB; #endif */ - cinfo->out_color_space = JCS_RGB; + decodejpg_dcinfo->out_color_space = JCS_RGB; new_subpixelorder = ZM_SUBPIX_ORDER_RGB; } break; @@ -1342,19 +1340,19 @@ cinfo->out_color_space = JCS_RGB; if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr ) { Error("Failed requesting writeable buffer for reading JPEG image."); - jpeg_abort_decompress(cinfo); + jpeg_abort_decompress(decodejpg_dcinfo); return false; } - jpeg_start_decompress(cinfo); + jpeg_start_decompress(decodejpg_dcinfo); JSAMPROW row_pointer = buffer; /* pointer to a single row */ - while ( cinfo->output_scanline < cinfo->output_height ) { - jpeg_read_scanlines(cinfo, &row_pointer, 1); + while ( decodejpg_dcinfo->output_scanline < decodejpg_dcinfo->output_height ) { + jpeg_read_scanlines(decodejpg_dcinfo, &row_pointer, 1); row_pointer += linesize; } - jpeg_finish_decompress(cinfo); + jpeg_finish_decompress(decodejpg_dcinfo); return true; } diff --git a/src/zm_image.h b/src/zm_image.h index 7778747e4..ccbae9f86 100644 --- a/src/zm_image.h +++ b/src/zm_image.h @@ -241,7 +241,7 @@ class Image { bool WriteJpeg(const std::string &filename, SystemTimePoint timestamp) const; bool WriteJpeg(const std::string &filename, int quality_override, SystemTimePoint timestamp) const; bool WriteJpeg(const std::string &filename, - int quality_override, + const int &quality_override, SystemTimePoint timestamp, bool on_blocking_abort) const; From a4ebf533a93e8834b24455541a48735a6dcbf20e Mon Sep 17 00:00:00 2001 From: Peter Keresztes Schmidt Date: Sun, 12 Sep 2021 11:38:44 +0200 Subject: [PATCH 021/174] Image: Codestyle changes --- src/zm_image.cpp | 304 +++++++++++++++++++++++------------------------ 1 file changed, 151 insertions(+), 153 deletions(-) diff --git a/src/zm_image.cpp b/src/zm_image.cpp index f0d94a542..09c05550e 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -936,7 +936,7 @@ bool Image::WriteRaw(const char *filename) const { bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsigned int p_subpixelorder) { unsigned int new_width, new_height, new_colours, new_subpixelorder; - if ( !readjpg_dcinfo ) { + if (!readjpg_dcinfo) { readjpg_dcinfo = new jpeg_decompress_struct; readjpg_dcinfo->err = jpeg_std_error(&jpg_err.pub); jpg_err.pub.error_exit = zm_jpeg_error_exit; @@ -945,12 +945,12 @@ bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsign } FILE *infile; - if ( (infile = fopen(filename.c_str(), "rb")) == nullptr ) { + if ((infile = fopen(filename.c_str(), "rb")) == nullptr) { Error("Can't open %s: %s", filename.c_str(), strerror(errno)); return false; } - if ( setjmp(jpg_err.setjmp_buffer) ) { + if (setjmp(jpg_err.setjmp_buffer)) { jpeg_abort_decompress(readjpg_dcinfo); fclose(infile); return false; @@ -958,9 +958,9 @@ bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsign jpeg_stdio_src(readjpg_dcinfo, infile); - jpeg_read_header(readjpg_dcinfo, TRUE); + jpeg_read_header(readjpg_dcinfo, true); - if ( (readjpg_dcinfo->num_components != 1) && (readjpg_dcinfo->num_components != 3) ) { + if ((readjpg_dcinfo->num_components != 1) && (readjpg_dcinfo->num_components != 3)) { Error("Unexpected colours when reading jpeg image: %d", colours); jpeg_abort_decompress(readjpg_dcinfo); fclose(infile); @@ -969,72 +969,72 @@ bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsign /* Check if the image has at least one huffman table defined. If not, use the standard ones */ /* This is required for the MJPEG capture palette of USB devices */ - if ( readjpg_dcinfo->dc_huff_tbl_ptrs[0] == nullptr ) { + if (readjpg_dcinfo->dc_huff_tbl_ptrs[0] == nullptr) { zm_use_std_huff_tables(readjpg_dcinfo); } new_width = readjpg_dcinfo->image_width; new_height = readjpg_dcinfo->image_height; - if ( (width != new_width) || (height != new_height) ) { + if ((width != new_width) || (height != new_height)) { Debug(9, "Image dimensions differ. Old: %ux%u New: %ux%u", width, height, new_width, new_height); } - switch ( p_colours ) { + switch (p_colours) { case ZM_COLOUR_GRAY8: - readjpg_dcinfo->out_color_space = JCS_GRAYSCALE; - new_colours = ZM_COLOUR_GRAY8; - new_subpixelorder = ZM_SUBPIX_ORDER_NONE; - break; + readjpg_dcinfo->out_color_space = JCS_GRAYSCALE; + new_colours = ZM_COLOUR_GRAY8; + new_subpixelorder = ZM_SUBPIX_ORDER_NONE; + break; case ZM_COLOUR_RGB32: #ifdef JCS_EXTENSIONS - new_colours = ZM_COLOUR_RGB32; - if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGRA ) { - readjpg_dcinfo->out_color_space = JCS_EXT_BGRX; - new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; - } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ARGB ) { - readjpg_dcinfo->out_color_space = JCS_EXT_XRGB; - new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; - } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ABGR ) { - readjpg_dcinfo->out_color_space = JCS_EXT_XBGR; - new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; - } else { - /* Assume RGBA */ - readjpg_dcinfo->out_color_space = JCS_EXT_RGBX; - new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; - } - break; + new_colours = ZM_COLOUR_RGB32; + if (p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + readjpg_dcinfo->out_color_space = JCS_EXT_BGRX; + new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; + } else if (p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + readjpg_dcinfo->out_color_space = JCS_EXT_XRGB; + new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; + } else if (p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + readjpg_dcinfo->out_color_space = JCS_EXT_XBGR; + new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; + } else { + /* Assume RGBA */ + readjpg_dcinfo->out_color_space = JCS_EXT_RGBX; + new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; + } + break; #else - Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead."); + Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead."); #endif case ZM_COLOUR_RGB24: default: - new_colours = ZM_COLOUR_RGB24; - if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGR ) { + new_colours = ZM_COLOUR_RGB24; + if (p_subpixelorder == ZM_SUBPIX_ORDER_BGR) { #ifdef JCS_EXTENSIONS - readjpg_dcinfo->out_color_space = JCS_EXT_BGR; - new_subpixelorder = ZM_SUBPIX_ORDER_BGR; + readjpg_dcinfo->out_color_space = JCS_EXT_BGR; + new_subpixelorder = ZM_SUBPIX_ORDER_BGR; #else - Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); - cinfo->out_color_space = JCS_RGB; - new_subpixelorder = ZM_SUBPIX_ORDER_RGB; + Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); + cinfo->out_color_space = JCS_RGB; + new_subpixelorder = ZM_SUBPIX_ORDER_RGB; #endif - } else { - /* Assume RGB */ - /* + } else { + /* Assume RGB */ + /* #ifdef JCS_EXTENSIONS cinfo->out_color_space = JCS_EXT_RGB; #else cinfo->out_color_space = JCS_RGB; #endif - */ - readjpg_dcinfo->out_color_space = JCS_RGB; - new_subpixelorder = ZM_SUBPIX_ORDER_RGB; - } - break; + */ + readjpg_dcinfo->out_color_space = JCS_RGB; + new_subpixelorder = ZM_SUBPIX_ORDER_RGB; + } + break; } // end switch p_colours - if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr ) { + if (WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr) { Error("Failed requesting writeable buffer for reading JPEG image."); jpeg_abort_decompress(readjpg_dcinfo); fclose(infile); @@ -1044,13 +1044,12 @@ cinfo->out_color_space = JCS_RGB; jpeg_start_decompress(readjpg_dcinfo); JSAMPROW row_pointer = buffer; - while ( readjpg_dcinfo->output_scanline < readjpg_dcinfo->output_height ) { + while (readjpg_dcinfo->output_scanline < readjpg_dcinfo->output_height) { jpeg_read_scanlines(readjpg_dcinfo, &row_pointer, 1); row_pointer += linesize; } jpeg_finish_decompress(readjpg_dcinfo); - fclose(infile); return true; @@ -1080,34 +1079,37 @@ bool Image::WriteJpeg(const std::string &filename, const int &quality_override, SystemTimePoint timestamp, bool on_blocking_abort) const { - if ( config.colour_jpeg_files && (colours == ZM_COLOUR_GRAY8) ) { + if (config.colour_jpeg_files && (colours == ZM_COLOUR_GRAY8)) { Image temp_image(*this); temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB); return temp_image.WriteJpeg(filename, quality_override, timestamp, on_blocking_abort); } int quality = quality_override ? quality_override : config.jpeg_file_quality; - struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality]; + jpeg_compress_struct *cinfo = writejpg_ccinfo[quality]; FILE *outfile = nullptr; int raw_fd = 0; - if ( !cinfo ) { + if (!cinfo) { cinfo = writejpg_ccinfo[quality] = new jpeg_compress_struct; cinfo->err = jpeg_std_error(&jpg_err.pub); jpeg_create_compress(cinfo); } - if ( !on_blocking_abort ) { + if (!on_blocking_abort) { jpg_err.pub.error_exit = zm_jpeg_error_exit; jpg_err.pub.emit_message = zm_jpeg_emit_message; } else { jpg_err.pub.error_exit = zm_jpeg_error_silent; jpg_err.pub.emit_message = zm_jpeg_emit_silence; - if ( setjmp(jpg_err.setjmp_buffer) ) { + if (setjmp(jpg_err.setjmp_buffer)) { jpeg_abort_compress(cinfo); - Debug(1, "Aborted a write mid-stream and %s and %d", (outfile == nullptr) ? "closing file" : "file not opened", raw_fd); - if ( raw_fd ) + Debug(1, + "Aborted a write mid-stream and %s and %d", + (outfile == nullptr) ? "closing file" : "file not opened", + raw_fd); + if (raw_fd) close(raw_fd); - if ( outfile ) + if (outfile) fclose(outfile); return false; } @@ -1134,58 +1136,58 @@ bool Image::WriteJpeg(const std::string &filename, cinfo->image_width = width; /* image width and height, in pixels */ cinfo->image_height = height; - switch ( colours ) { + switch (colours) { case ZM_COLOUR_GRAY8: - cinfo->input_components = 1; - cinfo->in_color_space = JCS_GRAYSCALE; - break; + cinfo->input_components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + break; case ZM_COLOUR_RGB32: #ifdef JCS_EXTENSIONS - cinfo->input_components = 4; - if ( subpixelorder == ZM_SUBPIX_ORDER_RGBA ) { - cinfo->in_color_space = JCS_EXT_RGBX; - } else if ( subpixelorder == ZM_SUBPIX_ORDER_BGRA ) { - cinfo->in_color_space = JCS_EXT_BGRX; - } else if ( subpixelorder == ZM_SUBPIX_ORDER_ARGB ) { - cinfo->in_color_space = JCS_EXT_XRGB; - } else if ( subpixelorder == ZM_SUBPIX_ORDER_ABGR ) { - cinfo->in_color_space = JCS_EXT_XBGR; - } else { - Warning("Unknwon subpixelorder %d", subpixelorder); - /* Assume RGBA */ - cinfo->in_color_space = JCS_EXT_RGBX; - } - break; + cinfo->input_components = 4; + if (subpixelorder == ZM_SUBPIX_ORDER_RGBA) { + cinfo->in_color_space = JCS_EXT_RGBX; + } else if (subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + cinfo->in_color_space = JCS_EXT_BGRX; + } else if (subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + cinfo->in_color_space = JCS_EXT_XRGB; + } else if (subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + cinfo->in_color_space = JCS_EXT_XBGR; + } else { + Warning("Unknwon subpixelorder %d", subpixelorder); + /* Assume RGBA */ + cinfo->in_color_space = JCS_EXT_RGBX; + } + break; #else - Error("libjpeg-turbo is required for JPEG encoding directly from RGB32 source"); + Error("libjpeg-turbo is required for JPEG encoding directly from RGB32 source"); + jpeg_abort_compress(cinfo); + fclose(outfile); + return false; +#endif + case ZM_COLOUR_RGB24: + default: + cinfo->input_components = 3; + if (subpixelorder == ZM_SUBPIX_ORDER_BGR) { +#ifdef JCS_EXTENSIONS + cinfo->in_color_space = JCS_EXT_BGR; +#else + Error("libjpeg-turbo is required for JPEG encoding directly from BGR24 source"); jpeg_abort_compress(cinfo); fclose(outfile); return false; #endif - case ZM_COLOUR_RGB24: - default: - cinfo->input_components = 3; - if ( subpixelorder == ZM_SUBPIX_ORDER_BGR) { -#ifdef JCS_EXTENSIONS - cinfo->in_color_space = JCS_EXT_BGR; -#else - Error("libjpeg-turbo is required for JPEG encoding directly from BGR24 source"); - jpeg_abort_compress(cinfo); - fclose(outfile); - return false; -#endif - } else { - /* Assume RGB */ - /* + } else { + /* Assume RGB */ + /* #ifdef JCS_EXTENSIONS cinfo->out_color_space = JCS_EXT_RGB; #else cinfo->out_color_space = JCS_RGB; #endif */ - cinfo->in_color_space = JCS_RGB; - } - break; + cinfo->in_color_space = JCS_RGB; + } + break; } // end switch(colours) jpeg_set_defaults(cinfo); @@ -1193,7 +1195,7 @@ cinfo->out_color_space = JCS_RGB; cinfo->dct_method = JDCT_FASTEST; jpeg_start_compress(cinfo, TRUE); - if ( config.add_jpeg_comments && !annotation_.empty() ) { + if (config.add_jpeg_comments && !annotation_.empty()) { jpeg_write_marker(cinfo, JPEG_COM, reinterpret_cast(annotation_.c_str()), annotation_.size()); } // If we have a non-zero time (meaning a parameter was passed in), then form a simple exif segment with that time as DateTimeOriginal and SubsecTimeOriginal @@ -1217,19 +1219,19 @@ cinfo->out_color_space = JCS_RGB; snprintf(msbuf, sizeof msbuf, "%06d", static_cast(ts_usec.count())); unsigned char exiftimes[82] = { - 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x69, 0x87, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x03, 0x90, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x91, 0x92, - 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00 }; - memcpy(&exiftimes[EXIFTIMES_OFFSET], timebuf,EXIFTIMES_LEN); + 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x69, 0x87, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x03, 0x90, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x91, 0x92, + 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00}; + memcpy(&exiftimes[EXIFTIMES_OFFSET], timebuf, EXIFTIMES_LEN); memcpy(&exiftimes[EXIFTIMES_MS_OFFSET], msbuf, EXIFTIMES_MS_LEN); - jpeg_write_marker(cinfo, EXIF_CODE, (const JOCTET *)exiftimes, sizeof(exiftimes)); + jpeg_write_marker(cinfo, EXIF_CODE, (const JOCTET *) exiftimes, sizeof(exiftimes)); } JSAMPROW row_pointer = buffer; /* pointer to a single row */ - while ( cinfo->next_scanline < cinfo->image_height ) { + while (cinfo->next_scanline < cinfo->image_height) { jpeg_write_scanlines(cinfo, &row_pointer, 1); row_pointer += linesize; } @@ -1239,23 +1241,19 @@ cinfo->out_color_space = JCS_RGB; return true; } -bool Image::DecodeJpeg( - const JOCTET *inbuffer, - int inbuffer_size, - unsigned int p_colours, - unsigned int p_subpixelorder) +bool Image::DecodeJpeg(const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder) { unsigned int new_width, new_height, new_colours, new_subpixelorder; - if ( !decodejpg_dcinfo ) { + if (!decodejpg_dcinfo) { decodejpg_dcinfo = new jpeg_decompress_struct; - decodejpg_dcinfo->err = jpeg_std_error( &jpg_err.pub ); + decodejpg_dcinfo->err = jpeg_std_error(&jpg_err.pub); jpg_err.pub.error_exit = zm_jpeg_error_exit; jpg_err.pub.emit_message = zm_jpeg_emit_message; - jpeg_create_decompress( decodejpg_dcinfo ); + jpeg_create_decompress(decodejpg_dcinfo); } - if ( setjmp(jpg_err.setjmp_buffer) ) { + if (setjmp(jpg_err.setjmp_buffer)) { jpeg_abort_decompress(decodejpg_dcinfo); return false; } @@ -1264,7 +1262,7 @@ bool Image::DecodeJpeg( jpeg_read_header(decodejpg_dcinfo, TRUE); - if ( (decodejpg_dcinfo->num_components != 1) && (decodejpg_dcinfo->num_components != 3) ) { + if ((decodejpg_dcinfo->num_components != 1) && (decodejpg_dcinfo->num_components != 3)) { Error("Unexpected colours when reading jpeg image: %d", colours); jpeg_abort_decompress(decodejpg_dcinfo); return false; @@ -1272,73 +1270,73 @@ bool Image::DecodeJpeg( /* Check if the image has at least one huffman table defined. If not, use the standard ones */ /* This is required for the MJPEG capture palette of USB devices */ - if ( decodejpg_dcinfo->dc_huff_tbl_ptrs[0] == nullptr ) { + if (decodejpg_dcinfo->dc_huff_tbl_ptrs[0] == nullptr) { zm_use_std_huff_tables(decodejpg_dcinfo); } new_width = decodejpg_dcinfo->image_width; new_height = decodejpg_dcinfo->image_height; - if ( (width != new_width) || (height != new_height) ) { + if ((width != new_width) || (height != new_height)) { Debug(9, "Image dimensions differ. Old: %ux%u New: %ux%u", - width, height, new_width, new_height); + width, height, new_width, new_height); } switch (p_colours) { case ZM_COLOUR_GRAY8: decodejpg_dcinfo->out_color_space = JCS_GRAYSCALE; - new_colours = ZM_COLOUR_GRAY8; - new_subpixelorder = ZM_SUBPIX_ORDER_NONE; - break; + new_colours = ZM_COLOUR_GRAY8; + new_subpixelorder = ZM_SUBPIX_ORDER_NONE; + break; case ZM_COLOUR_RGB32: #ifdef JCS_EXTENSIONS - new_colours = ZM_COLOUR_RGB32; - if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGRA ) { - decodejpg_dcinfo->out_color_space = JCS_EXT_BGRX; - new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; - } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ARGB ) { - decodejpg_dcinfo->out_color_space = JCS_EXT_XRGB; - new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; - } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ABGR ) { - decodejpg_dcinfo->out_color_space = JCS_EXT_XBGR; - new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; - } else { - /* Assume RGBA */ - decodejpg_dcinfo->out_color_space = JCS_EXT_RGBX; - new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; - } - break; + new_colours = ZM_COLOUR_RGB32; + if (p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + decodejpg_dcinfo->out_color_space = JCS_EXT_BGRX; + new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; + } else if (p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + decodejpg_dcinfo->out_color_space = JCS_EXT_XRGB; + new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; + } else if (p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + decodejpg_dcinfo->out_color_space = JCS_EXT_XBGR; + new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; + } else { + /* Assume RGBA */ + decodejpg_dcinfo->out_color_space = JCS_EXT_RGBX; + new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; + } + break; #else - Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead."); + Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead."); #endif case ZM_COLOUR_RGB24: default: - new_colours = ZM_COLOUR_RGB24; - if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGR ) { + new_colours = ZM_COLOUR_RGB24; + if (p_subpixelorder == ZM_SUBPIX_ORDER_BGR) { #ifdef JCS_EXTENSIONS - decodejpg_dcinfo->out_color_space = JCS_EXT_BGR; - new_subpixelorder = ZM_SUBPIX_ORDER_BGR; + decodejpg_dcinfo->out_color_space = JCS_EXT_BGR; + new_subpixelorder = ZM_SUBPIX_ORDER_BGR; #else - Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); - cinfo->out_color_space = JCS_RGB; - new_subpixelorder = ZM_SUBPIX_ORDER_RGB; + Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); + cinfo->out_color_space = JCS_RGB; + new_subpixelorder = ZM_SUBPIX_ORDER_RGB; #endif - } else { - /* Assume RGB */ - /* + } else { + /* Assume RGB */ + /* #ifdef JCS_EXTENSIONS cinfo->out_color_space = JCS_EXT_RGB; #else cinfo->out_color_space = JCS_RGB; #endif - */ - decodejpg_dcinfo->out_color_space = JCS_RGB; - new_subpixelorder = ZM_SUBPIX_ORDER_RGB; - } - break; + */ + decodejpg_dcinfo->out_color_space = JCS_RGB; + new_subpixelorder = ZM_SUBPIX_ORDER_RGB; + } + break; } // end switch - if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr ) { + if (WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr) { Error("Failed requesting writeable buffer for reading JPEG image."); jpeg_abort_decompress(decodejpg_dcinfo); return false; @@ -1347,7 +1345,7 @@ cinfo->out_color_space = JCS_RGB; jpeg_start_decompress(decodejpg_dcinfo); JSAMPROW row_pointer = buffer; /* pointer to a single row */ - while ( decodejpg_dcinfo->output_scanline < decodejpg_dcinfo->output_height ) { + while (decodejpg_dcinfo->output_scanline < decodejpg_dcinfo->output_height) { jpeg_read_scanlines(decodejpg_dcinfo, &row_pointer, 1); row_pointer += linesize; } From 4b4152b837f07eba1bcb0ce0dfadc23546d6c6f2 Mon Sep 17 00:00:00 2001 From: Andrea Vezzali Date: Mon, 13 Sep 2021 13:28:48 +0200 Subject: [PATCH 022/174] Update it_it translation (#3350) --- web/lang/it_it.php | 274 ++++++++++++++++++++++----------------------- 1 file changed, 137 insertions(+), 137 deletions(-) diff --git a/web/lang/it_it.php b/web/lang/it_it.php index 62e881d45..b51b85300 100644 --- a/web/lang/it_it.php +++ b/web/lang/it_it.php @@ -98,8 +98,8 @@ $SLANG = array( 'AlarmRefImageBlendPct'=> 'Alarm Reference Image Blend %ge', // Added - 2015-04-18 'Alert' => 'Attenzione', 'All' => 'Tutto', - 'AnalysisFPS' => 'Analysis FPS', // Added - 2015-07-22 - 'AnalysisUpdateDelay' => 'Analysis Update Delay', // Added - 2015-07-23 + 'AnalysisFPS' => 'Analisi FPS', // Added - 2015-07-22 + 'AnalysisUpdateDelay' => 'Intervallo aggiornamento analisi', // Added - 2015-07-23 'Apply' => 'Applica', 'ApplyingStateChange' => 'Sto applicando le modifiche', 'ArchArchived' => 'Archiviato', @@ -112,31 +112,31 @@ $SLANG = array( 'AttrArchiveStatus' => 'Stato Archivio', 'AttrAvgScore' => 'Punteggio medio', 'AttrCause' => 'Causa', - 'AttrDiskBlocks' => 'Blocchi del Disco', - 'AttrDiskPercent' => 'Percentuale del Disco', - 'AttrDiskSpace' => 'Disk Space', // Added - 2018-08-30 + 'AttrDiskBlocks' => 'Blocchi disco', + 'AttrDiskPercent' => 'Percentuale disco', + 'AttrDiskSpace' => 'Spazio disco', // Added - 2018-08-30 'AttrDuration' => 'Durata', 'AttrEndDate' => 'End Date', // Added - 2018-08-30 'AttrEndDateTime' => 'End Date/Time', // Added - 2018-08-30 'AttrEndTime' => 'End Time', // Added - 2018-08-30 'AttrEndWeekday' => 'End Weekday', // Added - 2018-08-30 - 'AttrFilterServer' => 'Server Filter is Running On', // Added - 2018-08-30 + 'AttrFilterServer' => 'Filtro attivo su Server', // Added - 2018-08-30 'AttrFrames' => 'Immagini', 'AttrId' => 'Id', 'AttrMaxScore' => 'Punteggio massimo', 'AttrMonitorId' => 'Id Monitor', 'AttrMonitorName' => 'Nome Monitor', - 'AttrMonitorServer' => 'Server Monitor is Running On', // Added - 2018-08-30 + 'AttrMonitorServer' => 'Monitor attivo su Server', // Added - 2018-08-30 'AttrName' => 'Nome', 'AttrNotes' => 'Note', - 'AttrStartDate' => 'Start Date', // Added - 2018-08-30 - 'AttrStartDateTime' => 'Start Date/Time', // Added - 2018-08-30 - 'AttrStartTime' => 'Start Time', // Added - 2018-08-30 - 'AttrStartWeekday' => 'Start Weekday', // Added - 2018-08-30 - 'AttrStateId' => 'Run State', // Added - 2018-08-30 - 'AttrStorageArea' => 'Storage Area', // Added - 2018-08-30 - 'AttrStorageServer' => 'Server Hosting Storage', // Added - 2018-08-30 - 'AttrSystemLoad' => 'System Load', + 'AttrStartDate' => 'Inizio - Data', // Added - 2018-08-30 + 'AttrStartDateTime' => 'Inizio - Data/orario', // Added - 2018-08-30 + 'AttrStartTime' => 'Inizio - Orario', // Added - 2018-08-30 + 'AttrStartWeekday' => 'Inizio - Giorno della settimana', // Added - 2018-08-30 + 'AttrStateId' => 'Stato esecuzione', // Added - 2018-08-30 + 'AttrStorageArea' => 'Area Salvataggio', // Added - 2018-08-30 + 'AttrStorageServer' => 'Server Salvataggio remoto', // Added - 2018-08-30 + 'AttrSystemLoad' => 'Carico di sistema', 'AttrTotalScore' => 'Punteggio totale', 'Auto' => 'Auto', 'AutoStopTimeout' => 'Auto Stop Timeout', @@ -181,56 +181,56 @@ $SLANG = array( 'BlobPx' => 'Blob Px', 'BlobSizes' => 'Dimensioni Blob', 'Blobs' => 'Blobs', - 'Brightness' => 'Luminosità', + 'Brightness' => 'Luminosità;', 'Buffer' => 'Buffer', // Added - 2015-04-18 'Buffers' => 'Buffers', 'CSSDescription' => 'Change the default css for this computer', // Added - 2015-04-18 - 'CanAutoFocus' => 'Puo\' Auto Focus', - 'CanAutoGain' => 'Puo\' Auto Gains', - 'CanAutoIris' => 'Puo\' Auto Iris', - 'CanAutoWhite' => 'Puo\' Auto bil bianco', - 'CanAutoZoom' => 'Puo\' Auto Zoom', - 'CanFocus' => 'Puo\' Fuoco', - 'CanFocusAbs' => 'Puo\' Fuoco Assoluto', - 'CanFocusCon' => 'Puo\' Fuoco Continuo ', - 'CanFocusRel' => 'Puo\' Fuoco Relativo', - 'CanGain' => 'Puo\' Gain ', - 'CanGainAbs' => 'Puo\' Gain Assoluto', - 'CanGainCon' => 'Puo\' Gain Continuo ', - 'CanGainRel' => 'Puo\' Gain Relativo', - 'CanIris' => 'Puo\' Iris', - 'CanIrisAbs' => 'Puo\' Iris Assoluto', - 'CanIrisCon' => 'Puo\' Iris Continuo ', - 'CanIrisRel' => 'Puo\' Iris Relativo', - 'CanMove' => 'Puo\' Mov.', - 'CanMoveAbs' => 'Puo\' Mov. Assoluto', - 'CanMoveCon' => 'Puo\' Mov. Continuo ', - 'CanMoveDiag' => 'Puo\' Mov. Diagonale ', - 'CanMoveMap' => 'Puo\' Mov Mappato', - 'CanMoveRel' => 'Puo\' Mov. Relativo', - 'CanPan' => 'Puo\' Pan' , - 'CanReset' => 'Puo\' Reset', - 'CanReboot' => 'Can Reboot', - 'CanSetPresets' => 'Puo\' impostare preset', - 'CanSleep' => 'Puo\' andare in sleep', - 'CanTilt' => 'Puo\' Tilt', - 'CanWake' => 'Puo\' essere riattivato', - 'CanWhite' => 'Puo\' bilanciare il bianco', - 'CanWhiteAbs' => 'Puo\' bilanciare il bianco assoluto', - 'CanWhiteBal' => 'Puo\' bilanciare il bianco', - 'CanWhiteCon' => 'Puo\' bilanciare il bianco Continuo', - 'CanWhiteRel' => 'Puo\' bilanciare il bianco Relativo', - 'CanZoom' => 'Puo\' Zoom', - 'CanZoomAbs' => 'Puo\' Zoom Assoluto', - 'CanZoomCon' => 'Puo\' Zoom Continuo', - 'CanZoomRel' => 'Puo\' Zoom Relativo', + 'CanAutoFocus' => 'Può Auto Focus', + 'CanAutoGain' => 'Può Auto Gains', + 'CanAutoIris' => 'Può Auto Iris', + 'CanAutoWhite' => 'Può Auto bil bianco', + 'CanAutoZoom' => 'Può Auto Zoom', + 'CanFocus' => 'Può Fuoco', + 'CanFocusAbs' => 'Può Fuoco Assoluto', + 'CanFocusCon' => 'Può Fuoco Continuo ', + 'CanFocusRel' => 'Può Fuoco Relativo', + 'CanGain' => 'Può Gain ', + 'CanGainAbs' => 'Può Gain Assoluto', + 'CanGainCon' => 'Può Gain Continuo ', + 'CanGainRel' => 'Può Gain Relativo', + 'CanIris' => 'Può Iris', + 'CanIrisAbs' => 'Può Iris Assoluto', + 'CanIrisCon' => 'Può Iris Continuo ', + 'CanIrisRel' => 'Può Iris Relativo', + 'CanMove' => 'Può Mov.', + 'CanMoveAbs' => 'Può Mov. Assoluto', + 'CanMoveCon' => 'Può Mov. Continuo ', + 'CanMoveDiag' => 'Può Mov. Diagonale ', + 'CanMoveMap' => 'Può Mov Mappato', + 'CanMoveRel' => 'Può Mov. Relativo', + 'CanPan' => 'Può Pan' , + 'CanReset' => 'Può Reset', + 'CanReboot' => 'Può Riavviare', + 'CanSetPresets' => 'Può impostare preset', + 'CanSleep' => 'Può andare in sleep', + 'CanTilt' => 'Può Tilt', + 'CanWake' => 'Può essere riattivato', + 'CanWhite' => 'Può bilanciare il bianco', + 'CanWhiteAbs' => 'Può bilanciare il bianco assoluto', + 'CanWhiteBal' => 'Può bilanciare il bianco', + 'CanWhiteCon' => 'Può bilanciare il bianco Continuo', + 'CanWhiteRel' => 'Può bilanciare il bianco Relativo', + 'CanZoom' => 'Può Zoom', + 'CanZoomAbs' => 'Può Zoom Assoluto', + 'CanZoomCon' => 'Può Zoom Continuo', + 'CanZoomRel' => 'Può Zoom Relativo', 'Cancel' => 'Annulla', 'CancelForcedAlarm' => 'Annulla Allarme Forzato', - 'CaptureHeight' => 'Altezza img catturata', - 'CaptureMethod' => 'Metodo di cattura', // Added - 2009-02-08 - 'CapturePalette' => 'Paletta img catturata', - 'CaptureResolution' => 'Risoluzione di cattura', // Added - 2015-04-18 - 'CaptureWidth' => 'Larghezza img Catturata', + 'CaptureHeight' => 'Altezza Cattura Immagine', + 'CaptureMethod' => 'Metodo Cattura Immagine', // Added - 2009-02-08 + 'CapturePalette' => 'Tavolozza Cattura Immagine', + 'CaptureResolution' => 'Risoluzione Cattura Immagine', // Added - 2015-04-18 + 'CaptureWidth' => 'Larghezza Cattura Immagine', 'Cause' => 'Causa', 'CheckMethod' => 'Metodo di Controllo Allarme', 'ChooseDetectedCamera' => 'Scegli telecamera rilevata', // Added - 2009-03-31 @@ -244,7 +244,7 @@ $SLANG = array( 'Colour' => 'Colori', 'Command' => 'Comando', 'Component' => 'Component', // Added - 2011-06-16 - 'ConcurrentFilter' => 'Run filter concurrently', // Added - 2018-08-30 + 'ConcurrentFilter' => 'Esegui filtro contemporaneamente', // Added - 2018-08-30 'Config' => 'Configura', 'ConfiguredFor' => 'Configurato per', 'ConfirmDeleteEvents' => 'Sei sicuro di voler cancellare gli eventi selezionati', @@ -279,7 +279,7 @@ $SLANG = array( 'DeleteSavedFilter' => 'Elimina il filtro salvato', 'Description' => 'Descrizione', 'DetectedCameras' => 'Telecamere Rilevate', // Added - 2009-03-31 - 'DetectedProfiles' => 'Detected Profiles', // Added - 2015-04-18 + 'DetectedProfiles' => 'Profili Rilevati', // Added - 2015-04-18 'Device' => 'Periferica', // Added - 2009-02-08 'DeviceChannel' => 'Canale Periferica', 'DeviceFormat' => 'Formato', @@ -287,14 +287,14 @@ $SLANG = array( 'DevicePath' => 'Percorso Dispositivo', 'Devices' => 'Dispositivi', 'Dimensions' => 'Dimensioni', - 'DisableAlarms' => 'Disabil Allarme', + 'DisableAlarms' => 'Disabilita Allarme', 'Disk' => 'Utilizzo Disco', - 'Display' => 'Display', // Added - 2011-01-30 - 'Displaying' => 'Displaying', // Added - 2011-06-16 - 'DoNativeMotionDetection'=> 'Do Native Motion Detection', + 'Display' => 'Mostra', // Added - 2011-01-30 + 'Displaying' => 'Visualizzazione', // Added - 2011-06-16 + 'DoNativeMotionDetection'=> 'Attiva Motion Detection Nativo', 'Donate' => 'Donate,per favore', 'DonateAlready' => 'No, ho gia donato... ', - 'DonateEnticement' => 'Stai usando ZoneMinder da un po\' di tempo e spero che tu lo stia trovando utile per la sicurezza di casa tua o del tuo posto di lavoro..Anche se ZoneMinder e\' distribuito liberamente come software libero,costa soldi sia svilupparlo che supportarlo. Se preferisci che questo software continui ad avere supporto e sviluppo in futuro allora considera l\idea di fare una piccola donazione. Donare e\' ovviamente opzionale, ma apprezzato e puoi donare quanto vuoi,quel poco o tanto che tu desideri.

Se hai voglia per cortesia seleziona l\'opzione sotto o punta il tuo browser a https://zoneminder.com/donate/ .

Grazie per usare ZoneMinder e non dimenticare di visitare il forum in ZoneMinder.com se cerchi supporto o hai suggerimenti riguardo a come rendere migliore Zoneminder.', + 'DonateEnticement' => 'Stai usando ZoneMinder da un pò di tempo e spero che tu lo stia trovando utile per la sicurezza di casa tua o del tuo posto di lavoro..Anche se ZoneMinder e\' distribuito liberamente come software libero,costa soldi sia svilupparlo che supportarlo. Se preferisci che questo software continui ad avere supporto e sviluppo in futuro allora considera l\idea di fare una piccola donazione. Donare e\' ovviamente opzionale, ma apprezzato e puoi donare quanto vuoi,quel poco o tanto che tu desideri.

Se hai voglia per cortesia seleziona l\'opzione sotto o punta il tuo browser a https://zoneminder.com/donate/ .

Grazie per usare ZoneMinder e non dimenticare di visitare il forum in ZoneMinder.com se cerchi supporto o hai suggerimenti riguardo a come rendere migliore Zoneminder.', 'DonateRemindDay' => 'Non ancora, ricordamelo ancora tra 1 giorno', 'DonateRemindHour' => 'Non ancora, ricordamelo ancora tra 1 ora', 'DonateRemindMonth' => 'Non ancora, ricordamelo ancora tra 1 mese', @@ -325,24 +325,24 @@ $SLANG = array( 'Execute' => 'Esegui', 'Exif' => 'Includi dati EXIF nell\'immagine', // Added - 2018-08-30 'Export' => 'Esporta', - 'ExportDetails' => 'Esp. dettagli eventi', - 'ExportFailed' => 'Esp. Fallita ', - 'ExportFormat' => 'Formato File Esp. ', + 'ExportDetails' => 'Esporta dettagli eventi', + 'ExportFailed' => 'Esportazione Fallita ', + 'ExportFormat' => 'Formato File Esportazione', 'ExportFormatTar' => 'Tar', 'ExportFormatZip' => 'Zip', - 'ExportFrames' => 'Dettagli frame espo.', + 'ExportFrames' => 'Esporta dettagli immagini', 'ExportImageFiles' => 'Esporta le immagini', - 'ExportLog' => 'Export Log', // Added - 2011-06-17 - 'ExportMiscFiles' => 'Esporto Altri file (se presenti)', + 'ExportLog' => 'Esporta Log', // Added - 2011-06-17 + 'ExportMiscFiles' => 'Esporta Altri file (se presenti)', 'ExportOptions' => 'Opzioni Esportazione', - 'ExportSucceeded' => 'Export completata con successo', // Added - 2009-02-08 - 'ExportVideoFiles' => 'Esporto File Video (se presenti)', - 'Exporting' => 'In corso.', + 'ExportSucceeded' => 'Esportazione completata con successo', // Added - 2009-02-08 + 'ExportVideoFiles' => 'Esporta File Video (se presenti)', + 'Exporting' => 'In corso', 'FPS' => 'fps', 'FPSReportInterval' => 'Intervallo Report FPS', 'FTP' => 'FTP', 'Far' => 'Lontano', - 'FastForward' => 'Fast Forward', + 'FastForward' => 'Avanzamento veloce', 'Feed' => 'Feed', 'Ffmpeg' => 'Ffmpeg', // Added - 2009-02-08 'File' => 'File', @@ -351,7 +351,7 @@ $SLANG = array( 'FilterDeleteEvents' => 'Elimina gli eventi', 'FilterEmailEvents' => 'Invia dettagli via email', 'FilterExecuteEvents' => 'Esegui un comando', - 'FilterLog' => 'Filter log', // Added - 2015-04-18 + 'FilterLog' => 'Filtra log', // Added - 2015-04-18 'FilterMessageEvents' => 'Invia dettagli tramite messaggio', 'FilterMoveEvents' => 'Sposta tutti gli eventi', // Added - 2018-08-30 'FilterPx' => 'Px Filtro', @@ -388,19 +388,19 @@ $SLANG = array( 'Grey' => 'Grigio', 'Group' => 'Gruppo', 'Groups' => 'Gruppi', - 'HasFocusSpeed' => 'Ha velocita\' di focus', - 'HasGainSpeed' => 'Ha velocita\' di guadagno', + 'HasFocusSpeed' => 'Ha velocità di focus', + 'HasGainSpeed' => 'Ha velocità di guadagno', 'HasHomePreset' => 'Ha posizioni di present', - 'HasIrisSpeed' => 'Ha velocota\' di iris', - 'HasPanSpeed' => 'Ha velocita\' di Pan', + 'HasIrisSpeed' => 'Ha velocotà di iris', + 'HasPanSpeed' => 'Ha velocità di Pan', 'HasPresets' => 'Ha preset', - 'HasTiltSpeed' => 'Ha velocita\' di Tilt', + 'HasTiltSpeed' => 'Ha velocità di Tilt', 'HasTurboPan' => 'Ha il Turbo Pan', 'HasTurboTilt' => 'Ha il Turbo Tilt', - 'HasWhiteSpeed' => 'Ha velocita\' di bilanciamento del bianco', - 'HasZoomSpeed' => 'Ha velocita\' di zoom', + 'HasWhiteSpeed' => 'Ha velocità di bilanciamento del bianco', + 'HasZoomSpeed' => 'Ha velocità di zoom', 'High' => 'Alta', - 'HighBW' => 'Banda Alta', + 'HighBW' => 'Banda Alta', 'Home' => 'Home', 'Hostname' => 'Nome Host', // Added - 2018-08-30 'Hour' => 'Ora', @@ -445,31 +445,31 @@ $SLANG = array( 'Mark' => 'Seleziona', 'Max' => 'Massima', 'MaxBandwidth' => 'Banda Massima', - 'MaxBrScore' => 'Punteggio
Massimo', + 'MaxBrScore' => 'Punteggio Massimo', 'MaxFocusRange' => 'Massimo range del focus', - 'MaxFocusSpeed' => 'Massima velocita\' del focus', + 'MaxFocusSpeed' => 'Massima velocità del focus', 'MaxFocusStep' => 'Massimo step del focus', 'MaxGainRange' => 'Massimo range del guadagno', - 'MaxGainSpeed' => 'Massima velocita\' del guadagno', + 'MaxGainSpeed' => 'Massima velocità del guadagno', 'MaxGainStep' => 'Massimo step del guadagno', 'MaxIrisRange' => 'Massima range dell\'Iris', - 'MaxIrisSpeed' => 'Massima velocita\' dell\'Iris', + 'MaxIrisSpeed' => 'Massima velocità dell\'Iris', 'MaxIrisStep' => 'Massimo step dell\'Iris', 'MaxPanRange' => 'Massimo range del pan', - 'MaxPanSpeed' => 'Massima velocita\' del tilt', + 'MaxPanSpeed' => 'Massima velocità del tilt', 'MaxPanStep' => 'Massimo step del pan', 'MaxTiltRange' => 'Massimo range del tilt', - 'MaxTiltSpeed' => 'Massima velocita\' del tilt', + 'MaxTiltSpeed' => 'Massima velocità del tilt', 'MaxTiltStep' => 'Massimo passo del tilt', 'MaxWhiteRange' => 'Massimo range del bilanciamento del bianco', - 'MaxWhiteSpeed' => 'Massima velocita\' del bilanciamento del bianco', + 'MaxWhiteSpeed' => 'Massima velocità del bilanciamento del bianco', 'MaxWhiteStep' => 'Massimo Step del bilanciamento del bianco', 'MaxZoomRange' => 'Massimo range dello zoom', - 'MaxZoomSpeed' => 'Massima velocita\' dello zoom', + 'MaxZoomSpeed' => 'Massima velocità dello zoom', 'MaxZoomStep' => 'Massimo step dello zoom', 'MaximumFPS' => 'Massimi FPS', 'Medium' => 'Media', - 'MediumBW' => 'Banda Media', + 'MediumBW' => 'Larghezza Banda Media', 'Message' => 'Message', // Added - 2011-06-16 'MinAlarmAreaLtMax' => 'L\'area minima dell\'allarme deve essere minore di quella massima', 'MinAlarmAreaUnset' => 'Devi specificare il numero minimo di pixel per l\'allarme', @@ -482,47 +482,47 @@ $SLANG = array( 'MinFilterAreaUnset' => 'Devi specificare il numero minimo di pixel per il filtro', 'MinFilterLtMinAlarm' => 'L\'area minima di filtro deve essere minore o uguale dell\area minima di allarme', 'MinFocusRange' => 'Range minimo del Focus', - 'MinFocusSpeed' => 'Velocita\' minima del Focus', + 'MinFocusSpeed' => 'Velocità minima del Focus', 'MinFocusStep' => 'Minimo step del Focus', 'MinGainRange' => 'Minimo range del Guadagno', - 'MinGainSpeed' => 'Velocita\' minima del Guadagno', + 'MinGainSpeed' => 'Velocità minima del Guadagno', 'MinGainStep' => 'Step minimo del guadagno', 'MinIrisRange' => 'Range minimo dell\'Iris', - 'MinIrisSpeed' => 'Velocita\' minima dell\'Iris', + 'MinIrisSpeed' => 'Velocità minima dell\'Iris', 'MinIrisStep' => 'Step minimo dell\'Iris', 'MinPanRange' => 'Range minimo del pan', - 'MinPanSpeed' => 'Velocita\' minima del Pan', + 'MinPanSpeed' => 'Velocità minima del Pan', 'MinPanStep' => 'Step minimo del Pan', 'MinPixelThresLtMax' => 'I pixel minimi della soglia devono essere minori dei pixel massimi della soglia', 'MinPixelThresUnset' => 'Devi specificare una soglia minima di pixel', // Added - 2009-02-08 'MinTiltRange' => 'Range minimo del Tilt', - 'MinTiltSpeed' => 'Velocita\' minima del Tilt', + 'MinTiltSpeed' => 'Velocità minima del Tilt', 'MinTiltStep' => 'Step minimo del Tilt', 'MinWhiteRange' => 'Range minimo del bilanciamento del bianco', - 'MinWhiteSpeed' => 'Velocita\' minima del bialnciamento del bianco', + 'MinWhiteSpeed' => 'Velocità minima del bialnciamento del bianco', 'MinWhiteStep' => 'Minimo step del bilanciamento del bianco', 'MinZoomRange' => 'Range minimo dello zoom', - 'MinZoomSpeed' => 'Velocita\' minima dello zoom', + 'MinZoomSpeed' => 'Velocità minima dello zoom', 'MinZoomStep' => 'Step minimo dello zoom', 'Misc' => 'Altro', 'Mode' => 'Modalità', // Added - 2015-04-18 'Monitor' => 'Monitor', - 'MonitorIds' => 'Monitor Ids', + 'MonitorIds' => 'Monitor Ids', 'MonitorPreset' => 'Monitor Presenti', 'MonitorPresetIntro' => 'Selezionare un appropriato pre settaggio dalla lista riportata qui sotto.

Per favore notare che questo potrebbe sovrascrivere ogni valore che hai già configurato su questo monitor.

', 'MonitorProbe' => 'Prova Monitor', // Added - 2009-03-31 'MonitorProbeIntro' => 'The list below shows detected analog and network cameras and whether they are already being used or available for selection.

Select the desired entry from the list below.

Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.

', // Added - 2009-03-31 'Monitors' => 'Monitors', 'Montage' => 'Montaggio', - 'MontageReview' => 'Montage Review', // Added - 2018-08-30 + 'MontageReview' => 'Revisione del montaggio', // Added - 2018-08-30 'Month' => 'Mese', - 'More' => 'More', // Added - 2011-06-16 - 'MotionFrameSkip' => 'Motion Frame Skip', + 'More' => 'Più', // Added - 2011-06-16 + 'MotionFrameSkip' => 'Salta/scarta fotogramma', 'Move' => 'Sposta', - 'Mtg2widgrd' => '2-wide grid', // Added 2013.08.15. - 'Mtg3widgrd' => '3-wide grid', // Added 2013.08.15. - 'Mtg3widgrx' => '3-wide grid, scaled, enlarge on alarm', // Added 2013.08.15. - 'Mtg4widgrd' => '4-wide grid', // Added 2013.08.15. + 'Mtg2widgrd' => 'Griglia 2 colonne', // Added 2013.08.15. + 'Mtg3widgrd' => 'Griglia 3 colonne', // Added 2013.08.15. + 'Mtg3widgrx' => 'Griglia 3 colonne, scalata, ingrandita su allarme', // Added 2013.08.15. + 'Mtg4widgrd' => 'Griglia 4 colonne', // Added 2013.08.15. 'MtgDefault' => 'Predefinito', // Added 2013.08.15. 'MustBeGe' => 'deve essere superiore a', 'MustBeLe' => 'deve essere inferiore o pari a', @@ -609,7 +609,7 @@ $SLANG = array( 'ProfileProbeIntro' => 'L\'elenco seguente mostra i profili di streaming esistenti della telecamera selezionata.

Selezionare la voce desiderata dall\'elenco seguente.

Si noti che ZoneMinder non è in grado di configurare profili aggiuntivi e che la scelta di una telecamera qui può sovrascrivere qualsiasi valore già configurato per il monitor corrente.

', // Added - 2015-04-18 'Progress' => 'Progresso', // Added - 2015-04-18 'Protocol' => 'Protocollo', - 'RTSPDescribe' => 'Use RTSP Response Media URL', // Added - 2018-08-30 + 'RTSPDescribe' => 'Usa URL multimediale di risposta RTSP', // Added - 2018-08-30 'RTSPTransport' => 'RTSP Transport Protocol', // Added - 2018-08-30 'Rate' => 'Velocità', 'Real' => 'Reale', @@ -622,15 +622,15 @@ $SLANG = array( 'RemoteHostName' => 'Nome dell\'Host Remoto', 'RemoteHostPath' => 'Percorso dell\'Host Remoto', 'RemoteHostPort' => 'Porta dell\'Host Remoto', - 'RemoteHostSubPath' => 'SubPath host remoto', // Added - 2009-02-08 + 'RemoteHostSubPath' => 'Percorso secondario dell\'Host remoto', // Added - 2009-02-08 'RemoteImageColours' => 'Colori delle immagini Remote', 'RemoteMethod' => 'Metodo Remoto', // Added - 2009-02-08 'RemoteProtocol' => 'Protocollo Remoto', // Added - 2009-02-08 'Rename' => 'Rinomina', - 'Replay' => 'Replay', - 'ReplayAll' => 'All Events', - 'ReplayGapless' => 'Gapless Events', - 'ReplaySingle' => 'Single Event', + 'Replay' => 'Riproduci', + 'ReplayAll' => 'Tutti gli Eventi', + 'ReplayGapless' => 'Eventi continui', + 'ReplaySingle' => 'Evento singolo', 'ReportEventAudit' => 'Rapporto Eventi di controllo', // Added - 2018-08-30 'Reset' => 'Resetta', 'ResetEventCounts' => 'Resetta Contatore Eventi', @@ -644,7 +644,7 @@ $SLANG = array( 'RotateLeft' => 'Ruota a Sinista', 'RotateRight' => 'Ruota a Destra', 'RunLocalUpdate' => 'Eseguire zmupdate.pl per l\'aggiornamento', // Added - 2011-05-25 - 'RunMode' => 'Modalita\' funzionamento', + 'RunMode' => 'Modalità funzionamento', 'RunState' => 'Stato di funzionamento', 'Running' => 'Attivo', 'Save' => 'Salva', @@ -679,25 +679,25 @@ $SLANG = array( 'SourcePath' => 'Percorso della Sorgente', // Added - 2009-02-08 'SourceType' => 'Tipo Sorgente', 'Speed' => 'Velocita\'', - 'SpeedHigh' => 'Alta Velocita\'', - 'SpeedLow' => 'Bassa Velocita\'', - 'SpeedMedium' => 'Media Velocita\'', - 'SpeedTurbo' => 'Turbo Velocita\'', + 'SpeedHigh' => 'Alta Velocità', + 'SpeedLow' => 'Bassa Velocità', + 'SpeedMedium' => 'Media Velocità', + 'SpeedTurbo' => 'Turbo Velocità', 'Start' => 'Avvia', 'State' => 'Stato', 'Stats' => 'Statistiche', 'Status' => 'Stato', - 'StatusConnected' => 'Capturing', // Added - 2018-08-30 - 'StatusNotRunning' => 'Not Running', // Added - 2018-08-30 - 'StatusRunning' => 'Not Capturing', // Added - 2018-08-30 - 'StatusUnknown' => 'Unknown', // Added - 2018-08-30 + 'StatusConnected' => 'Registrazione in corso', // Added - 2018-08-30 + 'StatusNotRunning' => 'Non in esecuzione', // Added - 2018-08-30 + 'StatusRunning' => 'Registrazione in pausa', // Added - 2018-08-30 + 'StatusUnknown' => 'Sconosciuto', // Added - 2018-08-30 'Step' => 'Passo', 'StepBack' => 'Passo indietro', 'StepForward' => 'Passo avanti', - 'StepLarge' => 'Lungo passo', - 'StepMedium' => 'Medio passo', - 'StepNone' => 'No passo', - 'StepSmall' => 'Piccolo passo', + 'StepLarge' => 'Passo lungo', + 'StepMedium' => 'Passo medio', + 'StepNone' => 'Nessun passo', + 'StepSmall' => 'Passo piccolo', 'Stills' => 'Foto', 'Stop' => 'Stop', 'Stopped' => 'Inattivo', @@ -728,12 +728,12 @@ $SLANG = array( 'Today' => 'Oggi ', 'Tools' => 'Strumenti', 'Total' => 'Totale', // Added - 2011-06-16 - 'TotalBrScore' => 'Punteggio
Totale', + 'TotalBrScore' => 'Punteggio Totale', 'TrackDelay' => 'Track Delay', 'TrackMotion' => 'Track Motion', 'Triggers' => 'Triggers', - 'TurboPanSpeed' => 'Velocita\' Turbo Pan', - 'TurboTiltSpeed' => 'Velocita\' Turbo Tilt', + 'TurboPanSpeed' => 'Velocità Turbo Pan', + 'TurboTiltSpeed' => 'Velocità Turbo Tilt', 'Type' => 'Tipo', 'Unarchive' => 'Togli dall\'archivio', 'Undefined' => 'Non specificato', // Added - 2009-02-08 @@ -745,7 +745,7 @@ $SLANG = array( 'Updated' => 'Updated', // Added - 2011-06-16 'Upload' => 'Upload', // Added - 2011-08-23 'UseFilter' => 'Usa Filtro', - 'UseFilterExprsPost' => ' espressioni filtri', // This is used at the end of the phrase 'use N filter expressions' + 'UseFilterExprsPost' => ' espressioni filtri', // This is used at the end of the phrase 'use N filter expressions' 'UseFilterExprsPre' => 'Usa ', // This is used at the beginning of the phrase 'use N filter expressions' 'UsedPlugins' => 'Used Plugins', 'User' => 'Utente', @@ -767,7 +767,7 @@ $SLANG = array( 'VideoGenFiles' => 'File Video Esistenti', 'VideoGenNoFiles' => 'Non ho trovato file ', 'VideoGenParms' => 'Parametri Generazione Video', - 'VideoGenSucceeded' => 'Successo: Generato Video !', + 'VideoGenSucceeded' => 'Successo: Video Generato!', 'VideoSize' => 'Dimensioni Video', 'VideoWriter' => 'Scrittore video', // Added - 2018-08-30 'View' => 'Vedi', @@ -782,7 +782,7 @@ $SLANG = array( 'WebSiteUrl' => 'Website URL', // Added - 2018-08-30 'Week' => 'Settimana', 'White' => 'Bianco', - 'WhiteBalance' => 'Bil. Bianco ', + 'WhiteBalance' => 'Bilanciamento del Bianco', 'Wide' => 'Larghezza', 'X' => 'X', 'X10' => 'X10', @@ -795,7 +795,7 @@ $SLANG = array( 'Zone' => 'Zona', 'ZoneAlarmColour' => 'Colore Allarme (RGB)', 'ZoneArea' => 'Zone Area', - 'ZoneExtendAlarmFrames' => 'Extend Alarm Frame Count', + 'ZoneExtendAlarmFrames' => 'Estendi conteggio immagini allarme', 'ZoneFilterSize' => 'Larghezza/Altezza Filtro (pixels)', 'ZoneMinMaxAlarmArea' => 'Min/Max Area Allarmata', 'ZoneMinMaxBlobArea' => 'Min/Max Area di Blob', @@ -803,7 +803,7 @@ $SLANG = array( 'ZoneMinMaxFiltArea' => 'Min/Max Area Filtrata', 'ZoneMinMaxPixelThres' => 'Min/Max Soglia Pixel (0-255)', 'ZoneMinderLog' => 'ZoneMinder Log', // Added - 2011-06-17 - 'ZoneOverloadFrames' => 'Overload Frame Ignore Count', + 'ZoneOverloadFrames' => 'Sovraccarico - contatore immagini ignorate', 'Zones' => 'Zone', 'Zoom' => 'Zoom', 'ZoomIn' => 'Ingrandisci', From 6dbfd2219076afb377381babb75ac6ec39ba5066 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 13 Sep 2021 15:03:36 -0400 Subject: [PATCH 023/174] Add missing update_function_pointers so that we use SSE blend functions. Significantly reduces cpu use in motion detection. --- src/zm_image.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 09c05550e..2b7bc69e2 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -313,6 +313,7 @@ bool Image::Assign(const AVFrame *frame, SwsContext *convert_context, AVFrame *t return false; } zm_dump_video_frame(temp_frame, "dest frame after convert"); + update_function_pointers(); return true; } // end Image::Assign(const AVFrame *frame, SwsContext *convert_context, AVFrame *temp_frame) @@ -687,6 +688,7 @@ void Image::AssignDirect( subpixelorder = p_subpixelorder; pixels = width * height; size = new_buffer_size; + update_function_pointers(); } // end void Image::AssignDirect void Image::Assign( @@ -788,6 +790,7 @@ void Image::Assign(const Image &image) { linesize = image.linesize; } + update_function_pointers(); if ( image.buffer != buffer ) (*fptr_imgbufcpy)(buffer, image.buffer, size); } From c4a49721d2f77128a3e3404a1a22fbabd55a08d1 Mon Sep 17 00:00:00 2001 From: Andrea Vezzali Date: Tue, 14 Sep 2021 15:16:25 +0200 Subject: [PATCH 024/174] Update it_it.php --- web/lang/it_it.php | 140 ++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/web/lang/it_it.php b/web/lang/it_it.php index b51b85300..f06b18cc4 100644 --- a/web/lang/it_it.php +++ b/web/lang/it_it.php @@ -84,7 +84,7 @@ $SLANG = array( 'AddNewControl' => 'Aggiungi nuovo Controllo', 'AddNewMonitor' => 'Aggiungi nuovo Monitor', 'AddNewServer' => 'Aggiungi nuovo Server', // Added - 2018-08-30 - 'AddNewStorage' => 'Aggiungi nuovo Storage', // Added - 2018-08-30 + 'AddNewStorage' => 'Aggiungi nuovo Archivio', // Added - 2018-08-30 'AddNewUser' => 'Aggiungi nuovo Utente', 'AddNewZone' => 'Aggiungi nuova Zona', 'Alarm' => 'Allarme', @@ -95,7 +95,7 @@ $SLANG = array( 'AlarmMaximumFPS' => 'FPS massimi durante l\'allarme', 'AlarmPx' => 'Pixel Allarme', 'AlarmRGBUnset' => 'Devi settare un colore RGB di allarme', - 'AlarmRefImageBlendPct'=> 'Alarm Reference Image Blend %ge', // Added - 2015-04-18 + 'AlarmRefImageBlendPct'=> 'Riferimento Allarme - Fusione Immagine %', // Added - 2015-04-18 'Alert' => 'Attenzione', 'All' => 'Tutto', 'AnalysisFPS' => 'Analisi FPS', // Added - 2015-07-22 @@ -103,14 +103,14 @@ $SLANG = array( 'Apply' => 'Applica', 'ApplyingStateChange' => 'Sto applicando le modifiche', 'ArchArchived' => 'Archiviato', - 'ArchUnarchived' => 'Non archiviato', + 'ArchUnarchived' => 'Non Archiviato', 'Archive' => 'Archivio', 'Archived' => 'Archiviato', 'Area' => 'Area', 'AreaUnits' => 'Area (px/%)', - 'AttrAlarmFrames' => 'Immagini in Allarme', + 'AttrAlarmFrames' => 'Immagini Allarme', 'AttrArchiveStatus' => 'Stato Archivio', - 'AttrAvgScore' => 'Punteggio medio', + 'AttrAvgScore' => 'Punteggio Medio', 'AttrCause' => 'Causa', 'AttrDiskBlocks' => 'Blocchi disco', 'AttrDiskPercent' => 'Percentuale disco', @@ -123,7 +123,7 @@ $SLANG = array( 'AttrFilterServer' => 'Filtro attivo su Server', // Added - 2018-08-30 'AttrFrames' => 'Immagini', 'AttrId' => 'Id', - 'AttrMaxScore' => 'Punteggio massimo', + 'AttrMaxScore' => 'Punteggio Massimo', 'AttrMonitorId' => 'Id Monitor', 'AttrMonitorName' => 'Nome Monitor', 'AttrMonitorServer' => 'Monitor attivo su Server', // Added - 2018-08-30 @@ -133,11 +133,11 @@ $SLANG = array( 'AttrStartDateTime' => 'Inizio - Data/orario', // Added - 2018-08-30 'AttrStartTime' => 'Inizio - Orario', // Added - 2018-08-30 'AttrStartWeekday' => 'Inizio - Giorno della settimana', // Added - 2018-08-30 - 'AttrStateId' => 'Stato esecuzione', // Added - 2018-08-30 - 'AttrStorageArea' => 'Area Salvataggio', // Added - 2018-08-30 - 'AttrStorageServer' => 'Server Salvataggio remoto', // Added - 2018-08-30 - 'AttrSystemLoad' => 'Carico di sistema', - 'AttrTotalScore' => 'Punteggio totale', + 'AttrStateId' => 'Stato Esecuzione', // Added - 2018-08-30 + 'AttrStorageArea' => 'Area Archiviazione', // Added - 2018-08-30 + 'AttrStorageServer' => 'Server Archiviazione remota', // Added - 2018-08-30 + 'AttrSystemLoad' => 'Carico Sistema', + 'AttrTotalScore' => 'Punteggio Totale', 'Auto' => 'Auto', 'AutoStopTimeout' => 'Auto Stop Timeout', 'Available' => 'Disponibile', // Added - 2009-03-31 @@ -181,7 +181,7 @@ $SLANG = array( 'BlobPx' => 'Blob Px', 'BlobSizes' => 'Dimensioni Blob', 'Blobs' => 'Blobs', - 'Brightness' => 'Luminosità;', + 'Brightness' => 'Luminosità', 'Buffer' => 'Buffer', // Added - 2015-04-18 'Buffers' => 'Buffers', 'CSSDescription' => 'Change the default css for this computer', // Added - 2015-04-18 @@ -213,7 +213,7 @@ $SLANG = array( 'CanReboot' => 'Può Riavviare', 'CanSetPresets' => 'Può impostare preset', 'CanSleep' => 'Può andare in sleep', - 'CanTilt' => 'Può Tilt', + 'CanTilt' => 'Può inclinare', 'CanWake' => 'Può essere riattivato', 'CanWhite' => 'Può bilanciare il bianco', 'CanWhiteAbs' => 'Può bilanciare il bianco assoluto', @@ -238,8 +238,8 @@ $SLANG = array( 'ChooseLogFormat' => 'Scegli un formato di registro', // Added - 2011-06-17 'ChooseLogSelection' => 'Scegli una selezione del registro', // Added - 2011-06-17 'ChoosePreset' => 'Scegli Preset', - 'Clear' => 'Clear', // Added - 2011-06-16 - 'CloneMonitor' => 'Clone', // Added - 2018-08-30 + 'Clear' => 'Pulisci', // Added - 2011-06-16 + 'CloneMonitor' => 'Clona', // Added - 2018-08-30 'Close' => 'Chiudi', 'Colour' => 'Colori', 'Command' => 'Comando', @@ -257,25 +257,25 @@ $SLANG = array( 'Contrast' => 'Contrasto', 'Control' => 'Controllo', 'ControlAddress' => 'Indirizzo di controllo', - 'ControlCap' => 'Capacita\' di controllo', - 'ControlCaps' => 'Capacita\' di controllo', + 'ControlCap' => 'Capacità di controllo', + 'ControlCaps' => 'Capacità di controllo', 'ControlDevice' => 'Dispositivo di controllo', 'ControlType' => 'Tipo Controllo', 'Controllable' => 'Controllabile', - 'Current' => 'Current', // Added - 2015-04-18 + 'Current' => 'Corrente', // Added - 2015-04-18 'Cycle' => 'Cicla', 'CycleWatch' => 'Vista Ciclica', - 'DateTime' => 'Date/Time', // Added - 2011-06-16 + 'DateTime' => 'Data/Orario', // Added - 2011-06-16 'Day' => 'Giorno', 'Debug' => 'Debug', - 'DefaultRate' => 'Default Rate', + 'DefaultRate' => 'Rateo predefinito', 'DefaultScale' => 'Scala di default', - 'DefaultView' => 'Visualizzazione di default', - 'Deinterlacing' => 'Deinterlacing', // Added - 2015-04-18 - 'Delay' => 'Delay', // Added - 2015-04-18 + 'DefaultView' => 'Visualizzazione predefinita', + 'Deinterlacing' => 'Deinterlacciamento', // Added - 2015-04-18 + 'Delay' => 'Ritardo', // Added - 2015-04-18 'Delete' => 'Elimina', - 'DeleteAndNext' => 'Elimina & Prossimo', - 'DeleteAndPrev' => 'Elimina & Precedente', + 'DeleteAndNext' => 'Elimina e Prossimo', + 'DeleteAndPrev' => 'Elimina e Precedente', 'DeleteSavedFilter' => 'Elimina il filtro salvato', 'Description' => 'Descrizione', 'DetectedCameras' => 'Telecamere Rilevate', // Added - 2009-03-31 @@ -298,7 +298,7 @@ $SLANG = array( 'DonateRemindDay' => 'Non ancora, ricordamelo ancora tra 1 giorno', 'DonateRemindHour' => 'Non ancora, ricordamelo ancora tra 1 ora', 'DonateRemindMonth' => 'Non ancora, ricordamelo ancora tra 1 mese', - 'DonateRemindNever' => 'No, io non voglio donare, non lo faro\' mai', + 'DonateRemindNever' => 'No, io non voglio donare, non lo farò mai', 'DonateRemindWeek' => 'Non ancora, ricordamelo ancora tra 1 settimana', 'DonateYes' => 'Si,mi piacerebbe donare qualcosa ora', 'Download' => 'Scarica', @@ -363,12 +363,12 @@ $SLANG = array( 'First' => 'Primo', 'FlippedHori' => 'ribaltato orizzontale', 'FlippedVert' => 'ribaltato verticale', - 'FnMocord' => 'Mocord', // Added 2013.08.16. - 'FnModect' => 'Modect', // Added 2013.08.16. - 'FnMonitor' => 'Monitor', // Added 2013.08.16. - 'FnNodect' => 'Nodect', // Added 2013.08.16. - 'FnNone' => 'None', // Added 2013.08.16. - 'FnRecord' => 'Record', // Added 2013.08.16. + 'FnMocord' => 'Mocord - Registrazione continua (con evidenziazione eventi)', // Added 2013.08.16. + 'FnModect' => 'Modect - MOtion DEteCTtion (registrazione su rilevamento movimento)', // Added 2013.08.16. + 'FnMonitor' => 'Monitor - Visualizza Live', // Added 2013.08.16. + 'FnNodect' => 'Nodect - No DEteCTtion (registrazione su evento esterno)', // Added 2013.08.16. + 'FnNone' => 'None - Nessuno (Monitor disabilitato)', // Added 2013.08.16. + 'FnRecord' => 'Record - Registrazione continua', // Added 2013.08.16. 'Focus' => 'Focus', 'ForceAlarm' => 'Forza Allarme', 'Format' => 'Formato', @@ -379,7 +379,7 @@ $SLANG = array( 'Frames' => 'Immagini', 'Func' => 'Funz', 'Function' => 'Funzione', - 'Gain' => 'Gain', + 'Gain' => 'Guadagno', 'General' => 'Generale', 'GenerateDownload' => 'Genera download', // Added - 2018-08-30 'GenerateVideo' => 'Genera video', @@ -391,7 +391,7 @@ $SLANG = array( 'HasFocusSpeed' => 'Ha velocità di focus', 'HasGainSpeed' => 'Ha velocità di guadagno', 'HasHomePreset' => 'Ha posizioni di present', - 'HasIrisSpeed' => 'Ha velocotà di iris', + 'HasIrisSpeed' => 'Ha velocità di iris', 'HasPanSpeed' => 'Ha velocità di Pan', 'HasPresets' => 'Ha preset', 'HasTiltSpeed' => 'Ha velocità di Tilt', @@ -414,7 +414,7 @@ $SLANG = array( 'In' => 'In', 'Include' => 'Includi', 'Inverted' => 'Invertito', - 'Iris' => 'Iris', + 'Iris' => 'Iride', 'KeyString' => 'Stringa Chiave', 'Label' => 'Etichetta', 'Language' => 'Linguaggio', @@ -438,7 +438,7 @@ $SLANG = array( 'Logout' => 'Logout', 'Logs' => 'Logs', // Added - 2011-06-17 'Low' => 'Bassa', - 'LowBW' => 'Banda Bassa', + 'LowBW' => 'Banda Bassa', 'Main' => 'Principale', 'Man' => 'Man', 'Manual' => 'Manuale', @@ -452,9 +452,9 @@ $SLANG = array( 'MaxGainRange' => 'Massimo range del guadagno', 'MaxGainSpeed' => 'Massima velocità del guadagno', 'MaxGainStep' => 'Massimo step del guadagno', - 'MaxIrisRange' => 'Massima range dell\'Iris', - 'MaxIrisSpeed' => 'Massima velocità dell\'Iris', - 'MaxIrisStep' => 'Massimo step dell\'Iris', + 'MaxIrisRange' => 'Massima range dell\'Iride', + 'MaxIrisSpeed' => 'Massima velocità dell\'Iride', + 'MaxIrisStep' => 'Massimo step dell\'Iride', 'MaxPanRange' => 'Massimo range del pan', 'MaxPanSpeed' => 'Massima velocità del tilt', 'MaxPanStep' => 'Massimo step del pan', @@ -470,7 +470,7 @@ $SLANG = array( 'MaximumFPS' => 'Massimi FPS', 'Medium' => 'Media', 'MediumBW' => 'Larghezza Banda Media', - 'Message' => 'Message', // Added - 2011-06-16 + 'Message' => 'Messaggio', // Added - 2011-06-16 'MinAlarmAreaLtMax' => 'L\'area minima dell\'allarme deve essere minore di quella massima', 'MinAlarmAreaUnset' => 'Devi specificare il numero minimo di pixel per l\'allarme', 'MinBlobAreaLtMax' => 'L\'area di blob minima deve essere minore dell\'area di blob massima', @@ -487,10 +487,10 @@ $SLANG = array( 'MinGainRange' => 'Minimo range del Guadagno', 'MinGainSpeed' => 'Velocità minima del Guadagno', 'MinGainStep' => 'Step minimo del guadagno', - 'MinIrisRange' => 'Range minimo dell\'Iris', - 'MinIrisSpeed' => 'Velocità minima dell\'Iris', - 'MinIrisStep' => 'Step minimo dell\'Iris', - 'MinPanRange' => 'Range minimo del pan', + 'MinIrisRange' => 'Range minimo dell\'Iride', + 'MinIrisSpeed' => 'Velocità minima dell\'Iride', + 'MinIrisStep' => 'Step minimo dell\'Iride', + 'MinPanRange' => 'Range minimo del Pan', 'MinPanSpeed' => 'Velocità minima del Pan', 'MinPanStep' => 'Step minimo del Pan', 'MinPixelThresLtMax' => 'I pixel minimi della soglia devono essere minori dei pixel massimi della soglia', @@ -550,7 +550,7 @@ $SLANG = array( 'NoneAvailable' => 'Nessuno disponibile', 'Normal' => 'Normale', 'Notes' => 'Note', - 'NumPresets' => 'Num Presets', + 'NumPresets' => 'Num redefiniti', 'Off' => 'Off', 'On' => 'On', 'OnvifCredentialsIntro'=> 'Fornire nome utente e password per la telecamera selezionata.
Se non è stato creato alcun utente per la videocamera, l\'utente qui indicato verrà creato con la password specificata.

', // Added - 2015-04-18 @@ -589,7 +589,7 @@ $SLANG = array( 'Paths' => 'Percorsi', 'Pause' => 'Pause', 'Phone' => 'Telefono', - 'PhoneBW' => 'Banda Tel', + 'PhoneBW' => 'Banda Tel', 'Pid' => 'PID', // Added - 2011-06-16 'PixelDiff' => 'Pixel Diff', 'Pixels' => 'pixels', @@ -598,11 +598,11 @@ $SLANG = array( 'PleaseWait' => 'Attendere prego', 'Plugins' => 'Plugins', 'Point' => 'Punto', - 'PostEventImageBuffer' => 'Buffer di immagini Dopo Evento', - 'PreEventImageBuffer' => 'Buffer di immagini Pre Evento', + 'PostEventImageBuffer' => 'Buffer immagini Dopo Evento', + 'PreEventImageBuffer' => 'Buffer immagini Pre Evento', 'PreserveAspect' => 'Preserve Aspect Ratio', 'Preset' => 'Preset', - 'Presets' => 'Presets', + 'Presets' => 'Predefiniti', 'Prev' => 'Prec', 'Probe' => 'Prova la telecamera', // Added - 2009-03-31 'ProfileProbe' => 'Prova lo stream', // Added - 2015-04-18 @@ -632,8 +632,8 @@ $SLANG = array( 'ReplayGapless' => 'Eventi continui', 'ReplaySingle' => 'Evento singolo', 'ReportEventAudit' => 'Rapporto Eventi di controllo', // Added - 2018-08-30 - 'Reset' => 'Resetta', - 'ResetEventCounts' => 'Resetta Contatore Eventi', + 'Reset' => 'Reset', + 'ResetEventCounts' => 'Reset Contatore Eventi', 'Restart' => 'Riavvia', 'Restarting' => 'Sto riavviando', 'RestrictedCameraIds' => 'Camera Ids Riservati', @@ -698,30 +698,30 @@ $SLANG = array( 'StepMedium' => 'Passo medio', 'StepNone' => 'Nessun passo', 'StepSmall' => 'Passo piccolo', - 'Stills' => 'Foto', + 'Stills' => 'Immagini fisse', 'Stop' => 'Stop', 'Stopped' => 'Inattivo', - 'StorageArea' => 'Area di salvataggio', // Added - 2018-08-30 - 'StorageScheme' => 'Scheme', // Added - 2018-08-30 - 'Stream' => 'Flusso', - 'StreamReplayBuffer' => 'Stream Replay Image Buffer', + 'StorageArea' => 'Area Archiviazione', // Added - 2018-08-30 + 'StorageScheme' => 'Schema Archiviazione', // Added - 2018-08-30 + 'Stream' => 'Stream', + 'StreamReplayBuffer' => 'Buffer immagini riproduzione stream', 'Submit' => 'Accetta', 'System' => 'Sistema', 'SystemLog' => 'Log di sistema', // Added - 2011-06-16 'TargetColorspace' => 'Target colorspace', // Added - 2015-04-18 'Tele' => 'Tele', 'Thumbnail' => 'Anteprima', - 'Tilt' => 'Tilt', + 'Tilt' => 'Tilt - Inclinazione', 'Time' => 'Ora', - 'TimeDelta' => 'Tempo di Delta', - 'TimeStamp' => 'Time Stamp', + 'TimeDelta' => 'Differenza orario', + 'TimeStamp' => 'Sovraimpressione data/orario', 'Timeline' => 'Linea Temporale', 'TimelineTip1' => 'Passa il mouse sul grafico per visualizzare un\'immagine dell\'istantanea e i dettagli dell\'evento.', // Added 2013.08.15. 'TimelineTip2' => 'Fai clic sulle sezioni colorate del grafico o sull\'immagine per visualizzare l\'evento.', // Added 2013.08.15. 'TimelineTip3' => 'Fare clic sullo sfondo per ingrandire un periodo di tempo più piccolo basato sul clic.', // Added 2013.08.15. 'TimelineTip4' => 'Utilizzare i controlli seguenti per ridurre o spostarsi avanti e indietro nell\'intervallo di tempo.', // Added 2013.08.15. - 'Timestamp' => 'Timestamp', - 'TimestampLabelFormat' => 'Formato etichetta timestamp', + 'Timestamp' => 'Sovraimpressione data/orario', + 'TimestampLabelFormat' => 'Formato etichetta Sovraimpressione data/orario', 'TimestampLabelSize' => 'Dimensione carattere', // Added - 2018-08-30 'TimestampLabelX' => 'coordinata X etichetta', 'TimestampLabelY' => 'coordinata Y etichetta', @@ -729,9 +729,9 @@ $SLANG = array( 'Tools' => 'Strumenti', 'Total' => 'Totale', // Added - 2011-06-16 'TotalBrScore' => 'Punteggio Totale', - 'TrackDelay' => 'Track Delay', - 'TrackMotion' => 'Track Motion', - 'Triggers' => 'Triggers', + 'TrackDelay' => 'Ritardo traccia', + 'TrackMotion' => 'Segui movimento', + 'Triggers' => 'Inneschi/Interruttori', 'TurboPanSpeed' => 'Velocità Turbo Pan', 'TurboTiltSpeed' => 'Velocità Turbo Tilt', 'Type' => 'Tipo', @@ -742,17 +742,17 @@ $SLANG = array( 'Update' => 'Aggiorna', 'UpdateAvailable' => 'Un aggiornamento di ZoneMinder è disponibilie.', 'UpdateNotNecessary' => 'Nessun aggiornamento necessario.', - 'Updated' => 'Updated', // Added - 2011-06-16 - 'Upload' => 'Upload', // Added - 2011-08-23 + 'Updated' => 'Aggiornato', // Added - 2011-06-16 + 'Upload' => 'Carica', // Added - 2011-08-23 'UseFilter' => 'Usa Filtro', 'UseFilterExprsPost' => ' espressioni filtri', // This is used at the end of the phrase 'use N filter expressions' 'UseFilterExprsPre' => 'Usa ', // This is used at the beginning of the phrase 'use N filter expressions' - 'UsedPlugins' => 'Used Plugins', + 'UsedPlugins' => 'Plugins in uso', 'User' => 'Utente', 'Username' => 'Nome Utente', 'Users' => 'Utenti', 'V4L' => 'V4L', // Added - 2015-04-18 - 'V4LCapturesPerFrame' => 'Captures Per Frame', // Added - 2015-04-18 + 'V4LCapturesPerFrame' => 'Rilevamenti per immagine', // Added - 2015-04-18 'V4LMultiBuffer' => 'Multi Buffering', // Added - 2015-04-18 'Value' => 'Valore', 'Version' => 'Versione', @@ -769,7 +769,7 @@ $SLANG = array( 'VideoGenParms' => 'Parametri Generazione Video', 'VideoGenSucceeded' => 'Successo: Video Generato!', 'VideoSize' => 'Dimensioni Video', - 'VideoWriter' => 'Scrittore video', // Added - 2018-08-30 + 'VideoWriter' => 'Scrittore Video', // Added - 2018-08-30 'View' => 'Vedi', 'ViewAll' => 'Vedi Tutto', 'ViewEvent' => 'Vedi Evento', @@ -789,7 +789,7 @@ $SLANG = array( 'X10ActivationString' => 'Stringa attivazione X10', 'X10InputAlarmString' => 'Stringa allarme input X10', 'X10OutputAlarmString' => 'Stringa allarme output X10', - 'Y' => 'Y', + 'Y' => 'S', 'Yes' => 'Si', 'YouNoPerms' => 'Non hai i permessi per accedere a questa risorsa.', 'Zone' => 'Zona', From 787b7f1874141ca675081db0fe6b945d88fe078a Mon Sep 17 00:00:00 2001 From: Andrea Vezzali Date: Tue, 14 Sep 2021 15:39:53 +0200 Subject: [PATCH 025/174] Update it_it.php --- web/lang/it_it.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/lang/it_it.php b/web/lang/it_it.php index f06b18cc4..4cdb24ee9 100644 --- a/web/lang/it_it.php +++ b/web/lang/it_it.php @@ -631,7 +631,7 @@ $SLANG = array( 'ReplayAll' => 'Tutti gli Eventi', 'ReplayGapless' => 'Eventi continui', 'ReplaySingle' => 'Evento singolo', - 'ReportEventAudit' => 'Rapporto Eventi di controllo', // Added - 2018-08-30 + 'ReportEventAudit' => 'Controllo Eventi', // Added - 2018-08-30 'Reset' => 'Reset', 'ResetEventCounts' => 'Reset Contatore Eventi', 'Restart' => 'Riavvia', @@ -671,14 +671,14 @@ $SLANG = array( 'Size' => 'grandezza', 'SkinDescription' => 'Cambia la skin predefinita per questo computer', // Added - 2011-01-30 'Sleep' => 'Sleep', - 'SortAsc' => 'Cresc', + 'SortAsc' => 'Crescente', 'SortBy' => 'Ordina per', - 'SortDesc' => 'Decr', + 'SortDesc' => 'Decrescente', 'Source' => 'Sorgente', 'SourceColours' => 'Colori della Sorgente', // Added - 2009-02-08 'SourcePath' => 'Percorso della Sorgente', // Added - 2009-02-08 'SourceType' => 'Tipo Sorgente', - 'Speed' => 'Velocita\'', + 'Speed' => 'Velocità', 'SpeedHigh' => 'Alta Velocità', 'SpeedLow' => 'Bassa Velocità', 'SpeedMedium' => 'Media Velocità', @@ -708,10 +708,10 @@ $SLANG = array( 'Submit' => 'Accetta', 'System' => 'Sistema', 'SystemLog' => 'Log di sistema', // Added - 2011-06-16 - 'TargetColorspace' => 'Target colorspace', // Added - 2015-04-18 + 'TargetColorspace' => 'Spazio dei colori obiettivo', // Added - 2015-04-18 'Tele' => 'Tele', 'Thumbnail' => 'Anteprima', - 'Tilt' => 'Tilt - Inclinazione', + 'Tilt' => 'Tilt (Inclinazione)', 'Time' => 'Ora', 'TimeDelta' => 'Differenza orario', 'TimeStamp' => 'Sovraimpressione data/orario', From c7aa41502aea2b6ab65fcaec5fb8c5ffa2981897 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 14 Sep 2021 10:26:07 -0400 Subject: [PATCH 026/174] Fix js error in montage review when using scaled mode. Fixes #3351 --- web/skins/classic/views/js/montagereview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/montagereview.js b/web/skins/classic/views/js/montagereview.js index 4650e7e21..787a910d0 100644 --- a/web/skins/classic/views/js/montagereview.js +++ b/web/skins/classic/views/js/montagereview.js @@ -498,8 +498,8 @@ function redrawScreen() { drawGraph(); } + var monitors = $j('#monitors'); if ( fitMode == 1 ) { - var monitors = $j('#monitors'); var fps = $j('#fps'); var vh = window.innerHeight; var mh = (vh - monitors.position().top - fps.outerHeight()); From 120d9764bce6796e6e0e5bd979ae2104603a63df Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 14 Sep 2021 13:38:55 -0400 Subject: [PATCH 027/174] notify anyone waiting in packetqueue before waiting on a packet in motion detection. Should fix decode lockup --- src/zm_monitor.cpp | 1 + src/zm_packetqueue.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 44e032979..5a2c646ab 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1846,6 +1846,7 @@ bool Monitor::Analyse() { while (!snap->decoded and !zm_terminate and !analysis_thread->Stopped()) { // Need to wait for the decoder thread. Debug(1, "Waiting for decode"); + packetqueue.notify_all(); // decode might be waiting packet_lock->wait(); if (!snap->image and snap->decoded) { Debug(1, "No image but was decoded, giving up"); diff --git a/src/zm_packetqueue.h b/src/zm_packetqueue.h index 7e2f367fc..2fc29ea33 100644 --- a/src/zm_packetqueue.h +++ b/src/zm_packetqueue.h @@ -81,6 +81,7 @@ class PacketQueue { ); bool is_there_an_iterator_pointing_to_packet(const std::shared_ptr &zm_packet); void unlock(ZMLockedPacket *lp); + void notify_all() { condition.notify_all(); }; }; #endif /* ZM_PACKETQUEUE_H */ From 8272411bb2320233035fff04be01a3e9b0e96e48 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 14 Sep 2021 15:47:35 -0400 Subject: [PATCH 028/174] Revert "use get_packet_and_increment_it instead of the two step to improve locking" This reverts commit a44bbf8e345d3eefea92e2b05bb1034ae1bd46b7. --- src/zm_monitor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 5a2c646ab..eb65ac6f0 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1723,7 +1723,7 @@ bool Monitor::Analyse() { // if have event, send frames until we find a video packet, at which point do analysis. Adaptive skip should only affect which frames we do analysis on. // get_analysis_packet will lock the packet and may wait if analysis_it is at the end - ZMLockedPacket *packet_lock = packetqueue.get_packet_and_increment_it(analysis_it); + ZMLockedPacket *packet_lock = packetqueue.get_packet(analysis_it); if (!packet_lock) return false; std::shared_ptr snap = packet_lock->packet_; @@ -1731,11 +1731,13 @@ bool Monitor::Analyse() { if (snap->score != -1) { Error("skipping because score was %d", snap->score); packetqueue.unlock(packet_lock); + packetqueue.increment_it(analysis_it); return false; } // Store the it that points to our snap we will need it later - packetqueue_iterator snap_it = std::prev(*analysis_it); + packetqueue_iterator snap_it = *analysis_it; + packetqueue.increment_it(analysis_it); // signal is set by capture bool signal = shared_data->signal; From de299ab8829d28e8fbe0e1cca1419f439c1590ac Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 14 Sep 2021 16:21:32 -0400 Subject: [PATCH 029/174] More properly fix the threading lock. Instead of waiting on a packet, release it and wait on the packetqueue. --- src/zm_monitor.cpp | 30 +++++++++++++++++------------- src/zm_packetqueue.cpp | 9 +++++++++ src/zm_packetqueue.h | 3 ++- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index eb65ac6f0..38160e354 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1735,10 +1735,6 @@ bool Monitor::Analyse() { return false; } - // Store the it that points to our snap we will need it later - packetqueue_iterator snap_it = *analysis_it; - packetqueue.increment_it(analysis_it); - // signal is set by capture bool signal = shared_data->signal; bool signal_change = (signal != last_signal); @@ -1848,8 +1844,15 @@ bool Monitor::Analyse() { while (!snap->decoded and !zm_terminate and !analysis_thread->Stopped()) { // Need to wait for the decoder thread. Debug(1, "Waiting for decode"); + packetqueue.unlock(packet_lock); packetqueue.notify_all(); // decode might be waiting - packet_lock->wait(); + packetqueue.wait(); + + // Another thread may have moved our it. Unlikely but possible + packet_lock = packetqueue.get_packet(analysis_it); + if (!packet_lock) return false; + snap = packet_lock->packet_; + if (!snap->image and snap->decoded) { Debug(1, "No image but was decoded, giving up"); delete packet_lock; @@ -1947,14 +1950,14 @@ bool Monitor::Analyse() { // Must start on a keyframe so rewind. Only for passthrough though I guess. // FIXME this iterator is not protected from invalidation packetqueue_iterator *start_it = packetqueue.get_event_start_packet_it( - snap_it, 0 /* pre_event_count */ + *analysis_it, 0 /* pre_event_count */ ); // This gets a lock on the starting packet ZMLockedPacket *starting_packet_lock = nullptr; std::shared_ptr starting_packet = nullptr; - if (*start_it != snap_it) { + if (*start_it != *analysis_it) { starting_packet_lock = packetqueue.get_packet(start_it); if (!starting_packet_lock) { Warning("Unable to get starting packet lock"); @@ -1968,12 +1971,12 @@ bool Monitor::Analyse() { event = new Event(this, starting_packet->timestamp, "Continuous", noteSetMap); // Write out starting packets, do not modify packetqueue it will garbage collect itself - while (starting_packet and ((*start_it) != snap_it)) { + while (starting_packet and ((*start_it) != *analysis_it)) { event->AddPacket(starting_packet); // Have added the packet, don't want to unlock it until we have locked the next packetqueue.increment_it(start_it); - if ((*start_it) == snap_it) { + if ((*start_it) == *analysis_it) { if (starting_packet_lock) delete starting_packet_lock; break; } @@ -2051,12 +2054,12 @@ bool Monitor::Analyse() { if (!event) { packetqueue_iterator *start_it = packetqueue.get_event_start_packet_it( - snap_it, + *analysis_it, (pre_event_count > alarm_frame_count ? pre_event_count : alarm_frame_count) ); ZMLockedPacket *starting_packet_lock = nullptr; std::shared_ptr starting_packet = nullptr; - if (*start_it != snap_it) { + if (*start_it != *analysis_it) { starting_packet_lock = packetqueue.get_packet(start_it); if (!starting_packet_lock) return false; starting_packet = starting_packet_lock->packet_; @@ -2071,11 +2074,11 @@ bool Monitor::Analyse() { shared_data->state = state = ALARM; // Write out starting packets, do not modify packetqueue it will garbage collect itself - while (*start_it != snap_it) { + while (*start_it != *analysis_it) { event->AddPacket(starting_packet); packetqueue.increment_it(start_it); - if ( (*start_it) == snap_it ) { + if ( (*start_it) == (*analysis_it) ) { if (starting_packet_lock) delete starting_packet_lock; break; } @@ -2262,6 +2265,7 @@ bool Monitor::Analyse() { if (function == MODECT or function == MOCORD) UpdateAnalysisFPS(); } + packetqueue.increment_it(analysis_it); packetqueue.unlock(packet_lock); shared_data->last_read_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index 67ba35c0f..43ab20d1e 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -663,3 +663,12 @@ void PacketQueue::setPreEventVideoPackets(int p) { pre_event_video_packet_count = 1; // We can simplify a lot of logic in queuePacket if we can assume at least 1 packet in queue } + +void PacketQueue::notify_all() { + condition.notify_all(); +}; + +void PacketQueue::wait() { + std::unique_lock lck(mutex); + condition.wait(lck); +} diff --git a/src/zm_packetqueue.h b/src/zm_packetqueue.h index 2fc29ea33..20cfdfe85 100644 --- a/src/zm_packetqueue.h +++ b/src/zm_packetqueue.h @@ -81,7 +81,8 @@ class PacketQueue { ); bool is_there_an_iterator_pointing_to_packet(const std::shared_ptr &zm_packet); void unlock(ZMLockedPacket *lp); - void notify_all() { condition.notify_all(); }; + void notify_all(); + void wait(); }; #endif /* ZM_PACKETQUEUE_H */ From cddb9d88bf4eb59e70fb2e87ce18e093521f0457 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 14 Sep 2021 18:08:50 -0400 Subject: [PATCH 030/174] Add support for package version --- utils/packpack/startpackpack.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/packpack/startpackpack.sh b/utils/packpack/startpackpack.sh index e8a8a182d..2ea949078 100755 --- a/utils/packpack/startpackpack.sh +++ b/utils/packpack/startpackpack.sh @@ -223,7 +223,7 @@ setdebpkgname () { if [ "" == "$VERSION" ]; then export VERSION="${versionfile}~${thedate}.${numcommits}" fi - export RELEASE="${DIST}" + export RELEASE="${DIST}${PACKAGE_VERSION}" checkvars From 38cda24b5383b79b92ed659455ee9f33a5c6ce9b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 15 Sep 2021 12:53:41 -0400 Subject: [PATCH 031/174] wait won't wake up other threads, so notify first. Since we have the lock, this should be ok --- src/zm_packetqueue.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index 43ab20d1e..cef7e8e2f 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -133,6 +133,7 @@ bool PacketQueue::queuePacket(std::shared_ptr add_packet) { if (max_video_packet_count > 0) { while (packet_counts[video_stream_id] > max_video_packet_count) { Error("Unable to free up older packets. Waiting."); + condition.notify_all(); condition.wait(lck); if (deleting or zm_terminate) return false; From c5f46231042195d25dad3c321bcb1a5579d77c39 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 15 Sep 2021 12:55:49 -0400 Subject: [PATCH 032/174] Don't crash when unable to create source. erase will call the desctructor. Fixes #3344 --- src/zm_rtsp_server.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/zm_rtsp_server.cpp b/src/zm_rtsp_server.cpp index 2276850cd..ea6f4e2b7 100644 --- a/src/zm_rtsp_server.cpp +++ b/src/zm_rtsp_server.cpp @@ -269,9 +269,8 @@ int main(int argc, char *argv[]) { Warning("Unknown format in %s", videoFifoPath.c_str()); } if (videoSource == nullptr) { - Error("Unable to create source"); + Error("Unable to create source for %s", videoFifoPath.c_str()); rtspServer->RemoveSession(sessions[monitor->Id()]->GetMediaSessionId()); - delete sessions[monitor->Id()]; sessions.erase(monitor->Id()); continue; } From e63be2b18ed3b362b5db198d7da16204f00a6cd7 Mon Sep 17 00:00:00 2001 From: Mike Dussault Date: Wed, 15 Sep 2021 10:13:02 -0700 Subject: [PATCH 033/174] Fixed a bug in Image::Buffer that would return the wrong location in the image if the image had > 1 channels (and if the request were for x > 0). --- src/zm_image.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_image.h b/src/zm_image.h index ccbae9f86..24626d789 100644 --- a/src/zm_image.h +++ b/src/zm_image.h @@ -181,7 +181,7 @@ class Image { /* Internal buffer should not be modified from functions outside of this class */ inline const uint8_t* Buffer() const { return buffer; } - inline const uint8_t* Buffer(unsigned int x, unsigned int y=0) const { return &buffer[(y*linesize)+x]; } + inline const uint8_t* Buffer(unsigned int x, unsigned int y=0) const { return &buffer[(y*linesize) + x*colours]; } /* Request writeable buffer */ uint8_t* WriteBuffer(const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder); // Is only acceptable on a pre-allocated buffer From c233ec3b8c63f7c602395ccdb88bed0cc362b247 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 15 Sep 2021 13:38:00 -0400 Subject: [PATCH 034/174] Remove redundant notify_all, spelling mistake --- src/zm_monitor.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 38160e354..9a5144623 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1844,8 +1844,7 @@ bool Monitor::Analyse() { while (!snap->decoded and !zm_terminate and !analysis_thread->Stopped()) { // Need to wait for the decoder thread. Debug(1, "Waiting for decode"); - packetqueue.unlock(packet_lock); - packetqueue.notify_all(); // decode might be waiting + packetqueue.unlock(packet_lock); // This will delete packet_lock and notify_all packetqueue.wait(); // Another thread may have moved our it. Unlikely but possible @@ -3070,7 +3069,7 @@ int Monitor::PrimeCapture() { Debug(1, "Creating decoder thread"); decoder = zm::make_unique(this); } else { - Debug(1, "Restartg decoder thread"); + Debug(1, "Restarting decoder thread"); decoder->Start(); } } From 874552c06b2de7b5fd329d09a88bbd96febc3475 Mon Sep 17 00:00:00 2001 From: ColorfullyZhang <36832299+ColorfullyZhang@users.noreply.github.com> Date: Thu, 16 Sep 2021 14:41:24 +0800 Subject: [PATCH 035/174] Set mysql character set to utf8 explicitly to support chinese characters (or other special characters). --- src/zm_db.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zm_db.cpp b/src/zm_db.cpp index 0d499edbd..c6cc452b9 100644 --- a/src/zm_db.cpp +++ b/src/zm_db.cpp @@ -102,6 +102,7 @@ bool zmDbConnect() { if ( mysql_query(&dbconn, "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED") ) { Error("Can't set isolation level: %s", mysql_error(&dbconn)); } + mysql_set_character_set(&dbconn, "utf8"); zmDbConnected = true; return zmDbConnected; } From 9e4f203632bad8193f07bd9cc64834a00a9b684d Mon Sep 17 00:00:00 2001 From: ColorfullyZhang <36832299+ColorfullyZhang@users.noreply.github.com> Date: Thu, 16 Sep 2021 18:24:37 +0800 Subject: [PATCH 036/174] Set character set as utf8 when connect to mysql to avoid mistakes when there are Chinese characters in storage path. --- scripts/ZoneMinder/lib/ZoneMinder/Database.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm index 18df301f3..35d2dc6fa 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm @@ -107,6 +107,7 @@ sub zmDbConnect { .$socket . $sslOptions . ($options?join(';', '', map { $_.'='.$$options{$_} } keys %{$options} ) : '') , $ZoneMinder::Config::Config{ZM_DB_USER} , $ZoneMinder::Config::Config{ZM_DB_PASS} + , { mysql_enable_utf8 => 1, } ); }; if ( !$dbh or $@ ) { From 0bf417bae0736673ce987d2924a8f610b89b0eaf Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 16 Sep 2021 10:03:21 -0400 Subject: [PATCH 037/174] Reduce logging level to debug dealing with index == -1, which is used in zmu to mean the last captured image. Fixes #3354 --- src/zm_monitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 9a5144623..723d4f7b5 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1153,7 +1153,7 @@ void Monitor::AddPrivacyBitmask() { int Monitor::GetImage(int32_t index, int scale) { if (index < 0 || index > image_buffer_count) { - Warning("Invalid index %d passed. image_buffer_count = %d", index, image_buffer_count); + Debug(1, "Invalid index %d passed. image_buffer_count = %d", index, image_buffer_count); index = shared_data->last_write_index; } if (!image_buffer.size() or static_cast(index) >= image_buffer.size()) { From e75d5a89e928c9f47a6e3ac17027498e5e0eedc8 Mon Sep 17 00:00:00 2001 From: Andrea Vezzali Date: Mon, 20 Sep 2021 14:02:35 +0200 Subject: [PATCH 038/174] Update italian (it_it) translation (#3357) --- web/lang/it_it.php | 105 +++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/web/lang/it_it.php b/web/lang/it_it.php index 4cdb24ee9..55fb3b34a 100644 --- a/web/lang/it_it.php +++ b/web/lang/it_it.php @@ -184,46 +184,46 @@ $SLANG = array( 'Brightness' => 'Luminosità', 'Buffer' => 'Buffer', // Added - 2015-04-18 'Buffers' => 'Buffers', - 'CSSDescription' => 'Change the default css for this computer', // Added - 2015-04-18 - 'CanAutoFocus' => 'Può Auto Focus', - 'CanAutoGain' => 'Può Auto Gains', - 'CanAutoIris' => 'Può Auto Iris', - 'CanAutoWhite' => 'Può Auto bil bianco', - 'CanAutoZoom' => 'Può Auto Zoom', - 'CanFocus' => 'Può Fuoco', - 'CanFocusAbs' => 'Può Fuoco Assoluto', - 'CanFocusCon' => 'Può Fuoco Continuo ', - 'CanFocusRel' => 'Può Fuoco Relativo', - 'CanGain' => 'Può Gain ', - 'CanGainAbs' => 'Può Gain Assoluto', - 'CanGainCon' => 'Può Gain Continuo ', - 'CanGainRel' => 'Può Gain Relativo', - 'CanIris' => 'Può Iris', - 'CanIrisAbs' => 'Può Iris Assoluto', - 'CanIrisCon' => 'Può Iris Continuo ', - 'CanIrisRel' => 'Può Iris Relativo', - 'CanMove' => 'Può Mov.', - 'CanMoveAbs' => 'Può Mov. Assoluto', - 'CanMoveCon' => 'Può Mov. Continuo ', - 'CanMoveDiag' => 'Può Mov. Diagonale ', - 'CanMoveMap' => 'Può Mov Mappato', - 'CanMoveRel' => 'Può Mov. Relativo', - 'CanPan' => 'Può Pan' , - 'CanReset' => 'Può Reset', - 'CanReboot' => 'Può Riavviare', - 'CanSetPresets' => 'Può impostare preset', - 'CanSleep' => 'Può andare in sleep', + 'CSSDescription' => 'Modificare il css predefinito per questo computer', // Added - 2015-04-18 + 'CanAutoFocus' => 'Può impostare Auto Focus', + 'CanAutoGain' => 'Può impostare Auto Gains', + 'CanAutoIris' => 'Può impostare Auto Iris', + 'CanAutoWhite' => 'Può impostare Auto bil bianco', + 'CanAutoZoom' => 'Può impostare Auto Zoom', + 'CanFocus' => 'Può impostare Fuoco', + 'CanFocusAbs' => 'Può impostare Fuoco Assoluto', + 'CanFocusCon' => 'Può impostare Fuoco Continuo', + 'CanFocusRel' => 'Può impostare Fuoco Relativo', + 'CanGain' => 'Può impostare Guadagno', + 'CanGainAbs' => 'Può impostare Guadagno Assoluto', + 'CanGainCon' => 'Può impostare Guadagno Continuo ', + 'CanGainRel' => 'Può impostare Guadagno Relativo', + 'CanIris' => 'Può impostare Iride', + 'CanIrisAbs' => 'Può impostare Iride Assoluto', + 'CanIrisCon' => 'Può impostare Iride Continuo', + 'CanIrisRel' => 'Può impostare Iride Relativo', + 'CanMove' => 'Può impostare Movimento', + 'CanMoveAbs' => 'Può impostare Movimento Assoluto', + 'CanMoveCon' => 'Può impostare Movimento Continuo', + 'CanMoveDiag' => 'Può impostare Movimento Diagonale', + 'CanMoveMap' => 'Può impostare Movimento Mappato', + 'CanMoveRel' => 'Può impostare Movimento Relativo', + 'CanPan' => 'Può impostare Panoramica' , + 'CanReset' => 'Può effettuare Reset', + 'CanReboot' => 'Può Riavviare', + 'CanSetPresets' => 'Può impostare Preset', + 'CanSleep' => 'Può sospendere', 'CanTilt' => 'Può inclinare', - 'CanWake' => 'Può essere riattivato', + 'CanWake' => 'Può riattivare', 'CanWhite' => 'Può bilanciare il bianco', 'CanWhiteAbs' => 'Può bilanciare il bianco assoluto', 'CanWhiteBal' => 'Può bilanciare il bianco', 'CanWhiteCon' => 'Può bilanciare il bianco Continuo', 'CanWhiteRel' => 'Può bilanciare il bianco Relativo', - 'CanZoom' => 'Può Zoom', - 'CanZoomAbs' => 'Può Zoom Assoluto', - 'CanZoomCon' => 'Può Zoom Continuo', - 'CanZoomRel' => 'Può Zoom Relativo', + 'CanZoom' => 'Può impostare Zoom', + 'CanZoomAbs' => 'Può impostare Zoom Assoluto', + 'CanZoomCon' => 'Può impostare Zoom Continuo', + 'CanZoomRel' => 'Può impostare Zoom Relativo', 'Cancel' => 'Annulla', 'CancelForcedAlarm' => 'Annulla Allarme Forzato', 'CaptureHeight' => 'Altezza Cattura Immagine', @@ -401,6 +401,7 @@ $SLANG = array( 'HasZoomSpeed' => 'Ha velocità di zoom', 'High' => 'Alta', 'HighBW' => 'Banda Alta', + 'Hight' => 'Altezza', 'Home' => 'Home', 'Hostname' => 'Nome Host', // Added - 2018-08-30 'Hour' => 'Ora', @@ -508,10 +509,10 @@ $SLANG = array( 'Mode' => 'Modalità', // Added - 2015-04-18 'Monitor' => 'Monitor', 'MonitorIds' => 'Monitor Ids', - 'MonitorPreset' => 'Monitor Presenti', - 'MonitorPresetIntro' => 'Selezionare un appropriato pre settaggio dalla lista riportata qui sotto.

Per favore notare che questo potrebbe sovrascrivere ogni valore che hai già configurato su questo monitor.

', + 'MonitorPreset' => 'Monitor Preset', + 'MonitorPresetIntro' => 'Selezionare un preset appropriato dalla lista riportata qui sotto.

Notare che questo potrebbe sovrascrivere ogni valore che hai già configurato su questo monitor.

', 'MonitorProbe' => 'Prova Monitor', // Added - 2009-03-31 - 'MonitorProbeIntro' => 'The list below shows detected analog and network cameras and whether they are already being used or available for selection.

Select the desired entry from the list below.

Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.

', // Added - 2009-03-31 + 'MonitorProbeIntro' => 'L\'elenco seguente mostra le telecamere analogiche e di rete rilevate e se sono già in uso o disponibili per la selezione.

Selezionare la voce desiderata dall\'elenco seguente.

Si noti che non tutte le telecamere possono essere rilevate e che la scelta di una telecamera qui potrebbe sovrascrivere tutti i valori già configurati per il monitor corrente.

', // Added - 2009-03-31 'Monitors' => 'Monitors', 'Montage' => 'Montaggio', 'MontageReview' => 'Revisione del montaggio', // Added - 2018-08-30 @@ -661,16 +662,17 @@ $SLANG = array( 'SelectMonitors' => 'Monitor Selezionati', 'SelfIntersecting' => 'I vertici del poligono non devono intersecarsi', 'Set' => 'Imposta', - 'SetNewBandwidth' => 'Imposta nuova Banda', - 'SetPreset' => 'Imposta Preset', + 'SetNewBandwidth' => 'Imposta Nuova Banda', + 'SetPreset' => 'Imposta Predefiniti', 'Settings' => 'Impostazioni', - 'ShowFilterWindow' => 'MostraFinestraFiltri', + 'ShowFilterWindow' => 'Mostra Finestra Filtri', 'ShowTimeline' => 'Mostra linea temporale', + 'Show Zones' => 'Visualizza Zone', 'SignalCheckColour' => 'Colore controllo segnale', 'SignalCheckPoints' => 'Punti di controllo segnale', // Added - 2018-08-30 'Size' => 'grandezza', 'SkinDescription' => 'Cambia la skin predefinita per questo computer', // Added - 2011-01-30 - 'Sleep' => 'Sleep', + 'Sleep' => 'Sospendi', 'SortAsc' => 'Crescente', 'SortBy' => 'Ordina per', 'SortDesc' => 'Decrescente', @@ -747,7 +749,7 @@ $SLANG = array( 'UseFilter' => 'Usa Filtro', 'UseFilterExprsPost' => ' espressioni filtri', // This is used at the end of the phrase 'use N filter expressions' 'UseFilterExprsPre' => 'Usa ', // This is used at the beginning of the phrase 'use N filter expressions' - 'UsedPlugins' => 'Plugins in uso', + 'UsedPlugins' => 'Plugins in uso', 'User' => 'Utente', 'Username' => 'Nome Utente', 'Users' => 'Utenti', @@ -784,6 +786,7 @@ $SLANG = array( 'White' => 'Bianco', 'WhiteBalance' => 'Bilanciamento del Bianco', 'Wide' => 'Larghezza', + 'Width' => 'Larghezza', 'X' => 'X', 'X10' => 'X10', 'X10ActivationString' => 'Stringa attivazione X10', @@ -937,17 +940,17 @@ function zmVlang( $langVarArray, $count ) // So for example, to override the help text for ZM_LANG_DEFAULT do $OLANG = array( 'OPTIONS_FFMPEG' => array( - 'Help' => "Parameters in this field are passed on to FFmpeg. Multiple parameters can be separated by ,~~ ". - "Examples (do not enter quotes)~~~~". - "\"allowed_media_types=video\" Set datatype to request fromcam (audio, video, data)~~~~". - "\"reorder_queue_size=nnn\" Set number of packets to buffer for handling of reordered packets~~~~". - "\"loglevel=debug\" Set verbosity of FFmpeg (quiet, panic, fatal, error, warning, info, verbose, debug)" + 'Help' => "I parametri in questo campo vengono passati a FFmpeg. Più parametri possono essere separati da ,~~ ". + "Esempi (non inserire virgolette)~~~~". + "\"allowed_media_types=video\" Imposta il tipo di dati da richiedere dalla telecamera (audio, video, data)~~~~". + "\"reorder_queue_size=nnn\" Imposta il numero di pacchetti nel buffer per la gestione dei pacchetti riordinati~~~~". + "\"loglevel=debug\" Imposta la verbosità di FFmpeg (quiet, panic, fatal, error, warning, info, verbose, debug)" ), 'OPTIONS_LIBVLC' => array( - 'Help' => "Parameters in this field are passed on to libVLC. Multiple parameters can be separated by ,~~ ". - "Examples (do not enter quotes)~~~~". - "\"--rtp-client-port=nnn\" Set local port to use for rtp data~~~~". - "\"--verbose=2\" Set verbosity of libVLC" + 'Help' => "I parametri in questo campo vengono passati a libVLC. Più parametri possono essere separati da ,~~ ". + "Esempi (non inserire virgolette)~~~~". + "\"--rtp-client-port=nnn\" Imposta la porta locale da utilizzare per i dati RTP~~~~". + "\"--verbose=2\" Imposta la verbosità di of libVLC" ), From d81be9701a64a61a603dc0be58ca60d080ad9584 Mon Sep 17 00:00:00 2001 From: 5472qaywsx <39193575+5472qaywsx@users.noreply.github.com> Date: Mon, 20 Sep 2021 14:04:07 +0200 Subject: [PATCH 039/174] Docs: Fix a typo (#3358) --- docs/installationguide/packpack.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installationguide/packpack.rst b/docs/installationguide/packpack.rst index fc1d6c077..64a6b4004 100644 --- a/docs/installationguide/packpack.rst +++ b/docs/installationguide/packpack.rst @@ -77,7 +77,7 @@ To start the build, simply execute the following command from the root folder of OS= DIST= utils/packpack/startpackpack.sh -Where is the name of the distro you wish to build on, such as fedora, and is release name or number of the distro you wish to build on. Redhat distros expect a number for while Debian and Ubuntu distros expect a name. For example: +Where is the name of the distro you wish to build on, such as fedora, and is the release name or number of the distro you wish to build on. Redhat distros expect a number for while Debian and Ubuntu distros expect a name. For example: :: From 2a0ddc6337c4b46ac859a0ffa6179e20d5b34dfc Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 20 Sep 2021 13:48:13 -0400 Subject: [PATCH 040/174] Add open collective username --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 8804e639c..5994f0e6b 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -2,7 +2,7 @@ github: [connortechnology,pliablepixels] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: zoneminder # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username +open_collective: zoneminder # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry From 4bdf965dcb453273069dd0f4ce7a8233064f41f2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 20 Sep 2021 16:02:37 -0400 Subject: [PATCH 041/174] Set rows on email textarea --- web/skins/classic/views/filter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php index efb3eed15..60cc585d4 100644 --- a/web/skins/classic/views/filter.php +++ b/web/skins/classic/views/filter.php @@ -493,7 +493,7 @@ if ( ZM_OPT_EMAIL ) {

- +

Date: Tue, 21 Sep 2021 12:59:42 -0400 Subject: [PATCH 042/174] Always include the download button so that we can assume that it exists in the js. So avoid console errors when no mp4. --- web/skins/classic/views/event.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/web/skins/classic/views/event.php b/web/skins/classic/views/event.php index 81ff15075..a07c95042 100644 --- a/web/skins/classic/views/event.php +++ b/web/skins/classic/views/event.php @@ -149,13 +149,10 @@ if ( $Event->Id() and !file_exists($Event->Path()) ) -DefaultVideo() ) { -?> - - + DefaultVideo() ? '' : 'style="display:none;"' ?> +> From 92f6d3cbae0e41ffe4f093b593ce117b14720cab Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 21 Sep 2021 13:00:47 -0400 Subject: [PATCH 043/174] Restore the download button's behaviour. It is a simple link to the mp4, not an export. Also add a handler for the video.js rate control to sync up our non video.js rate dropdown and stored cookie. --- web/skins/classic/views/js/event.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/web/skins/classic/views/js/event.js b/web/skins/classic/views/js/event.js index e2d3c9ce3..727976e76 100644 --- a/web/skins/classic/views/js/event.js +++ b/web/skins/classic/views/js/event.js @@ -891,6 +891,12 @@ function initPage() { vid.on('timeupdate', function() { $j('#progressValue').html(secsToTime(Math.floor(vid.currentTime()))); }); + vid.on('ratechange', function() { + rate = vid.playbackRate() * 100; + console.log("rate change " + rate); + $j('select[name="rate"]').val(rate); + setCookie('zmEventRate', rate, 3600); + }); // rate is in % so 100 would be 1x if (rate > 0) { @@ -1012,19 +1018,6 @@ function initPage() { window.location.assign('?view=export&eids[]='+eventData.Id); }); - // Manage the DOWNLOAD VIDEO button - bindButton('#downloadBtn', 'click', null, function onDownloadClick(evt) { - evt.preventDefault(); - $j.getJSON(thisUrl + '?request=modal&modal=download&eids[]='+eventData.Id) - .done(function(data) { - insertModalHtml('downloadModal', data.html); - $j('#downloadModal').modal('show'); - // Manage the GENERATE DOWNLOAD button - $j('#exportButton').click(exportEvent); - }) - .fail(logAjaxFail); - }); - // Manage the Event STATISTICS Button bindButton('#statsBtn', 'click', null, function onStatsClick(evt) { evt.preventDefault(); From 568be3fc549f2e8d258077982494c82c560bc135 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 21 Sep 2021 14:29:05 -0400 Subject: [PATCH 044/174] initialize video_first_pts and when setting it need to specify microseconds otherwise we get nanoseconds. White space. --- src/zm_ffmpeg_camera.cpp | 4 ++-- src/zm_packet.cpp | 2 +- src/zm_packet.h | 3 ++- src/zm_videostore.cpp | 8 +++++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 1484d5234..82471c3dc 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -231,8 +231,8 @@ int FfmpegCamera::Capture(std::shared_ptr &zm_packet) { zm_packet->set_packet(&packet); zm_packet->stream = stream; zm_packet->pts = av_rescale_q(packet.pts, stream->time_base, AV_TIME_BASE_Q); - if ( packet.pts != AV_NOPTS_VALUE ) { - if ( stream == mVideoStream ) { + if (packet.pts != AV_NOPTS_VALUE) { + if (stream == mVideoStream) { if (mFirstVideoPTS == AV_NOPTS_VALUE) mFirstVideoPTS = packet.pts; diff --git a/src/zm_packet.cpp b/src/zm_packet.cpp index 3361667e0..55a78721e 100644 --- a/src/zm_packet.cpp +++ b/src/zm_packet.cpp @@ -83,7 +83,7 @@ ZMPacket::ZMPacket(ZMPacket &p) : av_init_packet(&packet); packet.size = 0; packet.data = nullptr; - if ( zm_av_packet_ref(&packet, &p.packet) < 0 ) { + if (zm_av_packet_ref(&packet, &p.packet) < 0) { Error("error refing packet"); } } diff --git a/src/zm_packet.h b/src/zm_packet.h index 66a6250ca..9cce4dd03 100644 --- a/src/zm_packet.h +++ b/src/zm_packet.h @@ -66,7 +66,7 @@ class ZMPacket { Image *set_image(Image *); int is_keyframe() { return keyframe; }; - int decode( AVCodecContext *ctx ); + int decode(AVCodecContext *ctx); explicit ZMPacket(Image *image, SystemTimePoint tv); explicit ZMPacket(ZMPacket &packet); ZMPacket(); @@ -88,6 +88,7 @@ class ZMLockedPacket { lck_(packet_->mutex_, std::defer_lock), locked(false) { } + ~ZMLockedPacket() { if (locked) unlock(); } diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 67f31cabc..1bd0724d5 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -93,6 +93,7 @@ VideoStore::VideoStore( converted_in_samples(nullptr), filename(filename_in), format(format_in), + video_first_pts(0), video_first_dts(0), audio_first_pts(0), audio_first_dts(0), @@ -990,23 +991,24 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr &zm_packet frame->pkt_duration = 0; if (!video_first_pts) { - video_first_pts = zm_packet->timestamp.time_since_epoch().count(); + video_first_pts = static_cast(std::chrono::duration_cast(zm_packet->timestamp.time_since_epoch()).count()); Debug(2, "No video_first_pts, set to (%" PRId64 ") secs(%.2f)", video_first_pts, FPSeconds(zm_packet->timestamp.time_since_epoch()).count()); frame->pts = 0; } else { + Microseconds useconds = std::chrono::duration_cast( zm_packet->timestamp - SystemTimePoint(Microseconds(video_first_pts))); frame->pts = av_rescale_q(useconds.count(), AV_TIME_BASE_Q, video_out_ctx->time_base); Debug(2, - "Setting pts for frame(%d) to (%" PRId64 ") from (start %" PRIu64 " - %" PRIu64 " - us(%" PRIi64 ") @ %d/%d", + "Setting pts for frame(%d) to (%" PRId64 ") from (zm_packet->timestamp(%" PRIi64 " - first %" PRId64 " us %" PRId64 " ) @ %d/%d", frame_count, frame->pts, + static_cast(std::chrono::duration_cast(zm_packet->timestamp.time_since_epoch()).count()), video_first_pts, static_cast(std::chrono::duration_cast(useconds).count()), - static_cast(std::chrono::duration_cast(zm_packet->timestamp.time_since_epoch()).count()), video_out_ctx->time_base.num, video_out_ctx->time_base.den); } From e98728c529a2f541b8fc59914c1b75ed7c8b1681 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 23 Sep 2021 16:04:36 -0400 Subject: [PATCH 045/174] Set new defaults for various settings --- scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index 0c8aec4a2..31d92bf11 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -308,7 +308,7 @@ our @options = ( }, { name => 'ZM_AUTH_HASH_IPS', - default => 'yes', + default => 'no', description => 'Include IP addresses in the authentication hash', help => q` When ZoneMinder is running in hashed authenticated mode it can @@ -346,7 +346,7 @@ our @options = ( }, { name => 'ZM_AUTH_HASH_LOGINS', - default => 'no', + default => 'yes', description => 'Allow login by authentication hash', help => q` The normal process for logging into ZoneMinder is via the login @@ -508,7 +508,7 @@ our @options = ( }, { name => 'ZM_SYSTEM_SHUTDOWN', - default => 'yes', + default => 'no', description => 'Allow Admin users to power off or restart the system from the ZoneMinder UI.', help => 'The system will need to have sudo installed and the following added to /etc/sudoers~~ ~~ @@ -1096,7 +1096,7 @@ our @options = ( }, { name => 'ZM_LOG_LEVEL_SYSLOG', - default => '0', + default => '-1', description => 'Save logging output to the system log', help => q` ZoneMinder logging is now more integrated between @@ -1604,7 +1604,7 @@ our @options = ( }, { name => 'ZM_WEB_EVENT_DISK_SPACE', - default => 'no', + default => 'yes', description => 'Whether to show disk space used by each event.', help => q` Adds another column to the listing of events @@ -1634,7 +1634,7 @@ our @options = ( }, { name => 'ZM_WEB_ID_ON_CONSOLE', - default => 'no', + default => 'yes', description => 'Should the console list the monitor id', help => q` Some find it useful to have the id always visible @@ -2270,7 +2270,7 @@ our @options = ( }, { name => 'ZM_MAX_RESTART_DELAY', - default => '600', + default => '30', description => 'Maximum delay (in seconds) for daemon restart attempts.', help => q` The zmdc (zm daemon control) process controls when processeses From b8022cdda266817191e01d768080455f02829ddb Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 23 Sep 2021 16:06:18 -0400 Subject: [PATCH 046/174] More new defaults. The navbar refreshes every 60 secs so make full page refresh be 240sec. Ajax timeout needs to be 10 seconds. Large event listings can take longer than 3 --- scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index 31d92bf11..ff802dd15 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -2855,7 +2855,7 @@ our @options = ( }, { name => 'ZM_WEB_H_REFRESH_MAIN', - default => '60', + default => '240', introduction => q` There are now a number of options that are grouped into bandwidth categories, this allows you to configure the @@ -3113,7 +3113,7 @@ our @options = ( }, { name => 'ZM_WEB_H_AJAX_TIMEOUT', - default => '3000', + default => '10000', description => 'How long to wait for Ajax request responses (ms)', help => q` The newer versions of the live feed and event views use Ajax to From 655daf4fbeaac2821e23c0ca8b28073a77d1ab30 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 23 Sep 2021 16:39:28 -0400 Subject: [PATCH 047/174] Add mmal device/pix fmt type --- src/zm_ffmpeg_camera.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 82471c3dc..6415b2134 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -55,31 +55,24 @@ static enum AVPixelFormat get_hw_format( } #if !LIBAVUTIL_VERSION_CHECK(56, 22, 0, 14, 0) static enum AVPixelFormat find_fmt_by_hw_type(const enum AVHWDeviceType type) { - enum AVPixelFormat fmt; switch (type) { case AV_HWDEVICE_TYPE_VAAPI: - fmt = AV_PIX_FMT_VAAPI; - break; + return AV_PIX_FMT_VAAPI; case AV_HWDEVICE_TYPE_DXVA2: - fmt = AV_PIX_FMT_DXVA2_VLD; - break; + return AV_PIX_FMT_DXVA2_VLD; case AV_HWDEVICE_TYPE_D3D11VA: - fmt = AV_PIX_FMT_D3D11; - break; + return = AV_PIX_FMT_D3D11; case AV_HWDEVICE_TYPE_VDPAU: - fmt = AV_PIX_FMT_VDPAU; - break; + return AV_PIX_FMT_VDPAU; case AV_HWDEVICE_TYPE_CUDA: - fmt = AV_PIX_FMT_CUDA; - break; + return AV_PIX_FMT_CUDA; + case AV_HWDEVICE_TYPE_MMAL: + return AV_PIX_FMT_MMAL; case AV_HWDEVICE_TYPE_VIDEOTOOLBOX: - fmt = AV_PIX_FMT_VIDEOTOOLBOX; - break; + return AV_PIX_FMT_VIDEOTOOLBOX; default: - fmt = AV_PIX_FMT_NONE; - break; + return AV_PIX_FMT_NONE; } - return fmt; } #endif #endif From 2e4bb73204b977123a72aef4784dfa890c1ea8a3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 14:27:10 -0400 Subject: [PATCH 048/174] remove useless commit. --- scripts/zmfilter.pl.in | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 64a20b4d5..1e62cb229 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -399,7 +399,6 @@ sub checkFilter { ) { $Event->save(); } - $ZoneMinder::Database::dbh->commit() if !$$filter{LockRows}; } # end if UpdateDiskSpace } # end foreach event ZoneMinder::Database::end_transaction($dbh, $in_transaction) if $$filter{LockRows}; From cbc376bb5a9df2f3b1d6cf02d5452c73053d7c17 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 16:08:58 -0400 Subject: [PATCH 049/174] Add zm_rtsp_server to ignores --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e617d937c..3d61b4f54 100644 --- a/.gitignore +++ b/.gitignore @@ -124,6 +124,7 @@ src/zmc src/zmf src/zms src/zmu +src/zm_rtsp_server src/zoneminder-zmc.8 src/zoneminder-zmc.8.gz src/zoneminder-zmf.8 From 43dfeb5b847fa47fbe191de7e1a00b2fe16b6891 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 16:10:50 -0400 Subject: [PATCH 050/174] whitespace --- web/skins/classic/views/monitor.php | 32 +++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 327de5def..e7afc8cf6 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -21,44 +21,50 @@ require_once('includes/Server.php'); require_once('includes/Storage.php'); -if ( !canEdit('Monitors', empty($_REQUEST['mid'])?0:$_REQUEST['mid']) ) { +if (!canEdit('Monitors', empty($_REQUEST['mid'])?0:$_REQUEST['mid'])) { $view = 'error'; return; } $Server = null; -if ( defined('ZM_SERVER_ID') ) { +if (defined('ZM_SERVER_ID')) { $Server = dbFetchOne('SELECT * FROM Servers WHERE Id=?', NULL, array(ZM_SERVER_ID)); } -if ( !$Server ) { +if (!$Server) { $Server = array('Id' => ''); } $mid = null; $monitor = null; -if ( !empty($_REQUEST['mid']) ) { +if (!empty($_REQUEST['mid'])) { $mid = validInt($_REQUEST['mid']); $monitor = new ZM\Monitor($mid); - if ( $monitor and ZM_OPT_X10 ) - $x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($mid)); + if ($monitor->Id()) { + if (ZM_OPT_X10) { + $x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($mid)); + } + } else { + $monitor->Name(translate('Monitor').'-'.$mid); + $monitor->WebColour(random_colour()); + } } -if ( !$monitor ) { +if (!$monitor) { $monitor = new ZM\Monitor(); $monitor->Name(translate('Monitor').'-'.getTableAutoInc('Monitors')); $monitor->WebColour(random_colour()); } # end if $_REQUEST['mid'] -if ( isset($_REQUEST['dupId']) ) { +if (isset($_REQUEST['dupId'])) { $monitor = new ZM\Monitor($_REQUEST['dupId']); $monitor->GroupIds(); // have to load before we change the Id - if ( ZM_OPT_X10 ) + if (ZM_OPT_X10) $x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['dupId'])); $clonedName = $monitor->Name(); $monitor->Name('Clone of '.$monitor->Name()); $monitor->Id($mid); } -if ( ZM_OPT_X10 && empty($x10Monitor) ) { +if (ZM_OPT_X10 && empty($x10Monitor)) { $x10Monitor = array( 'Activation' => '', 'AlarmInput' => '', @@ -69,14 +75,14 @@ if ( ZM_OPT_X10 && empty($x10Monitor) ) { function fourcc($a, $b, $c, $d) { return ord($a) | (ord($b) << 8) | (ord($c) << 16) | (ord($d) << 24); } -if ( isset($_REQUEST['newMonitor']) ) { +if (isset($_REQUEST['newMonitor'])) { # Update the monitor object with whatever has been set so far. $monitor->set($_REQUEST['newMonitor']); - if ( ZM_OPT_X10 ) + if (ZM_OPT_X10) $newX10Monitor = $_REQUEST['newX10Monitor']; } else { - if ( ZM_OPT_X10 ) + if (ZM_OPT_X10) $newX10Monitor = $x10Monitor; } From f40e2be28a4238ce104c155a4fd71389233d9670 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 25 Sep 2021 20:54:35 -0400 Subject: [PATCH 051/174] Add an input for an Id to assign to the new monitor. List 10 available Ids. --- web/skins/classic/views/monitor.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index e7afc8cf6..05462ace9 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -355,6 +355,7 @@ $codecs = array( 'MJPEG' => translate('MJPEG'), ); +$monitors = dbFetchAll('SELECT Id, Name FROM Monitors ORDER BY Name,Sequence ASC'); $controls = ZM\Control::find(null, array('order'=>'lower(Name)')); xhtmlHeaders(__FILE__, translate('Monitor').' - '.validHtmlStr($monitor->Name())); @@ -452,6 +453,21 @@ foreach ( $tabs as $name=>$value ) { switch ( $name ) { case 'general' : { + if (!$monitor->Id()) { + $monitor_ids = array(); + foreach ($monitors as $m) { $monitor_ids[] = $m['Id']; } + $available_monitor_ids = array_diff(range(min($monitor_ids),max($monitor_ids)), $monitor_ids); +?> + + +
+10 Available Ids: + + + +Id() ?> @@ -559,7 +575,6 @@ switch ( $name ) { Id() || ($monitor->Id()!= $linked_monitor['Id'])) && visibleMonitor($linked_monitor['Id']) ) { From ee609ad28bdeeec89f27b3c3c7d40f2fdfc040b3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 26 Sep 2021 14:46:56 -0400 Subject: [PATCH 052/174] Further develop behavour when typing in text input for new manufacturer or model. If it already exists, select it. --- web/skins/classic/views/js/monitor.js | 49 ++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/web/skins/classic/views/js/monitor.js b/web/skins/classic/views/js/monitor.js index 44bcddb5b..88fae0a67 100644 --- a/web/skins/classic/views/js/monitor.js +++ b/web/skins/classic/views/js/monitor.js @@ -346,7 +346,7 @@ function getLocation() { } function populate_models(ManufacturerId) { - let dropdown = $j('[name="newMonitor[ModelId]"]'); + const dropdown = $j('[name="newMonitor[ModelId]"]'); if (!dropdown.length) { console.log("No element found for ModelId"); return; @@ -356,18 +356,22 @@ function populate_models(ManufacturerId) { dropdown.append(''); dropdown.prop('selectedIndex', 0); - // Populate dropdown with list of provinces - $j.getJSON(thisUrl+'?request=models&ManufacturerId='+ManufacturerId, function (data) { + if (ManufacturerId) { + // Populate dropdown with list of provinces + $j.getJSON(thisUrl+'?request=models&ManufacturerId='+ManufacturerId, function(data) { if (data.result == 'Ok') { - $j.each(data.models, function (key, entry) { - dropdown.append($j('').attr('value', entry.Id).text(entry.Name)); - }); + $j.each(data.models, function(key, entry) { + dropdown.append($j('').attr('value', entry.Id).text(entry.Name)); + }); dropdown.chosen("destroy"); dropdown.chosen(); } else { alert(data.result); } - }); + }); + } + dropdown.chosen("destroy"); + dropdown.chosen(); } function ManufacturerId_onchange(ManufacturerId_select) { @@ -377,7 +381,7 @@ function ManufacturerId_onchange(ManufacturerId_select) { } else { ManufacturerId_select.form.elements['newMonitor[Manufacturer]'].style['display'] = 'inline'; // Set models dropdown to Unknown, text area visible - let ModelId_dropdown = $j('[name="newMonitor[ModelId]"]'); + const ModelId_dropdown = $j('[name="newMonitor[ModelId]"]'); ModelId_dropdown.empty(); ModelId_dropdown.append(''); ModelId_dropdown.prop('selectedIndex', 0); @@ -385,6 +389,31 @@ function ManufacturerId_onchange(ManufacturerId_select) { } } +function select_by_value_case_insensitive(dropdown, value) { + const test_value = value.toLowerCase(); + for (i=1; i < dropdown.options.length; i++) { + if (dropdown.options[i].text.toLowerCase() == test_value) { + dropdown.selectedIndex = i; + dropdown.options[i].selected = true; + $j(dropdown).chosen("destroy").chosen(); + return; + } + } + if (dropdown.selectedIndex != 0) { + dropdown.selectedIndex = 0; + $j(dropdown).chosen("destroy").chosen(); + } +} + +function Manufacturer_onchange(input) { + if (!input.value) { + return; + } + ManufacturerId_select = input.form.elements['newMonitor[ManufacturerId]']; + select_by_value_case_insensitive(ManufacturerId_select, input.value); + populate_models(ManufacturerId_select.value); +} + function ModelId_onchange(ModelId_select) { if (parseInt(ModelId_select.value)) { $j('[name="newMonitor[Model]"]').hide(); @@ -393,4 +422,8 @@ function ModelId_onchange(ModelId_select) { } } +function Model_onchange(input) { + select_by_value_case_insensitive(input.form.elements['newMonitor[ModelId]'], input.value); +} + window.addEventListener('DOMContentLoaded', initPage); From 1c01936f754b7cd4c72b9b01bb5ac9abef3f998d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 26 Sep 2021 14:47:29 -0400 Subject: [PATCH 053/174] add oninput methods to text inputs for new Manufacturer/Model --- web/skins/classic/views/monitor.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 05462ace9..f47e29912 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -482,7 +482,7 @@ switch ( $name ) { translate('unknown')); + $manufacturers = array(''=>translate('Unknown')); foreach ( ZM\Manufacturer::find( null, array('order'=>'lower(Name)')) as $Manufacturer ) { $manufacturers[$Manufacturer->Id()] = $Manufacturer->Name(); } @@ -492,6 +492,7 @@ switch ( $name ) { ManufacturerId() ? ' style="display:none"' : '' ?> + data-on-input-this="Manufacturer_onchange" /> @@ -500,7 +501,7 @@ switch ( $name ) { translate('unknown')); + $models = array(''=>translate('Unknown')); foreach ( ZM\Model::find(array('ManufacturerId'=>$monitor->ManufacturerId()), array('order'=>'lower(Name)')) as $Model ) { $models[$Model->Id()] = $Model->Name(); } @@ -509,7 +510,9 @@ switch ( $name ) { ?> ModelId() ? ' style="display:none"':'' ?>/> + value="Model()->Name() ?>"ModelId() ? ' style="display:none"':'' ?> + data-on-input-this="Model_onchange" + /> From fe734d4e1ec745aab4640de2f8f7ac3a413804de Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 27 Sep 2021 10:56:50 -0400 Subject: [PATCH 054/174] Add Manufacturer and CameraModel hasOne relationships --- web/api/app/Model/Monitor.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/api/app/Model/Monitor.php b/web/api/app/Model/Monitor.php index de9a7685a..7a7d03588 100644 --- a/web/api/app/Model/Monitor.php +++ b/web/api/app/Model/Monitor.php @@ -139,6 +139,16 @@ class Monitor extends AppModel { 'className' => 'Event_Summary', 'foreignKey' => 'MonitorId', 'joinTable' => 'Event_Summaries', + ), + 'Manufacturer' => array( + 'className' => 'Manufacturer', + 'foreignKey' => 'Id', + 'joinTable' => 'Manufacturers', + ), + 'CameraModel' => array( + 'className' => 'CameraModel', + 'foreignKey' => 'Id', + 'joinTable' => 'Models', ) ); From ee65d3e3dcf6f6e1a2b8fe8810cc2b7fa9ebbad6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 27 Sep 2021 10:57:06 -0400 Subject: [PATCH 055/174] add cmaeramodels route --- web/api/app/Config/routes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/api/app/Config/routes.php b/web/api/app/Config/routes.php index 6b3314d09..7c6352602 100644 --- a/web/api/app/Config/routes.php +++ b/web/api/app/Config/routes.php @@ -32,6 +32,7 @@ Router::mapResources('logs'); Router::mapResources('manufacturers'); Router::mapResources('models'); + Router::mapResources('cameramodels'); Router::mapResources('monitors'); Router::mapResources('servers'); Router::mapResources('states'); From 9cf4e892545e1460f7e5b4bc37e802a5cdebd76f Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 27 Sep 2021 11:03:16 -0400 Subject: [PATCH 056/174] add update to 1.37.3 --- db/zm_update-1.37.3.sql | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 db/zm_update-1.37.3.sql diff --git a/db/zm_update-1.37.3.sql b/db/zm_update-1.37.3.sql new file mode 100644 index 000000000..341c5e162 --- /dev/null +++ b/db/zm_update-1.37.3.sql @@ -0,0 +1,47 @@ +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ManufacturerId' + ) > 0, +"SELECT 'Column ManufacturerId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ManufacturerId` int(10) unsigned AFTER `StorageId`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ManufacturerId' + ) > 0, +"SELECT 'FOREIGN KEY for ManufacturerId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD FOREIGN KEY (`ManufacturerId`) REFERENCES `Manufacturers` (Id)" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ModelId' + ) > 0, +"SELECT 'Column ModelId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ModelId` int(10) unsigned AFTER `ManufacturerId`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ModelId' + ) > 0, +"SELECT 'FOREIGN KEY for ModelId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD FOREIGN KEY (`ModelId`) REFERENCES `Models` (Id)" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; From ac15ea42cd4d46968eda06269fd61841d8bf0fd0 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 19 Oct 2021 14:34:17 -0400 Subject: [PATCH 057/174] enforce default action --- utils/do_debian_package.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/utils/do_debian_package.sh b/utils/do_debian_package.sh index 2a4dd6989..6c8c06c00 100755 --- a/utils/do_debian_package.sh +++ b/utils/do_debian_package.sh @@ -230,12 +230,11 @@ rm .gitignore cd ../ -if [ !-e "$DIRECTORY.orig.tar.gz" ]; then -read -p "$DIRECTORY.orig.tar.gz does not exist, create it? [Y/n]" - if [[ $REPLY == [yY] ]]; then - - tar zcf $DIRECTORY.orig.tar.gz $DIRECTORY.orig -fi; +if [ ! -e "$DIRECTORY.orig.tar.gz" ]; then + read -p "$DIRECTORY.orig.tar.gz does not exist, create it? [Y/n]" + if [[ "$REPLY" == "" || "$REPLY" == [yY] ]]; then + tar zcf $DIRECTORY.orig.tar.gz $DIRECTORY.orig + fi; fi; IFS=',' ;for DISTRO in `echo "$DISTROS"`; do From a799eb3ad97e9b56687e83cf2181cad44ae128db Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 3 Nov 2021 17:01:11 -0400 Subject: [PATCH 058/174] add function get_codec to return the codec used in the output mp4 --- src/zm_videostore.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/zm_videostore.h b/src/zm_videostore.h index 682fc147b..c73ed19db 100644 --- a/src/zm_videostore.h +++ b/src/zm_videostore.h @@ -111,6 +111,13 @@ class VideoStore { int writePacket(const std::shared_ptr &pkt); int write_packets(PacketQueue &queue); void flush_codecs(); + const char *get_codec() { + if (chosen_codec_data) + return chosen_codec_data->codec_codec; + if (video_out_stream) + return avcodec_get_name(video_out_stream->codecpar->codec_id); + return ""; + } }; #endif // ZM_VIDEOSTORE_H From 814eca2b4f036e66f447f1d19c7ece21b9c2e5a9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 3 Nov 2021 17:02:02 -0400 Subject: [PATCH 059/174] Include the codec in the resulting mp4 filename. Remove event update setting the mp4 filename after insert, do it on event completing instead. Saves 1 db update. --- src/zm_event.cpp | 49 +++++++++++++++++++++++++++++------------------- src/zm_event.h | 7 ++++++- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 14b0fc9a3..442033c50 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -60,8 +60,8 @@ Event::Event( //snapshit_file(), //alarm_file(""), videoStore(nullptr), - //video_name(""), //video_file(""), + //video_path(""), last_db_frame(0), have_video_keyframe(false), //scheme @@ -104,6 +104,13 @@ Event::Event( // Copy it in case opening the mp4 doesn't work we can set it to another value save_jpegs = monitor->GetOptSaveJPEGs(); Storage * storage = monitor->getStorage(); + if (monitor->GetOptVideoWriter() != 0) { + container = monitor->OutputContainer(); + if ( container == "auto" || container == "" ) { + container = "mp4"; + } + video_incomplete_file = "incomplete."+container; + } std::string sql = stringtf( "INSERT INTO `Events` " @@ -120,7 +127,7 @@ Event::Event( state_id, monitor->getOrientation(), 0, - "", + video_incomplete_file.c_str(), save_jpegs, storage->SchemeString().c_str() ); @@ -178,24 +185,16 @@ Event::Event( } // end if ! setPath(Storage) Debug(1, "Using storage area at %s", path.c_str()); - video_name = ""; - snapshot_file = path + "/snapshot.jpg"; alarm_file = path + "/alarm.jpg"; - /* Save as video */ + video_incomplete_path = path + "/" + video_incomplete_file; - if ( monitor->GetOptVideoWriter() != 0 ) { - std::string container = monitor->OutputContainer(); - if ( container == "auto" || container == "" ) { - container = "mp4"; - } + if (monitor->GetOptVideoWriter() != 0) { + /* Save as video */ - video_name = stringtf("%" PRIu64 "-%s.%s", id, "video", container.c_str()); - video_file = path + "/" + video_name; - Debug(1, "Writing video file to %s", video_file.c_str()); videoStore = new VideoStore( - video_file.c_str(), + video_incomplete_path.c_str(), container.c_str(), monitor->GetVideoStream(), monitor->GetVideoCodecContext(), @@ -213,8 +212,10 @@ Event::Event( zmDbDo(sql); } } else { - sql = stringtf("UPDATE Events SET Videoed=1, DefaultVideo = '%s' WHERE Id=%" PRIu64, video_name.c_str(), id); - zmDbDo(sql); + std::string codec = videoStore->get_codec(); + video_file = stringtf("%" PRIu64 "-%s.%s.%s", id, "video", codec.c_str(), container.c_str()); + video_path = path + "/" + video_file; + Debug(1, "Video file is %s", video_file.c_str()); } } // end if GetOptVideoWriter } @@ -223,10 +224,18 @@ Event::~Event() { // We close the videowriter first, because if we finish the event, we might try to view the file, but we aren't done writing it yet. /* Close the video file */ - if ( videoStore != nullptr ) { + if (videoStore != nullptr) { Debug(4, "Deleting video store"); delete videoStore; videoStore = nullptr; + int result = rename(video_incomplete_path.c_str(), video_path.c_str()); + if (result == 0) { + Debug(1, "File successfully renamed"); + } else { + Error("Failed renaming %s to %s", video_incomplete_path.c_str(), video_path.c_str()); + // So that we don't update the event record + video_file = video_incomplete_file; + } } // endtime is set in AddFrame, so SHOULD be set to the value of the last frame timestamp. @@ -245,21 +254,23 @@ Event::~Event() { } std::string sql = stringtf( - "UPDATE Events SET Name='%s%" PRIu64 "', EndDateTime = from_unixtime(%ld), Length = %.2f, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64 " AND Name='New Event'", + "UPDATE Events SET Name='%s%" PRIu64 "', EndDateTime = from_unixtime(%ld), Length = %.2f, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo='%s' WHERE Id = %" PRIu64 " AND Name='New Event'", monitor->EventPrefix(), id, std::chrono::system_clock::to_time_t(end_time), delta_time.count(), frames, alarm_frames, tot_score, static_cast(alarm_frames ? (tot_score / alarm_frames) : 0), max_score, + video_file.c_str(), // defaults to "" id); if (!zmDbDoUpdate(sql)) { // Name might have been changed during recording, so just do the update without changing the name. sql = stringtf( - "UPDATE Events SET EndDateTime = from_unixtime(%ld), Length = %.2f, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64, + "UPDATE Events SET EndDateTime = from_unixtime(%ld), Length = %.2f, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo='%s' WHERE Id = %" PRIu64, std::chrono::system_clock::to_time_t(end_time), delta_time.count(), frames, alarm_frames, tot_score, static_cast(alarm_frames ? (tot_score / alarm_frames) : 0), max_score, + video_file.c_str(), // defaults to "" id); zmDbDoUpdate(sql); } // end if no changed rows due to Name change during recording diff --git a/src/zm_event.h b/src/zm_event.h index 8b8e49322..611b2f716 100644 --- a/src/zm_event.h +++ b/src/zm_event.h @@ -84,8 +84,13 @@ class Event { std::string alarm_file; VideoStore *videoStore; - std::string video_name; + std::string container; + std::string codec; std::string video_file; + std::string video_path; + std::string video_incomplete_file; + std::string video_incomplete_path; + int last_db_frame; bool have_video_keyframe; // a flag to tell us if we have had a video keyframe when writing an mp4. The first frame SHOULD be a video keyframe. Storage::Schemes scheme; From 93055f44e8bfd3a52d65fa348c5f1d1724091c83 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 3 Nov 2021 17:03:29 -0400 Subject: [PATCH 060/174] Merge UpdateCaptureFPS and UpdateAnalysisFPS into UpdateFPS and call it from zmc after capture. --- src/zm_monitor.cpp | 80 +++++++++------------------------------------- src/zm_monitor.h | 3 +- src/zmc.cpp | 3 +- 3 files changed, 18 insertions(+), 68 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 93ae2d026..679ea27b7 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1656,7 +1656,7 @@ void Monitor::CheckAction() { } } -void Monitor::UpdateCaptureFPS() { +void Monitor::UpdateFPS() { if ( fps_report_interval and ( !(image_count%fps_report_interval) @@ -1675,82 +1675,35 @@ void Monitor::UpdateCaptureFPS() { uint32 new_camera_bytes = camera->Bytes(); uint32 new_capture_bandwidth = static_cast((new_camera_bytes - last_camera_bytes) / elapsed.count()); - last_camera_bytes = new_camera_bytes; + double new_analysis_fps = (motion_frame_count - last_motion_frame_count) / elapsed.count(); - Debug(4, "%s: %d - last %d = %d now:%lf, last %lf, elapsed %lf = %lffps", - "Capturing", + Debug(4, "FPS: capture count %d - last capture count %d = %d now:%lf, last %lf, elapsed %lf = capture: %lf fps analysis: %lf fps", image_count, last_capture_image_count, image_count - last_capture_image_count, FPSeconds(now.time_since_epoch()).count(), - FPSeconds(last_analysis_fps_time.time_since_epoch()).count(), + FPSeconds(last_fps_time.time_since_epoch()).count(), elapsed.count(), - new_capture_fps); + new_capture_fps, + new_analysis_fps); - Info("%s: %d - Capturing at %.2lf fps, capturing bandwidth %ubytes/sec", - name.c_str(), image_count, new_capture_fps, new_capture_bandwidth); + Info("%s: %d - Capturing at %.2lf fps, capturing bandwidth %ubytes/sec Analysing at %.2lf fps", + name.c_str(), image_count, new_capture_fps, new_capture_bandwidth, new_analysis_fps); shared_data->capture_fps = new_capture_fps; last_fps_time = now; last_capture_image_count = image_count; + shared_data->analysis_fps = new_analysis_fps; + last_motion_frame_count = motion_frame_count; + last_camera_bytes = new_camera_bytes; std::string sql = stringtf( - "UPDATE LOW_PRIORITY Monitor_Status SET CaptureFPS = %.2lf, CaptureBandwidth=%u WHERE MonitorId=%u", - new_capture_fps, new_capture_bandwidth, id); + "UPDATE LOW_PRIORITY Monitor_Status SET CaptureFPS = %.2lf, CaptureBandwidth=%u, AnalysisFPS = %.2lf WHERE MonitorId=%u", + new_capture_fps, new_capture_bandwidth, new_analysis_fps, id); dbQueue.push(std::move(sql)); } // now != last_fps_time } // end if report fps -} // void Monitor::UpdateCaptureFPS() - -void Monitor::UpdateAnalysisFPS() { - Debug(1, "analysis_image_count(%d) motion_count(%d) fps_report_interval(%d) mod%d", - analysis_image_count, motion_frame_count, fps_report_interval, - ((analysis_image_count && fps_report_interval) ? !(analysis_image_count%fps_report_interval) : -1 ) ); - - if ( - ( analysis_image_count and fps_report_interval and !(analysis_image_count%fps_report_interval) ) - or - // In startup do faster updates - ( (analysis_image_count < fps_report_interval) and !(analysis_image_count%10) ) - ) { - SystemTimePoint now = std::chrono::system_clock::now(); - - FPSeconds elapsed = now - last_analysis_fps_time; - Debug(4, "%s: %d - now: %.2f, last %lf, diff %lf", - name.c_str(), - analysis_image_count, - FPSeconds(now.time_since_epoch()).count(), - FPSeconds(last_analysis_fps_time.time_since_epoch()).count(), - elapsed.count()); - - if (elapsed > Seconds(1)) { - double new_analysis_fps = (motion_frame_count - last_motion_frame_count) / elapsed.count(); - Info("%s: %d - Analysing at %.2lf fps from %d - %d=%d / %lf - %lf = %lf", - name.c_str(), - analysis_image_count, - new_analysis_fps, - motion_frame_count, - last_motion_frame_count, - (motion_frame_count - last_motion_frame_count), - FPSeconds(now.time_since_epoch()).count(), - FPSeconds(last_analysis_fps_time.time_since_epoch()).count(), - elapsed.count()); - - if (new_analysis_fps != shared_data->analysis_fps) { - shared_data->analysis_fps = new_analysis_fps; - - std::string sql = stringtf("UPDATE LOW_PRIORITY Monitor_Status SET AnalysisFPS = %.2lf WHERE MonitorId=%u", - new_analysis_fps, id); - dbQueue.push(std::move(sql)); - last_analysis_fps_time = now; - last_motion_frame_count = motion_frame_count; - } else { - Debug(4, "No change in fps"); - } // end if change in fps - } // end if at least 1 second has passed since last update - - } // end if time to do an update -} // end void Monitor::UpdateAnalysisFPS +} // void Monitor::UpdateFPS() // Would be nice if this JUST did analysis // This idea is that we should be analysing as close to the capture frame as possible. @@ -2299,8 +2252,6 @@ bool Monitor::Analyse() { // Only do these if it's a video packet. shared_data->last_read_index = snap->image_index; analysis_image_count++; - if (function == MODECT or function == MOCORD) - UpdateAnalysisFPS(); } packetqueue.increment_it(analysis_it); packetqueue.unlock(packet_lock); @@ -2585,7 +2536,6 @@ int Monitor::Capture() { // Will only be queued if there are iterators allocated in the queue. packetqueue.queuePacket(packet); - UpdateCaptureFPS(); } else { // result == 0 // Question is, do we update last_write_index etc? return 0; @@ -2625,7 +2575,7 @@ bool Monitor::Decode() { // //capture_image = packet->image = new Image(width, height, camera->Colours(), camera->SubpixelOrder()); int ret = packet->decode(camera->getVideoCodecContext()); - if (ret > 0) { + if (ret > 0 and !zm_terminate) { if (packet->in_frame and !packet->image) { packet->image = new Image(camera_width, camera_height, camera->Colours(), camera->SubpixelOrder()); AVFrame *input_frame = packet->in_frame; diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 92b724e65..56785405f 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -546,8 +546,7 @@ public: unsigned int GetLastWriteIndex() const; uint64_t GetLastEventId() const; double GetFPS() const; - void UpdateAnalysisFPS(); - void UpdateCaptureFPS(); + void UpdateFPS(); void ForceAlarmOn( int force_score, const char *force_case, const char *force_text="" ); void ForceAlarmOff(); void CancelForced(); diff --git a/src/zmc.cpp b/src/zmc.cpp index d974d1bec..68c6227af 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -268,7 +268,7 @@ int main(int argc, char *argv[]) { std::this_thread::sleep_for(sleep_time); } - if (zm_terminate){ + if (zm_terminate) { break; } @@ -308,6 +308,7 @@ int main(int argc, char *argv[]) { result = -1; break; } + monitors[i]->UpdateFPS(); // capture_delay is the amount of time we should sleep in useconds to achieve the desired framerate. Microseconds delay = (monitors[i]->GetState() == Monitor::ALARM) ? monitors[i]->GetAlarmCaptureDelay() From 0119ff46aaebf92881039800d953320f9d945fc8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 3 Nov 2021 17:03:54 -0400 Subject: [PATCH 061/174] Remove redundant debug --- src/zm_image.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 2b7bc69e2..295426254 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -270,7 +270,6 @@ int Image::PopulateFrame(AVFrame *frame) { frame->width = width; frame->height = height; frame->format = imagePixFormat; - Debug(1, "PopulateFrame: width %d height %d linesize %d colours %d imagesize %d", width, height, linesize, colours, size); zm_dump_video_frame(frame, "Image.Populate(frame)"); return 1; } // int Image::PopulateFrame(AVFrame *frame) From 364ae03195b45812bd5844b0db54d3a0edffe276 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 3 Nov 2021 17:04:13 -0400 Subject: [PATCH 062/174] Set zm_terminate on crash so that other threads exit instead of continuing --- src/zm_signal.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zm_signal.cpp b/src/zm_signal.cpp index 9a92b5eac..4107e96c8 100644 --- a/src/zm_signal.cpp +++ b/src/zm_signal.cpp @@ -46,6 +46,7 @@ RETSIGTYPE zm_die_handler(int signal, siginfo_t * info, void *context) RETSIGTYPE zm_die_handler(int signal) #endif { + zm_terminate = true; Error("Got signal %d (%s), crashing", signal, strsignal(signal)); #if (defined(__i386__) || defined(__x86_64__)) // Get more information if available From f737e3e945403019ee01efe1d85d1fa0eb1a135b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 6 Nov 2021 09:58:31 -0400 Subject: [PATCH 063/174] Only list available ids if there are some --- web/skins/classic/views/monitor.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 68ce50397..e4b2754ab 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -461,9 +461,12 @@ switch ( $name ) {
-10 Available Ids: - - + + Date: Sun, 7 Nov 2021 11:28:34 -0500 Subject: [PATCH 064/174] Pretty up the v4l field names --- web/ajax/modals/settings.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/web/ajax/modals/settings.php b/web/ajax/modals/settings.php index de42d6c87..e0bdf679c 100644 --- a/web/ajax/modals/settings.php +++ b/web/ajax/modals/settings.php @@ -38,7 +38,7 @@ if ($zmuOutput) { $ctls = shell_exec('v4l2-ctl -d '.$monitor->Device().' --list-ctrls'); if (!$ctls) { -ZM\Warning("Guessing v4l ctrls. We need v4l2-ctl please install it"); +ZM\Warning('Guessing v4l ctrls. We need v4l2-ctl please install it'); $ctls = ' brightness 0x00980900 (int) : min=-10 max=10 step=1 default=0 value=8 contrast 0x00980901 (int) : min=0 max=20 step=1 default=10 value=12 @@ -83,10 +83,15 @@ foreach ($ctls as $line) { } } + $label = translate($setting_uc); + if ($label == $setting_uc) { + $label = ucwords(str_replace('_', ' ', $label)); + } + if ($setting == 'brightness' or $setting == 'colour' or $setting == 'contrast' or $setting == 'hue') { echo ' - '.translate($setting_uc).' + '.$label.' '.$min.''.$max.' '; @@ -94,7 +99,7 @@ foreach ($ctls as $line) { if ($type == '(bool)') { echo ' - '.translate($setting_uc).' + '.$label.' '.html_radio('new'.$setting_uc, array('0'=>translate('True'), '1', translate('False')), $value, array('disabled'=>'disabled')).' @@ -102,14 +107,14 @@ foreach ($ctls as $line) { } else if ($type == '(int)') { echo ' - '.translate($setting_uc).' + '.$label.' '; } else { echo ' - '.translate($setting_uc).' + '.$label.' '.$value.' '; From 8c2dec03b6371aac74cca902608ac1ec4b1c981a Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 09:48:57 -0500 Subject: [PATCH 065/174] Default to now instead of ... epoch? when endtime is null. Fixes video playing when event is incomplete --- src/zm_eventstream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 5e1ad605d..af9dd8639 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -141,7 +141,7 @@ bool EventStream::loadEventData(uint64_t event_id) { event_data->storage_id = dbrow[1] ? atoi(dbrow[1]) : 0; event_data->frame_count = dbrow[2] == nullptr ? 0 : atoi(dbrow[2]); event_data->start_time = SystemTimePoint(Seconds(atoi(dbrow[3]))); - event_data->end_time = dbrow[4] ? SystemTimePoint(Seconds(atoi(dbrow[4]))) : SystemTimePoint(); + event_data->end_time = dbrow[4] ? SystemTimePoint(Seconds(atoi(dbrow[4]))) : std::chrono::system_clock::now(); event_data->duration = std::chrono::duration_cast(event_data->end_time - event_data->start_time); event_data->frames_duration = std::chrono::duration_cast(dbrow[5] ? FPSeconds(atof(dbrow[5])) : FPSeconds(0.0)); From ce81099489ccef7e3bfbadc35e792b479f057486 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 10:48:50 -0500 Subject: [PATCH 066/174] Report error if sql fails. Add check for access to specific event. --- web/ajax/events.php | 63 +++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index 4e364242a..090fe476e 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -67,20 +67,19 @@ if (isset($_REQUEST['sort'])) { // Offset specifies the starting row to return, used for pagination $offset = 0; -if ( isset($_REQUEST['offset']) ) { - if ( ( !is_int($_REQUEST['offset']) and !ctype_digit($_REQUEST['offset']) ) ) { +if (isset($_REQUEST['offset'])) { + if ((!is_int($_REQUEST['offset']) and !ctype_digit($_REQUEST['offset']))) { ZM\Error('Invalid value for offset: ' . $_REQUEST['offset']); } else { $offset = $_REQUEST['offset']; } } - // Limit specifies the number of rows to return // Set the default to 0 for events view, to prevent an issue with ALL pagination $limit = 0; -if ( isset($_REQUEST['limit']) ) { - if ( ( !is_int($_REQUEST['limit']) and !ctype_digit($_REQUEST['limit']) ) ) { +if (isset($_REQUEST['limit'])) { + if ((!is_int($_REQUEST['limit']) and !ctype_digit($_REQUEST['limit']))) { ZM\Error('Invalid value for limit: ' . $_REQUEST['limit']); } else { $limit = $_REQUEST['limit']; @@ -91,25 +90,24 @@ if ( isset($_REQUEST['limit']) ) { // MAIN LOOP // -switch ( $task ) { +switch ($task) { case 'archive' : - foreach ( $eids as $eid ) archiveRequest($task, $eid); + foreach ($eids as $eid) archiveRequest($task, $eid); break; case 'unarchive' : # The idea is that anyone can archive, but only people with Event Edit permission can unarchive.. - if ( !canEdit('Events') ) { + if (!canEdit('Events')) { ajaxError('Insufficient permissions for user '.$user['Username']); return; } - foreach ( $eids as $eid ) archiveRequest($task, $eid); + foreach ($eids as $eid) archiveRequest($task, $eid); break; case 'delete' : - if ( !canEdit('Events') ) { + if (!canEdit('Events')) { ajaxError('Insufficient permissions for user '.$user['Username']); return; } - - foreach ( $eids as $eid ) $data[] = deleteRequest($eid); + foreach ($eids as $eid) $data[] = deleteRequest($eid); break; case 'query' : $data = queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $limit); @@ -139,6 +137,8 @@ function deleteRequest($eid) { $message[] = array($eid=>'Event not found.'); } else if ( $event->Archived() ) { $message[] = array($eid=>'Event is archived, cannot delete it.'); + } else if (!$event->canEdit()) { + $message[] = array($eid=>'You do not have permission to delete event '.$event->Id()); } else { $event->delete(); } @@ -147,7 +147,6 @@ function deleteRequest($eid) { } function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $limit) { - $data = array( 'total' => 0, 'totalNotFiltered' => 0, @@ -156,7 +155,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim ); $failed = !$filter->test_pre_sql_conditions(); - if ( $failed ) { + if ($failed) { ZM\Debug('Pre conditions failed, not doing sql'); return $data; } @@ -171,7 +170,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim // The names of columns shown in the event view that are NOT dB columns in the database $col_alt = array('Monitor', 'Storage'); - if ( !in_array($sort, array_merge($columns, $col_alt)) ) { + if (!in_array($sort, array_merge($columns, $col_alt))) { ZM\Error('Invalid sort field: ' . $sort); $sort = 'Id'; } @@ -186,7 +185,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $storage_areas = ZM\Storage::find(); $StorageById = array(); - foreach ( $storage_areas as $S ) { + foreach ($storage_areas as $S) { $StorageById[$S->Id()] = $S; } @@ -195,41 +194,43 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim ZM\Debug('Calling the following sql query: ' .$sql); $query = dbQuery($sql, $values); - if ( $query ) { - while ( $row = dbFetchNext($query) ) { - $event = new ZM\Event($row); - $event->remove_from_cache(); - if ( !$filter->test_post_sql_conditions($event) ) { - continue; - } - $event_ids[] = $event->Id(); - $unfiltered_rows[] = $row; - } # end foreach row + if (!$query) { + ajaxError(dbError($sql)); + return; } + while ($row = dbFetchNext($query)) { + $event = new ZM\Event($row); + $event->remove_from_cache(); + if (!$filter->test_post_sql_conditions($event)) { + continue; + } + $event_ids[] = $event->Id(); + $unfiltered_rows[] = $row; + } # end foreach row ZM\Debug('Have ' . count($unfiltered_rows) . ' events matching base filter.'); $filtered_rows = null; - if ( count($advsearch) or $search != '' ) { + if (count($advsearch) or $search != '') { $search_filter = new ZM\Filter(); $search_filter = $search_filter->addTerm(array('cnj'=>'and', 'attr'=>'Id', 'op'=>'IN', 'val'=>$event_ids)); // There are two search bars in the log view, normal and advanced // Making an exuctive decision to ignore the normal search, when advanced search is in use // Alternatively we could try to do both - if ( count($advsearch) ) { + if (count($advsearch)) { $terms = array(); - foreach ( $advsearch as $col=>$text ) { + foreach ($advsearch as $col=>$text) { $terms[] = array('cnj'=>'and', 'attr'=>$col, 'op'=>'LIKE', 'val'=>$text); } # end foreach col in advsearch $terms[0]['obr'] = 1; $terms[count($terms)-1]['cbr'] = 1; $search_filter->addTerms($terms); - } else if ( $search != '' ) { + } else if ($search != '') { $search = '%' .$search. '%'; $terms = array(); - foreach ( $columns as $col ) { + foreach ($columns as $col) { $terms[] = array('cnj'=>'or', 'attr'=>$col, 'op'=>'LIKE', 'val'=>$search); } $terms[0]['obr'] = 1; From e617eb86152b25a44c82b8a168833eb630a3292e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 10:49:01 -0500 Subject: [PATCH 067/174] Whitespace --- web/includes/database.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/includes/database.php b/web/includes/database.php index 34ea384fa..01926a26e 100644 --- a/web/includes/database.php +++ b/web/includes/database.php @@ -112,7 +112,7 @@ function dbLog($sql, $update=false) { function dbError($sql) { global $dbConn; $error = $dbConn->errorInfo(); - if ( !$error[0] ) + if (!$error[0]) return ''; $message = "SQL-ERR '".implode("\n", $dbConn->errorInfo())."', statement was '".$sql."'"; @@ -130,17 +130,17 @@ function dbEscape( $string ) { function dbQuery($sql, $params=NULL, $debug = false) { global $dbConn; - if ( dbLog($sql, true) ) + if (dbLog($sql, true)) return; $result = NULL; try { - if ( isset($params) ) { - if ( ! $result = $dbConn->prepare($sql) ) { + if (isset($params)) { + if (!$result = $dbConn->prepare($sql)) { ZM\Error("SQL: Error preparing $sql: " . $pdo->errorInfo); return NULL; } - if ( ! $result->execute($params) ) { + if (!$result->execute($params)) { ZM\Error("SQL: Error executing $sql: " . print_r($result->errorInfo(), true)); return NULL; } From 7abbfc2fb54f8da9052baaab2c5107d2a0f5610d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 10:50:39 -0500 Subject: [PATCH 068/174] alert error message is an error is returned instead of rows --- web/skins/classic/views/js/events.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index 9f6d34f75..6139ba3e4 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -35,12 +35,16 @@ var params = // Called by bootstrap-table to retrieve zm event data function ajaxRequest(params) { - if ( params.data && params.data.filter ) { + if (params.data && params.data.filter) { params.data.advsearch = params.data.filter; delete params.data.filter; } $j.getJSON(thisUrl + '?view=request&request=events&task=query'+filterQuery, params.data) .done(function(data) { + if (data.result == 'Error') { + alert(data.message); + return; + } var rows = processRows(data.rows); // rearrange the result into what bootstrap-table expects params.success({total: data.total, totalNotFiltered: data.totalNotFiltered, rows: rows}); From 7aefd657c75b51a6e7c828d1e384ae23306639f7 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 13:51:32 -0500 Subject: [PATCH 069/174] Cleanup and spacing. Rework last_motion_score to be a bit more efficient and use fewer lines. Fix case where MOCORD was not ending/starting event on alarm. --- src/zm_monitor.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 679ea27b7..cdf544682 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1862,8 +1862,6 @@ bool Monitor::Analyse() { Debug(3, "signal and active and modect"); Event::StringSet zoneSet; - int motion_score = last_motion_score; - if (analysis_fps_limit) { double capture_fps = get_capture_fps(); motion_frame_skip = capture_fps / analysis_fps_limit; @@ -1880,7 +1878,7 @@ bool Monitor::Analyse() { } else { Debug(1, "Detecting motion on image %d, image %p", snap->image_index, snap->image); // Get new score. - motion_score = DetectMotion(*(snap->image), zoneSet); + int motion_score = DetectMotion(*(snap->image), zoneSet); snap->zone_stats.reserve(zones.size()); for (const Zone &zone : zones) { @@ -1892,21 +1890,20 @@ bool Monitor::Analyse() { Debug(3, "After motion detection, score:%d last_motion_score(%d), new motion score(%d)", score, last_motion_score, motion_score); motion_frame_count += 1; - // Why are we updating the last_motion_score too? last_motion_score = motion_score; + if (motion_score) { + if (cause.length()) cause += ", "; + cause += MOTION_CAUSE; + noteSetMap[MOTION_CAUSE] = zoneSet; + } // end if motion_score } } else { Debug(1, "no image so skipping motion detection"); } // end if has image } else { - Debug(1, "Skipped motion detection last motion score was %d", motion_score); + Debug(1, "Skipped motion detection last motion score was %d", last_motion_score); } - if (motion_score) { - score += motion_score; - if (cause.length()) cause += ", "; - cause += MOTION_CAUSE; - noteSetMap[MOTION_CAUSE] = zoneSet; - } // end if motion_score + score += last_motion_score; } else { Debug(1, "Not Active(%d) enabled %d active %d doing motion detection: %d", Active(), enabled, shared_data->active, @@ -2007,7 +2004,7 @@ bool Monitor::Analyse() { } // end if ! event } // end if RECORDING - if (score and (function == MODECT or function == NODECT)) { + if (score and (function == MODECT or function == NODECT or function == MOCORD)) { if ((state == IDLE) || (state == TAPE) || (state == PREALARM)) { // If we should end then previous continuous event and start a new non-continuous event if (event && event->Frames() @@ -2142,7 +2139,8 @@ bool Monitor::Analyse() { shared_data->state = state = ((function != MOCORD) ? IDLE : TAPE); } else { Debug(1, - "State %s because image_count(%d)-last_alarm_count(%d) > post_event_count(%d) and timestamp.tv_sec(%" PRIi64 ") - recording.tv_src(%" PRIi64 ") >= min_section_length(%" PRIi64 ")", + "State %d %s because analysis_image_count(%d)-last_alarm_count(%d) > post_event_count(%d) and timestamp.tv_sec(%" PRIi64 ") - recording.tv_src(%" PRIi64 ") >= min_section_length(%" PRIi64 ")", + state, State_Strings[state].c_str(), analysis_image_count, last_alarm_count, @@ -2161,12 +2159,10 @@ bool Monitor::Analyse() { // Generate analysis images if necessary if ((savejpegs > 1) and snap->image) { for (const Zone &zone : zones) { - if (zone.Alarmed()) { - if (zone.AlarmImage()) { + if (zone.Alarmed() and zone.AlarmImage()) { if (!snap->analysis_image) snap->analysis_image = new Image(*(snap->image)); snap->analysis_image->Overlay(*(zone.AlarmImage())); - } } // end if zone is alarmed } // end foreach zone } // end if savejpegs From 38105c67968bb1c38b8bd24ed3308673f40ba96d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 13:54:33 -0500 Subject: [PATCH 070/174] Spacing --- src/zm_event.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 442033c50..d52f606a6 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -323,32 +323,32 @@ void Event::updateNotes(const StringSetMap &newNoteSetMap) { bool update = false; //Info( "Checking notes, %d <> %d", noteSetMap.size(), newNoteSetMap.size() ); - if ( newNoteSetMap.size() > 0 ) { - if ( noteSetMap.size() == 0 ) { + if (newNoteSetMap.size() > 0) { + if (noteSetMap.size() == 0) { noteSetMap = newNoteSetMap; update = true; } else { - for ( StringSetMap::const_iterator newNoteSetMapIter = newNoteSetMap.begin(); + for (StringSetMap::const_iterator newNoteSetMapIter = newNoteSetMap.begin(); newNoteSetMapIter != newNoteSetMap.end(); - ++newNoteSetMapIter ) { + ++newNoteSetMapIter) { const std::string &newNoteGroup = newNoteSetMapIter->first; const StringSet &newNoteSet = newNoteSetMapIter->second; //Info( "Got %d new strings", newNoteSet.size() ); - if ( newNoteSet.size() > 0 ) { + if (newNoteSet.size() > 0) { StringSetMap::iterator noteSetMapIter = noteSetMap.find(newNoteGroup); - if ( noteSetMapIter == noteSetMap.end() ) { - //Info( "Can't find note group %s, copying %d strings", newNoteGroup.c_str(), newNoteSet.size() ); + if (noteSetMapIter == noteSetMap.end()) { + //Debug(3, "Can't find note group %s, copying %d strings", newNoteGroup.c_str(), newNoteSet.size()); noteSetMap.insert(StringSetMap::value_type(newNoteGroup, newNoteSet)); update = true; } else { StringSet ¬eSet = noteSetMapIter->second; - //Info( "Found note group %s, got %d strings", newNoteGroup.c_str(), newNoteSet.size() ); - for ( StringSet::const_iterator newNoteSetIter = newNoteSet.begin(); + //Debug(3, "Found note group %s, got %d strings", newNoteGroup.c_str(), newNoteSet.size()); + for (StringSet::const_iterator newNoteSetIter = newNoteSet.begin(); newNoteSetIter != newNoteSet.end(); - ++newNoteSetIter ) { + ++newNoteSetIter) { const std::string &newNote = *newNoteSetIter; StringSet::iterator noteSetIter = noteSet.find(newNote); - if ( noteSetIter == noteSet.end() ) { + if (noteSetIter == noteSet.end()) { noteSet.insert(newNote); update = true; } From 5d23362ae02ca61ae4b8d3e5f62f81cb9ee7f8ce Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 13:59:05 -0500 Subject: [PATCH 071/174] use != Monitor instead of all the other cases --- src/zm_monitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index cdf544682..81eacc956 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -2004,7 +2004,7 @@ bool Monitor::Analyse() { } // end if ! event } // end if RECORDING - if (score and (function == MODECT or function == NODECT or function == MOCORD)) { + if (score and (function != MONITOR)) { if ((state == IDLE) || (state == TAPE) || (state == PREALARM)) { // If we should end then previous continuous event and start a new non-continuous event if (event && event->Frames() From 66517218f1094ef22dad87abdec0f3878ac7092d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 14:00:04 -0500 Subject: [PATCH 072/174] Ignore versioned bootstrap --- .eslintignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index 4682851df..91b0fd196 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,7 +4,7 @@ web/api/lib web/includes/csrf/ web/js/videojs.zoomrotate.js -web/skins/classic/js/bootstrap.js +web/skins/classic/js/bootstrap-4.5.0.js web/skins/classic/js/chosen web/skins/classic/js/dateTimePicker web/skins/classic/js/jquery-*.js From 508be72e08cbfef15508208a0028c7fb97a31bf4 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 15:49:25 -0500 Subject: [PATCH 073/174] Don't exit(0) on QUIT. Instead set zm_terminate=true so that all the cleanup routines run. --- src/zm_monitorstream.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index 5c32b8e05..9bc04a311 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -229,6 +229,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) { break; case CMD_QUIT : Info("User initiated exit - CMD_QUIT"); + zm_terminate = true; break; case CMD_QUERY : Debug(1, "Got QUERY command, sending STATUS"); @@ -315,16 +316,6 @@ void MonitorStream::processCommand(const CmdMsg *msg) { } } Debug(2, "Number of bytes sent to (%s): (%d)", rem_addr.sun_path, nbytes); - - // quit after sending a status, if this was a quit request - if ( (MsgCommand)msg->msg_data[0] == CMD_QUIT ) { - zm_terminate = true; - Debug(2, "Quitting"); - return; - } - - //Debug(2,"Updating framerate"); - //updateFrameRate(monitor->GetFPS()); } // end void MonitorStream::processCommand(const CmdMsg *msg) bool MonitorStream::sendFrame(const std::string &filepath, SystemTimePoint timestamp) { From 30d4900b45a56974614fc42cf5538311efb01cf1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 14:32:06 -0500 Subject: [PATCH 074/174] rough in fullscreen mode in watch view --- web/skins/classic/js/skin.js | 26 ++++++++++++++++++++++++++ web/skins/classic/views/js/watch.js | 5 +++++ web/skins/classic/views/watch.php | 3 +++ 3 files changed, 34 insertions(+) diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index c7e2afedf..6ede08479 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -947,3 +947,29 @@ function initThumbAnimation() { }); } } + +/* View in fullscreen */ +function openFullscreen(elem) { + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.webkitRequestFullscreen) { + /* Safari */ + elem.webkitRequestFullscreen(); + } else if (elem.msRequestFullscreen) { + /* IE11 */ + elem.msRequestFullscreen(); + } +} + +/* Close fullscreen */ +function closeFullscreen() { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.webkitExitFullscreen) { + /* Safari */ + document.webkitExitFullscreen(); + } else if (document.msExitFullscreen) { + /* IE11 */ + document.msExitFullscreen(); + } +} diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index aacad5126..5ba4b407c 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -970,5 +970,10 @@ function initPage() { }); } // initPage +function watchFullscreen() { + const content = document.getElementById('content'); + openFullscreen(content); +} + // Kick everything off $j(document).ready(initPage); diff --git a/web/skins/classic/views/watch.php b/web/skins/classic/views/watch.php index e1e54c3c7..beab28ac1 100644 --- a/web/skins/classic/views/watch.php +++ b/web/skins/classic/views/watch.php @@ -142,6 +142,9 @@ if ( $streamMode == 'jpeg' ) { + From f263da89867c4db9fab4deaf461894c15673190b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 16:12:39 -0500 Subject: [PATCH 075/174] Rough in fullscreen mode on montage --- web/skins/classic/views/js/montage.js | 5 +++++ web/skins/classic/views/montage.php | 3 +++ 2 files changed, 8 insertions(+) diff --git a/web/skins/classic/views/js/montage.js b/web/skins/classic/views/js/montage.js index 5312928a6..75b3a74d2 100644 --- a/web/skins/classic/views/js/montage.js +++ b/web/skins/classic/views/js/montage.js @@ -317,5 +317,10 @@ function initPage() { } selectLayout('#zmMontageLayout'); } + +function watchFullscreen() { + const content = document.getElementById('content'); + openFullscreen(content); +} // Kick everything off $j(document).ready(initPage); diff --git a/web/skins/classic/views/montage.php b/web/skins/classic/views/montage.php index 3256cfcc8..b0b10f190 100644 --- a/web/skins/classic/views/montage.php +++ b/web/skins/classic/views/montage.php @@ -206,6 +206,9 @@ if ( canView('System') ) {   + From 44d88edbbbcbbd43ac6dcf7b35f8af7f2203d370 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 17:01:04 -0500 Subject: [PATCH 076/174] Fix some build warnings on arm --- src/zm_fifo.cpp | 4 ++-- src/zm_monitor.cpp | 22 +++++++++++----------- src/zm_packetqueue.cpp | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/zm_fifo.cpp b/src/zm_fifo.cpp index 319c35c31..a999adc23 100644 --- a/src/zm_fifo.cpp +++ b/src/zm_fifo.cpp @@ -143,8 +143,8 @@ bool Fifo::writePacket(std::string filename, const ZMPacket &packet) { bool Fifo::write(uint8_t *data, size_t bytes, int64_t pts) { if (!(outfile or open())) return false; // Going to write a brief header - Debug(1, "Writing header ZM %lu %" PRId64, bytes, pts); - if ( fprintf(outfile, "ZM %lu %" PRId64 "\n", bytes, pts) < 0 ) { + Debug(1, "Writing header ZM %zu %" PRId64, bytes, pts); + if (fprintf(outfile, "ZM %zu %" PRId64 "\n", bytes, pts) < 0) { if (errno != EAGAIN) { Error("Problem during writing: %s", strerror(errno)); } else { diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 81eacc956..b6e69a19f 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -155,7 +155,7 @@ bool Monitor::MonitorLink::connect() { mem_size = sizeof(SharedData) + sizeof(TriggerData); - Debug(1, "link.mem.size=%jd", mem_size); + Debug(1, "link.mem.size=%jd", static_cast(mem_size)); #if ZM_MEM_MAPPED map_fd = open(mem_file.c_str(), O_RDWR, (mode_t)0600); if (map_fd < 0) { @@ -182,14 +182,14 @@ bool Monitor::MonitorLink::connect() { disconnect(); return false; } else if (map_stat.st_size < mem_size) { - Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, mem_size); + Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, static_cast(mem_size)); disconnect(); return false; } mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0); if (mem_ptr == MAP_FAILED) { - Error("Can't map file %s (%jd bytes) to memory: %s", mem_file.c_str(), mem_size, strerror(errno)); + Error("Can't map file %s (%jd bytes) to memory: %s", mem_file.c_str(), static_cast(mem_size), strerror(errno)); disconnect(); return false; } @@ -947,7 +947,7 @@ bool Monitor::connect() { map_fd = -1; return false; } else { - Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, mem_size); + Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, static_cast(mem_size)); close(map_fd); map_fd = -1; return false; @@ -959,18 +959,18 @@ bool Monitor::connect() { mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0); if (mem_ptr == MAP_FAILED) { if (errno == EAGAIN) { - Debug(1, "Unable to map file %s (%jd bytes) to locked memory, trying unlocked", mem_file.c_str(), mem_size); + Debug(1, "Unable to map file %s (%jd bytes) to locked memory, trying unlocked", mem_file.c_str(), static_cast(mem_size)); #endif mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0); - Debug(1, "Mapped file %s (%jd bytes) to unlocked memory", mem_file.c_str(), mem_size); + Debug(1, "Mapped file %s (%jd bytes) to unlocked memory", mem_file.c_str(), static_cast(mem_size)); #ifdef MAP_LOCKED } else { - Error("Unable to map file %s (%jd bytes) to locked memory (%s)", mem_file.c_str(), mem_size, strerror(errno)); + Error("Unable to map file %s (%jd bytes) to locked memory (%s)", mem_file.c_str(), static_cast(mem_size), strerror(errno)); } } #endif if ((mem_ptr == MAP_FAILED) or (mem_ptr == nullptr)) { - Error("Can't map file %s (%jd bytes) to memory: %s(%d)", mem_file.c_str(), mem_size, strerror(errno), errno); + Error("Can't map file %s (%jd bytes) to memory: %s(%d)", mem_file.c_str(), static_cast(mem_size), strerror(errno), errno); close(map_fd); map_fd = -1; mem_ptr = nullptr; @@ -2310,7 +2310,7 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) { while ( 1 ) { dest_ptr = link_id_str; while ( *src_ptr >= '0' && *src_ptr <= '9' ) { - if ( (dest_ptr-link_id_str) < (unsigned int)(sizeof(link_id_str)-1) ) { + if ( (unsigned int)(dest_ptr-link_id_str) < (unsigned int)(sizeof(link_id_str)-1) ) { *dest_ptr++ = *src_ptr++; } else { break; @@ -2741,7 +2741,7 @@ void Monitor::TimestampImage(Image *ts_image, SystemTimePoint ts_time) const { const char *s_ptr = label_time_text; char *d_ptr = label_text; - while (*s_ptr && ((d_ptr - label_text) < (unsigned int) sizeof(label_text))) { + while (*s_ptr && ((unsigned int)(d_ptr - label_text) < (unsigned int) sizeof(label_text))) { if ( *s_ptr == config.timestamp_code_char[0] ) { bool found_macro = false; switch ( *(s_ptr+1) ) { @@ -2757,7 +2757,7 @@ void Monitor::TimestampImage(Image *ts_image, SystemTimePoint ts_time) const { typedef std::chrono::duration Centiseconds; Centiseconds centi_sec = std::chrono::duration_cast( ts_time.time_since_epoch() - std::chrono::duration_cast(ts_time.time_since_epoch())); - d_ptr += snprintf(d_ptr, sizeof(label_text) - (d_ptr - label_text), "%02ld", centi_sec.count()); + d_ptr += snprintf(d_ptr, sizeof(label_text) - (d_ptr - label_text), "%02lld", static_cast(centi_sec.count())); found_macro = true; break; } diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index ceef421db..509a25ee6 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -209,7 +209,7 @@ void PacketQueue::clearPackets(const std::shared_ptr &add_packet) { --it; } } - Debug(1, "Tail count is %d, queue size is %lu", tail_count, pktQueue.size()); + Debug(1, "Tail count is %d, queue size is %zu", tail_count, pktQueue.size()); if (!keep_keyframes) { // If not doing passthrough, we don't care about starting with a keyframe so logic is simpler From 4c2d50c1f422a915f706b010aceda467f3afb667 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:18:58 -0500 Subject: [PATCH 077/174] implement UrlToZMS in Monitor --- web/includes/Monitor.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index 027cafadd..788486b2e 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -495,6 +495,10 @@ class Monitor extends ZM_Object { return $this->Server()->UrlToIndex($port); } + public function UrlToZMS($port=null) { + return $this->Server()->UrlToZMS($port).'?mid='.$this->Id(); + } + public function sendControlCommand($command) { // command is generally a command option list like --command=blah but might be just the word quit From 474f65cff36354c5960e32070ae1d80d6a985556 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:20:19 -0500 Subject: [PATCH 078/174] Implement getElement, setScale in MonitorStream.js --- web/js/MonitorStream.js | 75 ++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index a10d90008..feb4b3611 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -3,8 +3,10 @@ function MonitorStream(monitorData) { this.id = monitorData.id; this.connKey = monitorData.connKey; this.url = monitorData.url; + this.url_to_zms = monitorData.url_to_zms; this.width = monitorData.width; this.height = monitorData.height; + this.scale = 100; this.status = null; this.alarmState = STATE_IDLE; this.lastAlarmState = STATE_IDLE; @@ -15,19 +17,68 @@ function MonitorStream(monitorData) { }; this.type = monitorData.type; this.refresh = monitorData.refresh; + this.element = null; + this.getElement = function() { + if (this.element) return this.element; + this.element = document.getElementById('liveStream'+this.id); + if (!this.element) { + console.error("No img for #liveStream"+this.id); + } + return this.element; + }; + + /* if the img element didn't have a src, this would fill it in, causing it to show. */ + this.show = function() { + const stream = this.getElement(); + if (!stream.src) { + stream.src = this.url_to_zms+"&mode=single&scale=100&connkey="+this.connKey; + } + }; + + this.setScale = function(newscale) { + const img = this.getElement(); + if (!img) return; + + this.scale = newscale; + + const oldSrc = img.getAttribute('src'); + let newSrc = ''; + + img.setAttribute('src', ''); + console.log("Scaling to: " + newscale); + + if (newscale == '0' || newscale == 'auto') { + let bottomElement = document.getElementById('replayStatus'); + if (!bottomElement) { + bottomElement = document.getElementById('monitorState'); + } + var newSize = scaleToFit(this.width, this.height, $j(img), $j(bottomElement)); + + console.log(newSize); + newWidth = newSize.width; + newHeight = newSize.height; + autoScale = parseInt(newSize.autoScale); + // This is so that we don't waste bandwidth and let the browser do all the scaling. + if (autoScale > 100) autoScale = 100; + if (autoScale) { + newSrc = oldSrc.replace(/scale=\d+/i, 'scale='+autoScale); + } + } else { + newWidth = this.width * newscale / SCALE_BASE; + newHeight = this.height * newscale / SCALE_BASE; + img.width(newWidth); + img.height(newHeight); + if (newscale > 100) newscale = 100; + newSrc = oldSrc.replace(/scale=\d+/i, 'scale='+newscale); + } + img.setAttribute('src', newSrc); + }; this.start = function(delay) { // Step 1 make sure we are streaming instead of a static image - var stream = $j('#liveStream'+this.id); - if (!stream.length) { - console.log('No live stream'); - return; - } - stream = stream[0]; - if ( !stream ) { - console.log('No live stream'); - return; - } - if ( !stream.src ) { + const stream = this.getElement(); + if (!stream) return; + + if (!stream.src) { // Website Monitors won't have an img tag console.log('No src for #liveStream'+this.id); console.log(stream); @@ -38,7 +89,7 @@ function MonitorStream(monitorData) { src += '&connkey='+this.connKey; } if ( stream.src != src ) { - console.log("Setting to streaming"); + console.log("Setting to streaming: " + src); stream.src = ''; stream.src = src; } From b8f6172110ddee1ade30cdb0474d301ff01eb197 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:21:12 -0500 Subject: [PATCH 079/174] If no bottom element is specified, take the last child of content in scaleToFit --- web/skins/classic/js/skin.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index 6ede08479..a12005e76 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -584,10 +584,21 @@ function scaleToFit(baseWidth, baseHeight, scaleEl, bottomEl) { $j(window).on('resize', endOfResize); //set delayed scaling when Scale to Fit is selected var ratio = baseWidth / baseHeight; var container = $j('#content'); + if (!container) { + console.error("No container found"); + return; + } + + if (!bottomEl || !bottomEl.length) { + bottomEl = $j(container[0].lastElementChild); + } + //console.log(bottomEl); var viewPort = $j(window); - // jquery does not provide a bottom offet, and offset dows not include margins. outerHeight true minus false gives total vertical margins. + // jquery does not provide a bottom offset, and offset does not include margins. outerHeight true minus false gives total vertical margins. var bottomLoc = bottomEl.offset().top + (bottomEl.outerHeight(true) - bottomEl.outerHeight()) + bottomEl.outerHeight(true); + //console.log("bottomLoc: " + bottomEl.offset().top + " + (" + bottomEl.outerHeight(true) + ' - ' + bottomEl.outerHeight() +') + '+bottomEl.outerHeight(true)); var newHeight = viewPort.height() - (bottomLoc - scaleEl.outerHeight(true)); + //console.log("newHeight = " + viewPort.height() +" - " + bottomLoc + ' - ' + scaleEl.outerHeight(true)); var newWidth = ratio * newHeight; if (newWidth > container.innerWidth()) { newWidth = container.innerWidth(); @@ -598,13 +609,15 @@ function scaleToFit(baseWidth, baseHeight, scaleEl, bottomEl) { return parseInt($j(this).val()); }).get(); scales.shift(); - var closest; + var closest = null; $j(scales).each(function() { //Set zms scale to nearest regular scale. Zoom does not like arbitrary scale values. if (closest == null || Math.abs(this - autoScale) < Math.abs(closest - autoScale)) { closest = this.valueOf(); } }); - autoScale = closest; + if (closest) { + autoScale = closest; + } return {width: Math.floor(newWidth), height: Math.floor(newHeight), autoScale: autoScale}; } From 43c188626705adcbdde54d771242d030e13fd941 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:21:38 -0500 Subject: [PATCH 080/174] Put SCALE_BASE in skin.js.php as it is used in many places. --- web/skins/classic/js/skin.js.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/skins/classic/js/skin.js.php b/web/skins/classic/js/skin.js.php index 802a21095..87e08310e 100644 --- a/web/skins/classic/js/skin.js.php +++ b/web/skins/classic/js/skin.js.php @@ -54,6 +54,7 @@ foreach ( $perms as $perm ) { ?> var ANIMATE_THUMBS = ; +var SCALE_BASE = ; var refreshParent = Date: Wed, 10 Nov 2021 14:22:05 -0500 Subject: [PATCH 081/174] Implement Exit Fullscreen using same button --- web/skins/classic/views/js/watch.js | 14 ++++++++++++-- web/skins/classic/views/js/watch.js.php | 6 +++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 5ba4b407c..324e7f7e0 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -971,8 +971,18 @@ function initPage() { } // initPage function watchFullscreen() { - const content = document.getElementById('content'); - openFullscreen(content); + const btn = document.getElementById('fullscreenBtn'); + console.log(btn); + if (btn.firstElementChild.innerHTML=='fullscreen') { + const content = document.getElementById('content'); + openFullscreen(content); + btn.firstElementChild.innerHTML='fullscreen_exit'; + btn.setAttribute('title', translate["Exit Fullscreen"]); + } else { + closeFullscreen(); + btn.firstElementChild.innerHTML='fullscreen'; + btn.setAttribute('title', translate["Fullscreen"]); + } } // Kick everything off diff --git a/web/skins/classic/views/js/watch.js.php b/web/skins/classic/views/js/watch.js.php index 258a1da73..5b4568dfc 100644 --- a/web/skins/classic/views/js/watch.js.php +++ b/web/skins/classic/views/js/watch.js.php @@ -97,9 +97,13 @@ foreach( dbFetchAll( 'SELECT * FROM ControlPresets WHERE MonitorId = ?', NULL, a $labels[$row['Preset']] = $row['Label']; } -foreach ( $labels as $index=>$label ) { +foreach ($labels as $index=>$label) { ?> labels[] = ''; +var translate = { + "Fullscreen": "", + "Exit Fullscreen": "", +}; From ed84b5967156572ab4e26240ddcb5de2f9d39358 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:23:36 -0500 Subject: [PATCH 082/174] remove extra , --- web/ajax/event.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ajax/event.php b/web/ajax/event.php index 906fe255a..a0b9cb57a 100644 --- a/web/ajax/event.php +++ b/web/ajax/event.php @@ -93,7 +93,7 @@ if ( canView('Events') or canView('Snapshots') ) { $exportFormat, $exportCompress, $exportStructure, - (!empty($_REQUEST['exportFile'])?$_REQUEST['exportFile']:'zmExport'), + (!empty($_REQUEST['exportFile'])?$_REQUEST['exportFile']:'zmExport') )) { ajaxResponse(array('exportFile'=>$exportFile)); } else { From 377219befea0ae4876c3367adb4d794126e3ede2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:25:12 -0500 Subject: [PATCH 083/174] Include url_to_zms in monitorData --- web/skins/classic/views/js/zone.js.php | 1 + web/skins/classic/views/js/zones.js.php | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/zone.js.php b/web/skins/classic/views/js/zone.js.php index fc6616327..37eb6db82 100644 --- a/web/skins/classic/views/js/zone.js.php +++ b/web/skins/classic/views/js/zone.js.php @@ -66,6 +66,7 @@ monitorData[monitorData.length] = { 'width': ViewWidth() ?>, 'height':ViewHeight() ?>, 'url': 'UrlToIndex( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>', + 'url_to_zms': 'UrlToZMS( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>', 'type': 'Type() ?>', 'refresh': 'Refresh() ?>' }; diff --git a/web/skins/classic/views/js/zones.js.php b/web/skins/classic/views/js/zones.js.php index 180a19d81..338095552 100644 --- a/web/skins/classic/views/js/zones.js.php +++ b/web/skins/classic/views/js/zones.js.php @@ -9,6 +9,7 @@ monitorData[monitorData.length] = { 'width': ViewWidth() ?>, 'height':ViewHeight() ?>, 'url': 'UrlToIndex( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>', + 'url_to_zms': 'UrlToZMS( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>', 'type': 'Type() ?>', 'refresh': 'Refresh() ?>' }; @@ -24,7 +25,7 @@ var STATE_TAPE = ; var stateStrings = new Array(); stateStrings[STATE_IDLE] = ""; -stateStrings[STATE_PREALARM] = ""; +stateStrings[STATE_PREALARM] = ""; stateStrings[STATE_ALARM] = ""; stateStrings[STATE_ALERT] = ""; stateStrings[STATE_TAPE] = ""; From 0732d4c1b3bd694ab6cb287ba70419b24686e914 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:25:29 -0500 Subject: [PATCH 084/174] setScale to auto --- web/skins/classic/views/js/zone.js | 1 + web/skins/classic/views/js/zones.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/web/skins/classic/views/js/zone.js b/web/skins/classic/views/js/zone.js index 6282cbf8a..58c286b43 100644 --- a/web/skins/classic/views/js/zone.js +++ b/web/skins/classic/views/js/zone.js @@ -661,6 +661,7 @@ function initPage() { // Start the fps and status updates. give a random delay so that we don't assault the server var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout ); + monitors[i].setScale('auto'); monitors[i].start(delay); } diff --git a/web/skins/classic/views/js/zones.js b/web/skins/classic/views/js/zones.js index 0ad91942d..67dcb094a 100644 --- a/web/skins/classic/views/js/zones.js +++ b/web/skins/classic/views/js/zones.js @@ -12,6 +12,7 @@ function initPage() { // Start the fps and status updates. give a random delay so that we don't assault the server var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout ); + monitors[i].setScale('auto'); monitors[i].start(delay); } @@ -31,5 +32,12 @@ function initPage() { }); } +function streamCmdQuit() { + for ( var i = 0, length = monitorData.length; i < length; i++ ) { + monitors[i] = new MonitorStream(monitorData[i]); + monitors[i].stop(); + } +} + window.addEventListener('DOMContentLoaded', initPage); From 2c0c257d76284b77277ef2941aef8e82b0e8a290 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:25:45 -0500 Subject: [PATCH 085/174] spacing --- web/skins/classic/views/zones.php | 67 +++++++++++++++---------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/web/skins/classic/views/zones.php b/web/skins/classic/views/zones.php index f457ad2fc..423326a98 100644 --- a/web/skins/classic/views/zones.php +++ b/web/skins/classic/views/zones.php @@ -80,15 +80,14 @@ xhtmlHeaders(__FILE__, translate('Zones')); Sorry, your browser does not support inline SVG @@ -96,37 +95,37 @@ xhtmlHeaders(__FILE__, translate('Zones'));  -  fps -
- - - - - - - - - - - - - - - - - - - -
 / ViewWidth()*$monitor->ViewHeight()) ) ?> disabled="disabled"/>
-
- - -
-
-
+
+ + + + + + + + + + + + + + + + + + + +
 / ViewWidth()*$monitor->ViewHeight()) ) ?> disabled="disabled"/>
+
+ + +
+
+
Date: Wed, 10 Nov 2021 16:53:07 -0500 Subject: [PATCH 086/174] Use event->StartTime instead of GetVideoWriterStartTime. Add some parenthesis to make logic clearer and add more info to debug statements --- src/zm_monitor.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index b6e69a19f..d808ddba0 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1916,7 +1916,7 @@ bool Monitor::Analyse() { if (event) { Debug(2, "Have event %" PRIu64 " in record", event->Id()); - if (section_length != Seconds(0) && (timestamp - GetVideoWriterStartTime() >= section_length) + if (section_length != Seconds(0) && (timestamp - event->StartTime() >= section_length) && ((function == MOCORD && event_close_mode != CLOSE_TIME) || (function == RECORD && event_close_mode == CLOSE_TIME) || std::chrono::duration_cast(timestamp.time_since_epoch()) % section_length == Seconds(0))) { @@ -1925,8 +1925,8 @@ bool Monitor::Analyse() { image_count, event->Id(), static_cast(std::chrono::duration_cast(timestamp.time_since_epoch()).count()), - static_cast(std::chrono::duration_cast(GetVideoWriterStartTime().time_since_epoch()).count()), - static_cast(std::chrono::duration_cast(timestamp - GetVideoWriterStartTime()).count()), + static_cast(std::chrono::duration_cast(event->StartTime().time_since_epoch()).count()), + static_cast(std::chrono::duration_cast(timestamp - event->StartTime()).count()), static_cast(Seconds(section_length).count())); closeEvent(); } // end if section_length @@ -2009,21 +2009,22 @@ bool Monitor::Analyse() { // If we should end then previous continuous event and start a new non-continuous event if (event && event->Frames() && !event->AlarmFrames() - && event_close_mode == CLOSE_ALARM - && timestamp - GetVideoWriterStartTime() >= min_section_length - && (!pre_event_count || Event::PreAlarmCount() >= alarm_frame_count - 1)) { + && (event_close_mode == CLOSE_ALARM) + && ((timestamp - event->StartTime()) >= min_section_length) + && ((!pre_event_count) || (Event::PreAlarmCount() >= alarm_frame_count - 1))) { Info("%s: %03d - Closing event %" PRIu64 ", continuous end, alarm begins", name.c_str(), image_count, event->Id()); closeEvent(); } else if (event) { // This is so if we need more than 1 alarm frame before going into alarm, so it is basically if we have enough alarm frames Debug(3, - "pre_alarm_count in event %d, event frames %d, alarm frames %d event length %" PRIi64 " >=? %" PRIi64 " min", - Event::PreAlarmCount(), + "pre_alarm_count in event %d of %d, event frames %d, alarm frames %d event length %" PRIi64 " >=? %" PRIi64 " min close mode is ALARM? %d", + Event::PreAlarmCount(), pre_event_count, event->Frames(), event->AlarmFrames(), - static_cast(std::chrono::duration_cast(timestamp - GetVideoWriterStartTime()).count()), - static_cast(Seconds(min_section_length).count())); + static_cast(std::chrono::duration_cast(timestamp - event->StartTime()).count()), + static_cast(Seconds(min_section_length).count()), + (event_close_mode == CLOSE_ALARM)); } if ((!pre_event_count) || (Event::PreAlarmCount() >= alarm_frame_count-1)) { // lets construct alarm cause. It will contain cause + names of zones alarmed @@ -2120,8 +2121,10 @@ bool Monitor::Analyse() { Info("%s: %03d - Gone into alert state", name.c_str(), analysis_image_count); shared_data->state = state = ALERT; } else if (state == ALERT) { - if (analysis_image_count - last_alarm_count > post_event_count - && timestamp - GetVideoWriterStartTime() >= min_section_length) { + if ( + ((analysis_image_count - last_alarm_count) > post_event_count) + && + ((timestamp - event->StartTime()) >= min_section_length)) { Info("%s: %03d - Left alarm state (%" PRIu64 ") - %d(%d) images", name.c_str(), analysis_image_count, event->Id(), event->Frames(), event->AlarmFrames()); //if ( function != MOCORD || event_close_mode == CLOSE_ALARM || event->Cause() == SIGNAL_CAUSE ) @@ -2168,7 +2171,6 @@ bool Monitor::Analyse() { } // end if savejpegs // incremement pre alarm image count - //have_pre_alarmed_frames ++; Event::AddPreAlarmFrame(snap->image, timestamp, score, nullptr); } else if (state == ALARM) { for (const Zone &zone : zones) { @@ -2183,7 +2185,7 @@ bool Monitor::Analyse() { if (event) { if (noteSetMap.size() > 0) event->updateNotes(noteSetMap); - if (section_length != Seconds(0) && (timestamp - GetVideoWriterStartTime() >= section_length)) { + if (section_length != Seconds(0) && (timestamp - event->StartTime() >= section_length)) { Warning("%s: %03d - event %" PRIu64 ", has exceeded desired section length. %" PRIi64 " - %" PRIi64 " = %" PRIi64 " >= %" PRIi64, name.c_str(), analysis_image_count, event->Id(), static_cast(std::chrono::duration_cast(timestamp.time_since_epoch()).count()), From 8d85d0f6402d43959e223234f798a969512af16e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 16:53:29 -0500 Subject: [PATCH 087/174] Make state enum start at 0 as we are indexing into an array for StateStrings --- src/zm_monitor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 56785405f..5b9a2ce46 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -100,7 +100,7 @@ public: } Deinterlace; typedef enum { - UNKNOWN=-1, + UNKNOWN, IDLE, PREALARM, ALARM, From 721769993b746f04f0205ca6fe854574dff855c6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 17:05:46 -0500 Subject: [PATCH 088/174] Set to never timeout while generating video --- web/skins/classic/views/js/video.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/skins/classic/views/js/video.js b/web/skins/classic/views/js/video.js index 970119f4f..c764f33b5 100644 --- a/web/skins/classic/views/js/video.js +++ b/web/skins/classic/views/js/video.js @@ -16,6 +16,9 @@ function generateVideoResponse( data, responseText ) { } function generateVideo() { + $j.ajaxSetup({ + timeout: 0 + }); var form = $j('#videoForm').serialize(); $j.getJSON(thisUrl + '?view=request&request=event&action=video', form) .done(generateVideoResponse) From 9d71f1192a0dac30f273942bbd062b453349e478 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 29 Sep 2021 09:30:04 -0400 Subject: [PATCH 089/174] merge manufacturer update into existing zm_update-1.37.2 and then move it to .in --- db/manufacturers.sql | 19 ----------------- db/zm_update-1.37.3.sql | 47 ----------------------------------------- 2 files changed, 66 deletions(-) delete mode 100644 db/zm_update-1.37.3.sql diff --git a/db/manufacturers.sql b/db/manufacturers.sql index eaee2630c..be15f9c01 100644 --- a/db/manufacturers.sql +++ b/db/manufacturers.sql @@ -1,23 +1,4 @@ INSERT INTO Manufacturers VALUES (1, 'Acti'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A21'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A23'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A24'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A28'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A31'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A310'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A311'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A32'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A41'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A415'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A416'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A418'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A42'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A421'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A43'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A45'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A46'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A48'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A74'); INSERT INTO Manufacturers VALUES (2, 'Amcrest'); INSERT INTO Manufacturers VALUES (3, 'Airlink101'); INSERT INTO Manufacturers VALUES (4, 'Arecont Vision'); diff --git a/db/zm_update-1.37.3.sql b/db/zm_update-1.37.3.sql deleted file mode 100644 index 341c5e162..000000000 --- a/db/zm_update-1.37.3.sql +++ /dev/null @@ -1,47 +0,0 @@ -SET @s = (SELECT IF( - (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() - AND table_name = 'Monitors' - AND column_name = 'ManufacturerId' - ) > 0, -"SELECT 'Column ManufacturerId already exists in Monitors'", -"ALTER TABLE `Monitors` ADD `ManufacturerId` int(10) unsigned AFTER `StorageId`" -)); - -PREPARE stmt FROM @s; -EXECUTE stmt; - -SET @s = (SELECT IF( - (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() - AND table_name = 'Monitors' - AND column_name = 'ManufacturerId' - ) > 0, -"SELECT 'FOREIGN KEY for ManufacturerId already exists in Monitors'", -"ALTER TABLE `Monitors` ADD FOREIGN KEY (`ManufacturerId`) REFERENCES `Manufacturers` (Id)" -)); - -PREPARE stmt FROM @s; -EXECUTE stmt; - -SET @s = (SELECT IF( - (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() - AND table_name = 'Monitors' - AND column_name = 'ModelId' - ) > 0, -"SELECT 'Column ModelId already exists in Monitors'", -"ALTER TABLE `Monitors` ADD `ModelId` int(10) unsigned AFTER `ManufacturerId`" -)); - -PREPARE stmt FROM @s; -EXECUTE stmt; - -SET @s = (SELECT IF( - (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() - AND table_name = 'Monitors' - AND column_name = 'ModelId' - ) > 0, -"SELECT 'FOREIGN KEY for ModelId already exists in Monitors'", -"ALTER TABLE `Monitors` ADD FOREIGN KEY (`ModelId`) REFERENCES `Models` (Id)" -)); - -PREPARE stmt FROM @s; -EXECUTE stmt; From dc756ad670373e7cbe6dd3201fabbb44f1c922a3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 19:20:39 -0500 Subject: [PATCH 090/174] add back update for Manufacturers and Models --- db/zm_update-1.37.3.sql | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 db/zm_update-1.37.3.sql diff --git a/db/zm_update-1.37.3.sql b/db/zm_update-1.37.3.sql new file mode 100644 index 000000000..341c5e162 --- /dev/null +++ b/db/zm_update-1.37.3.sql @@ -0,0 +1,47 @@ +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ManufacturerId' + ) > 0, +"SELECT 'Column ManufacturerId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ManufacturerId` int(10) unsigned AFTER `StorageId`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ManufacturerId' + ) > 0, +"SELECT 'FOREIGN KEY for ManufacturerId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD FOREIGN KEY (`ManufacturerId`) REFERENCES `Manufacturers` (Id)" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ModelId' + ) > 0, +"SELECT 'Column ModelId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ModelId` int(10) unsigned AFTER `ManufacturerId`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ModelId' + ) > 0, +"SELECT 'FOREIGN KEY for ModelId already exists in Monitors'", +"ALTER TABLE `Monitors` ADD FOREIGN KEY (`ModelId`) REFERENCES `Models` (Id)" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; From 6cd1f6b5f3286af43b1c1b3d09a6e953693c2914 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 11 Nov 2021 13:50:18 -0500 Subject: [PATCH 091/174] Fix memleak on event creation due to not freeing storage object --- src/zm_event.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index d52f606a6..aad16a767 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -103,7 +103,7 @@ Event::Event( // Copy it in case opening the mp4 doesn't work we can set it to another value save_jpegs = monitor->GetOptSaveJPEGs(); - Storage * storage = monitor->getStorage(); + Storage *storage = monitor->getStorage(); if (monitor->GetOptVideoWriter() != 0) { container = monitor->OutputContainer(); if ( container == "auto" || container == "" ) { @@ -133,22 +133,22 @@ Event::Event( ); id = zmDbDoInsert(sql); - if ( !SetPath(storage) ) { + if (!SetPath(storage)) { // Try another Warning("Failed creating event dir at %s", storage->Path()); sql = stringtf("SELECT `Id` FROM `Storage` WHERE `Id` != %u", storage->Id()); - if ( monitor->ServerId() ) + if (monitor->ServerId()) sql += stringtf(" AND ServerId=%u", monitor->ServerId()); - Debug(1, "%s", sql.c_str()); + delete storage; storage = nullptr; MYSQL_RES *result = zmDbFetch(sql); - if ( result ) { - for ( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) { + if (result) { + for (int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++) { storage = new Storage(atoi(dbrow[0])); - if ( SetPath(storage) ) + if (SetPath(storage)) break; delete storage; storage = nullptr; @@ -156,18 +156,18 @@ Event::Event( mysql_free_result(result); result = nullptr; } - if ( !storage ) { + if (!storage) { Info("No valid local storage area found. Trying all other areas."); // Try remote sql = "SELECT `Id` FROM `Storage` WHERE ServerId IS NULL"; - if ( monitor->ServerId() ) + if (monitor->ServerId()) sql += stringtf(" OR ServerId != %u", monitor->ServerId()); result = zmDbFetch(sql); - if ( result ) { + if (result) { for ( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) { storage = new Storage(atoi(dbrow[0])); - if ( SetPath(storage) ) + if (SetPath(storage)) break; delete storage; storage = nullptr; @@ -176,7 +176,7 @@ Event::Event( result = nullptr; } } - if ( !storage ) { + if (!storage) { storage = new Storage(); Warning("Failed to find a storage area to save events."); } @@ -218,6 +218,7 @@ Event::Event( Debug(1, "Video file is %s", video_file.c_str()); } } // end if GetOptVideoWriter + delete storage; } Event::~Event() { From 883772295d263b41044c41fe39020937f9212759 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 11 Nov 2021 13:51:17 -0500 Subject: [PATCH 092/174] spacing and log the new log level string as well as number --- src/zm_logger.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/zm_logger.cpp b/src/zm_logger.cpp index 5c7c5e9a7..f43ea6f30 100644 --- a/src/zm_logger.cpp +++ b/src/zm_logger.cpp @@ -43,11 +43,11 @@ Logger::IntMap Logger::smSyslogPriorities; void Logger::usrHandler(int sig) { Logger *logger = fetch(); - if ( sig == SIGUSR1 ) + if (sig == SIGUSR1) logger->level(logger->level()+1); - else if ( sig == SIGUSR2 ) + else if (sig == SIGUSR2) logger->level(logger->level()-1); - Info("Logger - Level changed to %d", logger->level()); + Info("Logger - Level changed to %d %s", logger->level(), smCodes[logger->level()].c_str()); } Logger::Logger() : @@ -296,23 +296,23 @@ const std::string &Logger::id(const std::string &id) { } Logger::Level Logger::level(Logger::Level level) { - if ( level > NOOPT ) { + if (level > NOOPT) { mLevel = limit(level); mEffectiveLevel = NOLOG; - if ( mTerminalLevel > mEffectiveLevel ) + if (mTerminalLevel > mEffectiveLevel) mEffectiveLevel = mTerminalLevel; - if ( mDatabaseLevel > mEffectiveLevel ) + if (mDatabaseLevel > mEffectiveLevel) mEffectiveLevel = mDatabaseLevel; - if ( mFileLevel > mEffectiveLevel ) + if (mFileLevel > mEffectiveLevel) mEffectiveLevel = mFileLevel; - if ( mSyslogLevel > mEffectiveLevel ) + if (mSyslogLevel > mEffectiveLevel) mEffectiveLevel = mSyslogLevel; - if ( mEffectiveLevel > mLevel) + if (mEffectiveLevel > mLevel) mEffectiveLevel = mLevel; // DEBUG levels should flush - if ( mLevel > INFO ) + if (mLevel > INFO) mFlush = true; } return mLevel; From a0215067e4ecaf0ccf3d7f7a370f0bb7ec4db01d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 11 Nov 2021 13:58:52 -0500 Subject: [PATCH 093/174] In multi-server when viewing an event it may be coming from a different server than the serverhost. Use monitorUrl instead of thisUrl in ajax calls and include auth data. Fixes failed ajax when viewing h264 using zms on a multi-server environment --- web/skins/classic/views/js/event.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/event.js b/web/skins/classic/views/js/event.js index 050a78d59..1c4f72404 100644 --- a/web/skins/classic/views/js/event.js +++ b/web/skins/classic/views/js/event.js @@ -34,7 +34,7 @@ function streamReq(data) { data.view = 'request'; data.request = 'stream'; - $j.getJSON(thisUrl, data) + $j.getJSON(monitorUrl, data) .done(getCmdResponse) .fail(logAjaxFail); } @@ -657,6 +657,7 @@ function getFrameResponse(respObj, respText) { function frameQuery(eventId, frameId, loadImage) { var data = {}; + if (auth_hash) data.auth = auth_hash; data.loopback = loadImage; data.id = {eventId, frameId}; From 036d47a832383353b37af3d148dd86ff13a5e99c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 11 Nov 2021 14:42:08 -0500 Subject: [PATCH 094/174] proper fix to memleak --- src/zm_event.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index aad16a767..9f1124e7b 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -141,7 +141,6 @@ Event::Event( if (monitor->ServerId()) sql += stringtf(" AND ServerId=%u", monitor->ServerId()); - delete storage; storage = nullptr; MYSQL_RES *result = zmDbFetch(sql); @@ -218,7 +217,8 @@ Event::Event( Debug(1, "Video file is %s", video_file.c_str()); } } // end if GetOptVideoWriter - delete storage; + if (storage != monitor->getStorage()) + delete storage; } Event::~Event() { From 193f349e385f9f41a820c54df993305bc1c5ca75 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 12 Nov 2021 13:36:10 -0500 Subject: [PATCH 095/174] implement Event::canEdit --- web/includes/Event.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/web/includes/Event.php b/web/includes/Event.php index 328b06f66..e042849e9 100644 --- a/web/includes/Event.php +++ b/web/includes/Event.php @@ -650,6 +650,23 @@ class Event extends ZM_Object { } return false; } + function canEdit($u=null) { + global $user; + if (!$u) $u=$user; + if (!$u) { + # auth turned on and not logged in + return false; + } + if (!empty($u['MonitorIds']) ) { + if (!in_array($this->{'MonitorId'}, explode(',', $u['MonitorIds']))) { + return false; + } + } + if ($u['Events'] != 'Edit') { + return false; + } + return true; + } } # end class ?> From 1561adbef930fc61dbb6885ac42eca7117808872 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 12 Nov 2021 15:11:41 -0500 Subject: [PATCH 096/174] Add title to Download button --- web/skins/classic/views/event.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/skins/classic/views/event.php b/web/skins/classic/views/event.php index 81d4e97be..e352f305b 100644 --- a/web/skins/classic/views/event.php +++ b/web/skins/classic/views/event.php @@ -150,6 +150,7 @@ if ( $Event->Id() and !file_exists($Event->Path()) ) DefaultVideo() ? '' : 'style="display:none;"' ?> > From 8868a0fc41735174b00380c338109ea5d11e1d69 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 19 Oct 2021 14:34:17 -0400 Subject: [PATCH 097/174] enforce default action --- utils/do_debian_package.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/utils/do_debian_package.sh b/utils/do_debian_package.sh index 2a4dd6989..6c8c06c00 100755 --- a/utils/do_debian_package.sh +++ b/utils/do_debian_package.sh @@ -230,12 +230,11 @@ rm .gitignore cd ../ -if [ !-e "$DIRECTORY.orig.tar.gz" ]; then -read -p "$DIRECTORY.orig.tar.gz does not exist, create it? [Y/n]" - if [[ $REPLY == [yY] ]]; then - - tar zcf $DIRECTORY.orig.tar.gz $DIRECTORY.orig -fi; +if [ ! -e "$DIRECTORY.orig.tar.gz" ]; then + read -p "$DIRECTORY.orig.tar.gz does not exist, create it? [Y/n]" + if [[ "$REPLY" == "" || "$REPLY" == [yY] ]]; then + tar zcf $DIRECTORY.orig.tar.gz $DIRECTORY.orig + fi; fi; IFS=',' ;for DISTRO in `echo "$DISTROS"`; do From caeaf91cad332d37d641e05e86a9ce6ef6462e50 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 6 Nov 2021 09:58:31 -0400 Subject: [PATCH 098/174] Only list available ids if there are some --- web/skins/classic/views/monitor.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index f47e29912..7d599904a 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -461,9 +461,12 @@ switch ( $name ) {
-10 Available Ids: - - + + Date: Sun, 7 Nov 2021 11:28:34 -0500 Subject: [PATCH 099/174] Pretty up the v4l field names --- web/ajax/modals/settings.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/web/ajax/modals/settings.php b/web/ajax/modals/settings.php index de42d6c87..e0bdf679c 100644 --- a/web/ajax/modals/settings.php +++ b/web/ajax/modals/settings.php @@ -38,7 +38,7 @@ if ($zmuOutput) { $ctls = shell_exec('v4l2-ctl -d '.$monitor->Device().' --list-ctrls'); if (!$ctls) { -ZM\Warning("Guessing v4l ctrls. We need v4l2-ctl please install it"); +ZM\Warning('Guessing v4l ctrls. We need v4l2-ctl please install it'); $ctls = ' brightness 0x00980900 (int) : min=-10 max=10 step=1 default=0 value=8 contrast 0x00980901 (int) : min=0 max=20 step=1 default=10 value=12 @@ -83,10 +83,15 @@ foreach ($ctls as $line) { } } + $label = translate($setting_uc); + if ($label == $setting_uc) { + $label = ucwords(str_replace('_', ' ', $label)); + } + if ($setting == 'brightness' or $setting == 'colour' or $setting == 'contrast' or $setting == 'hue') { echo ' - '.translate($setting_uc).' + '.$label.' '.$min.''.$max.' '; @@ -94,7 +99,7 @@ foreach ($ctls as $line) { if ($type == '(bool)') { echo ' - '.translate($setting_uc).' + '.$label.' '.html_radio('new'.$setting_uc, array('0'=>translate('True'), '1', translate('False')), $value, array('disabled'=>'disabled')).' @@ -102,14 +107,14 @@ foreach ($ctls as $line) { } else if ($type == '(int)') { echo ' - '.translate($setting_uc).' + '.$label.' '; } else { echo ' - '.translate($setting_uc).' + '.$label.' '.$value.' '; From 01eac4a277f650057bcb0f54f46abc1c60738e8c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 09:48:57 -0500 Subject: [PATCH 100/174] Default to now instead of ... epoch? when endtime is null. Fixes video playing when event is incomplete --- src/zm_eventstream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 5e1ad605d..af9dd8639 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -141,7 +141,7 @@ bool EventStream::loadEventData(uint64_t event_id) { event_data->storage_id = dbrow[1] ? atoi(dbrow[1]) : 0; event_data->frame_count = dbrow[2] == nullptr ? 0 : atoi(dbrow[2]); event_data->start_time = SystemTimePoint(Seconds(atoi(dbrow[3]))); - event_data->end_time = dbrow[4] ? SystemTimePoint(Seconds(atoi(dbrow[4]))) : SystemTimePoint(); + event_data->end_time = dbrow[4] ? SystemTimePoint(Seconds(atoi(dbrow[4]))) : std::chrono::system_clock::now(); event_data->duration = std::chrono::duration_cast(event_data->end_time - event_data->start_time); event_data->frames_duration = std::chrono::duration_cast(dbrow[5] ? FPSeconds(atof(dbrow[5])) : FPSeconds(0.0)); From 9036728bdc9b7ca8dddaa0638d2402f487034d5c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 10:48:50 -0500 Subject: [PATCH 101/174] Report error if sql fails. Add check for access to specific event. --- web/ajax/events.php | 63 +++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index 4e364242a..090fe476e 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -67,20 +67,19 @@ if (isset($_REQUEST['sort'])) { // Offset specifies the starting row to return, used for pagination $offset = 0; -if ( isset($_REQUEST['offset']) ) { - if ( ( !is_int($_REQUEST['offset']) and !ctype_digit($_REQUEST['offset']) ) ) { +if (isset($_REQUEST['offset'])) { + if ((!is_int($_REQUEST['offset']) and !ctype_digit($_REQUEST['offset']))) { ZM\Error('Invalid value for offset: ' . $_REQUEST['offset']); } else { $offset = $_REQUEST['offset']; } } - // Limit specifies the number of rows to return // Set the default to 0 for events view, to prevent an issue with ALL pagination $limit = 0; -if ( isset($_REQUEST['limit']) ) { - if ( ( !is_int($_REQUEST['limit']) and !ctype_digit($_REQUEST['limit']) ) ) { +if (isset($_REQUEST['limit'])) { + if ((!is_int($_REQUEST['limit']) and !ctype_digit($_REQUEST['limit']))) { ZM\Error('Invalid value for limit: ' . $_REQUEST['limit']); } else { $limit = $_REQUEST['limit']; @@ -91,25 +90,24 @@ if ( isset($_REQUEST['limit']) ) { // MAIN LOOP // -switch ( $task ) { +switch ($task) { case 'archive' : - foreach ( $eids as $eid ) archiveRequest($task, $eid); + foreach ($eids as $eid) archiveRequest($task, $eid); break; case 'unarchive' : # The idea is that anyone can archive, but only people with Event Edit permission can unarchive.. - if ( !canEdit('Events') ) { + if (!canEdit('Events')) { ajaxError('Insufficient permissions for user '.$user['Username']); return; } - foreach ( $eids as $eid ) archiveRequest($task, $eid); + foreach ($eids as $eid) archiveRequest($task, $eid); break; case 'delete' : - if ( !canEdit('Events') ) { + if (!canEdit('Events')) { ajaxError('Insufficient permissions for user '.$user['Username']); return; } - - foreach ( $eids as $eid ) $data[] = deleteRequest($eid); + foreach ($eids as $eid) $data[] = deleteRequest($eid); break; case 'query' : $data = queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $limit); @@ -139,6 +137,8 @@ function deleteRequest($eid) { $message[] = array($eid=>'Event not found.'); } else if ( $event->Archived() ) { $message[] = array($eid=>'Event is archived, cannot delete it.'); + } else if (!$event->canEdit()) { + $message[] = array($eid=>'You do not have permission to delete event '.$event->Id()); } else { $event->delete(); } @@ -147,7 +147,6 @@ function deleteRequest($eid) { } function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $limit) { - $data = array( 'total' => 0, 'totalNotFiltered' => 0, @@ -156,7 +155,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim ); $failed = !$filter->test_pre_sql_conditions(); - if ( $failed ) { + if ($failed) { ZM\Debug('Pre conditions failed, not doing sql'); return $data; } @@ -171,7 +170,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim // The names of columns shown in the event view that are NOT dB columns in the database $col_alt = array('Monitor', 'Storage'); - if ( !in_array($sort, array_merge($columns, $col_alt)) ) { + if (!in_array($sort, array_merge($columns, $col_alt))) { ZM\Error('Invalid sort field: ' . $sort); $sort = 'Id'; } @@ -186,7 +185,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $storage_areas = ZM\Storage::find(); $StorageById = array(); - foreach ( $storage_areas as $S ) { + foreach ($storage_areas as $S) { $StorageById[$S->Id()] = $S; } @@ -195,41 +194,43 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim ZM\Debug('Calling the following sql query: ' .$sql); $query = dbQuery($sql, $values); - if ( $query ) { - while ( $row = dbFetchNext($query) ) { - $event = new ZM\Event($row); - $event->remove_from_cache(); - if ( !$filter->test_post_sql_conditions($event) ) { - continue; - } - $event_ids[] = $event->Id(); - $unfiltered_rows[] = $row; - } # end foreach row + if (!$query) { + ajaxError(dbError($sql)); + return; } + while ($row = dbFetchNext($query)) { + $event = new ZM\Event($row); + $event->remove_from_cache(); + if (!$filter->test_post_sql_conditions($event)) { + continue; + } + $event_ids[] = $event->Id(); + $unfiltered_rows[] = $row; + } # end foreach row ZM\Debug('Have ' . count($unfiltered_rows) . ' events matching base filter.'); $filtered_rows = null; - if ( count($advsearch) or $search != '' ) { + if (count($advsearch) or $search != '') { $search_filter = new ZM\Filter(); $search_filter = $search_filter->addTerm(array('cnj'=>'and', 'attr'=>'Id', 'op'=>'IN', 'val'=>$event_ids)); // There are two search bars in the log view, normal and advanced // Making an exuctive decision to ignore the normal search, when advanced search is in use // Alternatively we could try to do both - if ( count($advsearch) ) { + if (count($advsearch)) { $terms = array(); - foreach ( $advsearch as $col=>$text ) { + foreach ($advsearch as $col=>$text) { $terms[] = array('cnj'=>'and', 'attr'=>$col, 'op'=>'LIKE', 'val'=>$text); } # end foreach col in advsearch $terms[0]['obr'] = 1; $terms[count($terms)-1]['cbr'] = 1; $search_filter->addTerms($terms); - } else if ( $search != '' ) { + } else if ($search != '') { $search = '%' .$search. '%'; $terms = array(); - foreach ( $columns as $col ) { + foreach ($columns as $col) { $terms[] = array('cnj'=>'or', 'attr'=>$col, 'op'=>'LIKE', 'val'=>$search); } $terms[0]['obr'] = 1; From 944c04e5b46cfa2c7bf883f69df025b78c17f0d0 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 10:49:01 -0500 Subject: [PATCH 102/174] Whitespace --- web/includes/database.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/includes/database.php b/web/includes/database.php index 34ea384fa..01926a26e 100644 --- a/web/includes/database.php +++ b/web/includes/database.php @@ -112,7 +112,7 @@ function dbLog($sql, $update=false) { function dbError($sql) { global $dbConn; $error = $dbConn->errorInfo(); - if ( !$error[0] ) + if (!$error[0]) return ''; $message = "SQL-ERR '".implode("\n", $dbConn->errorInfo())."', statement was '".$sql."'"; @@ -130,17 +130,17 @@ function dbEscape( $string ) { function dbQuery($sql, $params=NULL, $debug = false) { global $dbConn; - if ( dbLog($sql, true) ) + if (dbLog($sql, true)) return; $result = NULL; try { - if ( isset($params) ) { - if ( ! $result = $dbConn->prepare($sql) ) { + if (isset($params)) { + if (!$result = $dbConn->prepare($sql)) { ZM\Error("SQL: Error preparing $sql: " . $pdo->errorInfo); return NULL; } - if ( ! $result->execute($params) ) { + if (!$result->execute($params)) { ZM\Error("SQL: Error executing $sql: " . print_r($result->errorInfo(), true)); return NULL; } From 71931f007a9a90f3ca66c9550939c0b8c691c656 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 10:50:39 -0500 Subject: [PATCH 103/174] alert error message is an error is returned instead of rows --- web/skins/classic/views/js/events.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index 9f6d34f75..6139ba3e4 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -35,12 +35,16 @@ var params = // Called by bootstrap-table to retrieve zm event data function ajaxRequest(params) { - if ( params.data && params.data.filter ) { + if (params.data && params.data.filter) { params.data.advsearch = params.data.filter; delete params.data.filter; } $j.getJSON(thisUrl + '?view=request&request=events&task=query'+filterQuery, params.data) .done(function(data) { + if (data.result == 'Error') { + alert(data.message); + return; + } var rows = processRows(data.rows); // rearrange the result into what bootstrap-table expects params.success({total: data.total, totalNotFiltered: data.totalNotFiltered, rows: rows}); From 0573c09b5097ce18816b182eefd8bed9e1cf1923 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 13:51:32 -0500 Subject: [PATCH 104/174] Cleanup and spacing. Rework last_motion_score to be a bit more efficient and use fewer lines. Fix case where MOCORD was not ending/starting event on alarm. --- src/zm_monitor.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 679ea27b7..cdf544682 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1862,8 +1862,6 @@ bool Monitor::Analyse() { Debug(3, "signal and active and modect"); Event::StringSet zoneSet; - int motion_score = last_motion_score; - if (analysis_fps_limit) { double capture_fps = get_capture_fps(); motion_frame_skip = capture_fps / analysis_fps_limit; @@ -1880,7 +1878,7 @@ bool Monitor::Analyse() { } else { Debug(1, "Detecting motion on image %d, image %p", snap->image_index, snap->image); // Get new score. - motion_score = DetectMotion(*(snap->image), zoneSet); + int motion_score = DetectMotion(*(snap->image), zoneSet); snap->zone_stats.reserve(zones.size()); for (const Zone &zone : zones) { @@ -1892,21 +1890,20 @@ bool Monitor::Analyse() { Debug(3, "After motion detection, score:%d last_motion_score(%d), new motion score(%d)", score, last_motion_score, motion_score); motion_frame_count += 1; - // Why are we updating the last_motion_score too? last_motion_score = motion_score; + if (motion_score) { + if (cause.length()) cause += ", "; + cause += MOTION_CAUSE; + noteSetMap[MOTION_CAUSE] = zoneSet; + } // end if motion_score } } else { Debug(1, "no image so skipping motion detection"); } // end if has image } else { - Debug(1, "Skipped motion detection last motion score was %d", motion_score); + Debug(1, "Skipped motion detection last motion score was %d", last_motion_score); } - if (motion_score) { - score += motion_score; - if (cause.length()) cause += ", "; - cause += MOTION_CAUSE; - noteSetMap[MOTION_CAUSE] = zoneSet; - } // end if motion_score + score += last_motion_score; } else { Debug(1, "Not Active(%d) enabled %d active %d doing motion detection: %d", Active(), enabled, shared_data->active, @@ -2007,7 +2004,7 @@ bool Monitor::Analyse() { } // end if ! event } // end if RECORDING - if (score and (function == MODECT or function == NODECT)) { + if (score and (function == MODECT or function == NODECT or function == MOCORD)) { if ((state == IDLE) || (state == TAPE) || (state == PREALARM)) { // If we should end then previous continuous event and start a new non-continuous event if (event && event->Frames() @@ -2142,7 +2139,8 @@ bool Monitor::Analyse() { shared_data->state = state = ((function != MOCORD) ? IDLE : TAPE); } else { Debug(1, - "State %s because image_count(%d)-last_alarm_count(%d) > post_event_count(%d) and timestamp.tv_sec(%" PRIi64 ") - recording.tv_src(%" PRIi64 ") >= min_section_length(%" PRIi64 ")", + "State %d %s because analysis_image_count(%d)-last_alarm_count(%d) > post_event_count(%d) and timestamp.tv_sec(%" PRIi64 ") - recording.tv_src(%" PRIi64 ") >= min_section_length(%" PRIi64 ")", + state, State_Strings[state].c_str(), analysis_image_count, last_alarm_count, @@ -2161,12 +2159,10 @@ bool Monitor::Analyse() { // Generate analysis images if necessary if ((savejpegs > 1) and snap->image) { for (const Zone &zone : zones) { - if (zone.Alarmed()) { - if (zone.AlarmImage()) { + if (zone.Alarmed() and zone.AlarmImage()) { if (!snap->analysis_image) snap->analysis_image = new Image(*(snap->image)); snap->analysis_image->Overlay(*(zone.AlarmImage())); - } } // end if zone is alarmed } // end foreach zone } // end if savejpegs From bdf55f105e0dc1a18d0de38ba742ec4ff816447b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 13:54:33 -0500 Subject: [PATCH 105/174] Spacing --- src/zm_event.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 442033c50..d52f606a6 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -323,32 +323,32 @@ void Event::updateNotes(const StringSetMap &newNoteSetMap) { bool update = false; //Info( "Checking notes, %d <> %d", noteSetMap.size(), newNoteSetMap.size() ); - if ( newNoteSetMap.size() > 0 ) { - if ( noteSetMap.size() == 0 ) { + if (newNoteSetMap.size() > 0) { + if (noteSetMap.size() == 0) { noteSetMap = newNoteSetMap; update = true; } else { - for ( StringSetMap::const_iterator newNoteSetMapIter = newNoteSetMap.begin(); + for (StringSetMap::const_iterator newNoteSetMapIter = newNoteSetMap.begin(); newNoteSetMapIter != newNoteSetMap.end(); - ++newNoteSetMapIter ) { + ++newNoteSetMapIter) { const std::string &newNoteGroup = newNoteSetMapIter->first; const StringSet &newNoteSet = newNoteSetMapIter->second; //Info( "Got %d new strings", newNoteSet.size() ); - if ( newNoteSet.size() > 0 ) { + if (newNoteSet.size() > 0) { StringSetMap::iterator noteSetMapIter = noteSetMap.find(newNoteGroup); - if ( noteSetMapIter == noteSetMap.end() ) { - //Info( "Can't find note group %s, copying %d strings", newNoteGroup.c_str(), newNoteSet.size() ); + if (noteSetMapIter == noteSetMap.end()) { + //Debug(3, "Can't find note group %s, copying %d strings", newNoteGroup.c_str(), newNoteSet.size()); noteSetMap.insert(StringSetMap::value_type(newNoteGroup, newNoteSet)); update = true; } else { StringSet ¬eSet = noteSetMapIter->second; - //Info( "Found note group %s, got %d strings", newNoteGroup.c_str(), newNoteSet.size() ); - for ( StringSet::const_iterator newNoteSetIter = newNoteSet.begin(); + //Debug(3, "Found note group %s, got %d strings", newNoteGroup.c_str(), newNoteSet.size()); + for (StringSet::const_iterator newNoteSetIter = newNoteSet.begin(); newNoteSetIter != newNoteSet.end(); - ++newNoteSetIter ) { + ++newNoteSetIter) { const std::string &newNote = *newNoteSetIter; StringSet::iterator noteSetIter = noteSet.find(newNote); - if ( noteSetIter == noteSet.end() ) { + if (noteSetIter == noteSet.end()) { noteSet.insert(newNote); update = true; } From 82a26a1f83bd8c55b05e9fcf039d6d71e07f5299 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 13:59:05 -0500 Subject: [PATCH 106/174] use != Monitor instead of all the other cases --- src/zm_monitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index cdf544682..81eacc956 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -2004,7 +2004,7 @@ bool Monitor::Analyse() { } // end if ! event } // end if RECORDING - if (score and (function == MODECT or function == NODECT or function == MOCORD)) { + if (score and (function != MONITOR)) { if ((state == IDLE) || (state == TAPE) || (state == PREALARM)) { // If we should end then previous continuous event and start a new non-continuous event if (event && event->Frames() From 53c57478b812f555289c20065ac4c2b19a1c597c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 14:00:04 -0500 Subject: [PATCH 107/174] Ignore versioned bootstrap --- .eslintignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index 4682851df..91b0fd196 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,7 +4,7 @@ web/api/lib web/includes/csrf/ web/js/videojs.zoomrotate.js -web/skins/classic/js/bootstrap.js +web/skins/classic/js/bootstrap-4.5.0.js web/skins/classic/js/chosen web/skins/classic/js/dateTimePicker web/skins/classic/js/jquery-*.js From c76e688f05a8c67914c18b44766dc6fd799437b6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 15:49:25 -0500 Subject: [PATCH 108/174] Don't exit(0) on QUIT. Instead set zm_terminate=true so that all the cleanup routines run. --- src/zm_monitorstream.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index 5c32b8e05..9bc04a311 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -229,6 +229,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) { break; case CMD_QUIT : Info("User initiated exit - CMD_QUIT"); + zm_terminate = true; break; case CMD_QUERY : Debug(1, "Got QUERY command, sending STATUS"); @@ -315,16 +316,6 @@ void MonitorStream::processCommand(const CmdMsg *msg) { } } Debug(2, "Number of bytes sent to (%s): (%d)", rem_addr.sun_path, nbytes); - - // quit after sending a status, if this was a quit request - if ( (MsgCommand)msg->msg_data[0] == CMD_QUIT ) { - zm_terminate = true; - Debug(2, "Quitting"); - return; - } - - //Debug(2,"Updating framerate"); - //updateFrameRate(monitor->GetFPS()); } // end void MonitorStream::processCommand(const CmdMsg *msg) bool MonitorStream::sendFrame(const std::string &filepath, SystemTimePoint timestamp) { From acff4fb9c0900fce29c14487a25384bec3e84b90 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 14:32:06 -0500 Subject: [PATCH 109/174] rough in fullscreen mode in watch view --- web/skins/classic/js/skin.js | 26 ++++++++++++++++++++++++++ web/skins/classic/views/js/watch.js | 5 +++++ web/skins/classic/views/watch.php | 3 +++ 3 files changed, 34 insertions(+) diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index c7e2afedf..6ede08479 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -947,3 +947,29 @@ function initThumbAnimation() { }); } } + +/* View in fullscreen */ +function openFullscreen(elem) { + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.webkitRequestFullscreen) { + /* Safari */ + elem.webkitRequestFullscreen(); + } else if (elem.msRequestFullscreen) { + /* IE11 */ + elem.msRequestFullscreen(); + } +} + +/* Close fullscreen */ +function closeFullscreen() { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.webkitExitFullscreen) { + /* Safari */ + document.webkitExitFullscreen(); + } else if (document.msExitFullscreen) { + /* IE11 */ + document.msExitFullscreen(); + } +} diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index aacad5126..5ba4b407c 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -970,5 +970,10 @@ function initPage() { }); } // initPage +function watchFullscreen() { + const content = document.getElementById('content'); + openFullscreen(content); +} + // Kick everything off $j(document).ready(initPage); diff --git a/web/skins/classic/views/watch.php b/web/skins/classic/views/watch.php index e1e54c3c7..beab28ac1 100644 --- a/web/skins/classic/views/watch.php +++ b/web/skins/classic/views/watch.php @@ -142,6 +142,9 @@ if ( $streamMode == 'jpeg' ) { + From dc9f7b4d1d5960282f46c39c445b3a675753e240 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 16:12:39 -0500 Subject: [PATCH 110/174] Rough in fullscreen mode on montage --- web/skins/classic/views/js/montage.js | 5 +++++ web/skins/classic/views/montage.php | 3 +++ 2 files changed, 8 insertions(+) diff --git a/web/skins/classic/views/js/montage.js b/web/skins/classic/views/js/montage.js index 5312928a6..75b3a74d2 100644 --- a/web/skins/classic/views/js/montage.js +++ b/web/skins/classic/views/js/montage.js @@ -317,5 +317,10 @@ function initPage() { } selectLayout('#zmMontageLayout'); } + +function watchFullscreen() { + const content = document.getElementById('content'); + openFullscreen(content); +} // Kick everything off $j(document).ready(initPage); diff --git a/web/skins/classic/views/montage.php b/web/skins/classic/views/montage.php index 3256cfcc8..b0b10f190 100644 --- a/web/skins/classic/views/montage.php +++ b/web/skins/classic/views/montage.php @@ -206,6 +206,9 @@ if ( canView('System') ) {   + From 9d37fbcd8e7e66e76396200df8e757548aeed668 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Nov 2021 17:01:04 -0500 Subject: [PATCH 111/174] Fix some build warnings on arm --- src/zm_fifo.cpp | 4 ++-- src/zm_monitor.cpp | 22 +++++++++++----------- src/zm_packetqueue.cpp | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/zm_fifo.cpp b/src/zm_fifo.cpp index 319c35c31..a999adc23 100644 --- a/src/zm_fifo.cpp +++ b/src/zm_fifo.cpp @@ -143,8 +143,8 @@ bool Fifo::writePacket(std::string filename, const ZMPacket &packet) { bool Fifo::write(uint8_t *data, size_t bytes, int64_t pts) { if (!(outfile or open())) return false; // Going to write a brief header - Debug(1, "Writing header ZM %lu %" PRId64, bytes, pts); - if ( fprintf(outfile, "ZM %lu %" PRId64 "\n", bytes, pts) < 0 ) { + Debug(1, "Writing header ZM %zu %" PRId64, bytes, pts); + if (fprintf(outfile, "ZM %zu %" PRId64 "\n", bytes, pts) < 0) { if (errno != EAGAIN) { Error("Problem during writing: %s", strerror(errno)); } else { diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 81eacc956..b6e69a19f 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -155,7 +155,7 @@ bool Monitor::MonitorLink::connect() { mem_size = sizeof(SharedData) + sizeof(TriggerData); - Debug(1, "link.mem.size=%jd", mem_size); + Debug(1, "link.mem.size=%jd", static_cast(mem_size)); #if ZM_MEM_MAPPED map_fd = open(mem_file.c_str(), O_RDWR, (mode_t)0600); if (map_fd < 0) { @@ -182,14 +182,14 @@ bool Monitor::MonitorLink::connect() { disconnect(); return false; } else if (map_stat.st_size < mem_size) { - Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, mem_size); + Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, static_cast(mem_size)); disconnect(); return false; } mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0); if (mem_ptr == MAP_FAILED) { - Error("Can't map file %s (%jd bytes) to memory: %s", mem_file.c_str(), mem_size, strerror(errno)); + Error("Can't map file %s (%jd bytes) to memory: %s", mem_file.c_str(), static_cast(mem_size), strerror(errno)); disconnect(); return false; } @@ -947,7 +947,7 @@ bool Monitor::connect() { map_fd = -1; return false; } else { - Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, mem_size); + Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, static_cast(mem_size)); close(map_fd); map_fd = -1; return false; @@ -959,18 +959,18 @@ bool Monitor::connect() { mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0); if (mem_ptr == MAP_FAILED) { if (errno == EAGAIN) { - Debug(1, "Unable to map file %s (%jd bytes) to locked memory, trying unlocked", mem_file.c_str(), mem_size); + Debug(1, "Unable to map file %s (%jd bytes) to locked memory, trying unlocked", mem_file.c_str(), static_cast(mem_size)); #endif mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0); - Debug(1, "Mapped file %s (%jd bytes) to unlocked memory", mem_file.c_str(), mem_size); + Debug(1, "Mapped file %s (%jd bytes) to unlocked memory", mem_file.c_str(), static_cast(mem_size)); #ifdef MAP_LOCKED } else { - Error("Unable to map file %s (%jd bytes) to locked memory (%s)", mem_file.c_str(), mem_size, strerror(errno)); + Error("Unable to map file %s (%jd bytes) to locked memory (%s)", mem_file.c_str(), static_cast(mem_size), strerror(errno)); } } #endif if ((mem_ptr == MAP_FAILED) or (mem_ptr == nullptr)) { - Error("Can't map file %s (%jd bytes) to memory: %s(%d)", mem_file.c_str(), mem_size, strerror(errno), errno); + Error("Can't map file %s (%jd bytes) to memory: %s(%d)", mem_file.c_str(), static_cast(mem_size), strerror(errno), errno); close(map_fd); map_fd = -1; mem_ptr = nullptr; @@ -2310,7 +2310,7 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) { while ( 1 ) { dest_ptr = link_id_str; while ( *src_ptr >= '0' && *src_ptr <= '9' ) { - if ( (dest_ptr-link_id_str) < (unsigned int)(sizeof(link_id_str)-1) ) { + if ( (unsigned int)(dest_ptr-link_id_str) < (unsigned int)(sizeof(link_id_str)-1) ) { *dest_ptr++ = *src_ptr++; } else { break; @@ -2741,7 +2741,7 @@ void Monitor::TimestampImage(Image *ts_image, SystemTimePoint ts_time) const { const char *s_ptr = label_time_text; char *d_ptr = label_text; - while (*s_ptr && ((d_ptr - label_text) < (unsigned int) sizeof(label_text))) { + while (*s_ptr && ((unsigned int)(d_ptr - label_text) < (unsigned int) sizeof(label_text))) { if ( *s_ptr == config.timestamp_code_char[0] ) { bool found_macro = false; switch ( *(s_ptr+1) ) { @@ -2757,7 +2757,7 @@ void Monitor::TimestampImage(Image *ts_image, SystemTimePoint ts_time) const { typedef std::chrono::duration Centiseconds; Centiseconds centi_sec = std::chrono::duration_cast( ts_time.time_since_epoch() - std::chrono::duration_cast(ts_time.time_since_epoch())); - d_ptr += snprintf(d_ptr, sizeof(label_text) - (d_ptr - label_text), "%02ld", centi_sec.count()); + d_ptr += snprintf(d_ptr, sizeof(label_text) - (d_ptr - label_text), "%02lld", static_cast(centi_sec.count())); found_macro = true; break; } diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index ceef421db..509a25ee6 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -209,7 +209,7 @@ void PacketQueue::clearPackets(const std::shared_ptr &add_packet) { --it; } } - Debug(1, "Tail count is %d, queue size is %lu", tail_count, pktQueue.size()); + Debug(1, "Tail count is %d, queue size is %zu", tail_count, pktQueue.size()); if (!keep_keyframes) { // If not doing passthrough, we don't care about starting with a keyframe so logic is simpler From 98e29e7ef6d68b01ac2ac81ab04fd6869dcb39d6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:18:58 -0500 Subject: [PATCH 112/174] implement UrlToZMS in Monitor --- web/includes/Monitor.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index bd9987b2c..6423af11f 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -499,6 +499,10 @@ class Monitor extends ZM_Object { return $this->Server()->UrlToIndex($port); } + public function UrlToZMS($port=null) { + return $this->Server()->UrlToZMS($port).'?mid='.$this->Id(); + } + public function sendControlCommand($command) { // command is generally a command option list like --command=blah but might be just the word quit From 8d0463bbff5e9cef3d954f30e40fab752d8a7020 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:20:19 -0500 Subject: [PATCH 113/174] Implement getElement, setScale in MonitorStream.js --- web/js/MonitorStream.js | 75 ++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index a10d90008..feb4b3611 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -3,8 +3,10 @@ function MonitorStream(monitorData) { this.id = monitorData.id; this.connKey = monitorData.connKey; this.url = monitorData.url; + this.url_to_zms = monitorData.url_to_zms; this.width = monitorData.width; this.height = monitorData.height; + this.scale = 100; this.status = null; this.alarmState = STATE_IDLE; this.lastAlarmState = STATE_IDLE; @@ -15,19 +17,68 @@ function MonitorStream(monitorData) { }; this.type = monitorData.type; this.refresh = monitorData.refresh; + this.element = null; + this.getElement = function() { + if (this.element) return this.element; + this.element = document.getElementById('liveStream'+this.id); + if (!this.element) { + console.error("No img for #liveStream"+this.id); + } + return this.element; + }; + + /* if the img element didn't have a src, this would fill it in, causing it to show. */ + this.show = function() { + const stream = this.getElement(); + if (!stream.src) { + stream.src = this.url_to_zms+"&mode=single&scale=100&connkey="+this.connKey; + } + }; + + this.setScale = function(newscale) { + const img = this.getElement(); + if (!img) return; + + this.scale = newscale; + + const oldSrc = img.getAttribute('src'); + let newSrc = ''; + + img.setAttribute('src', ''); + console.log("Scaling to: " + newscale); + + if (newscale == '0' || newscale == 'auto') { + let bottomElement = document.getElementById('replayStatus'); + if (!bottomElement) { + bottomElement = document.getElementById('monitorState'); + } + var newSize = scaleToFit(this.width, this.height, $j(img), $j(bottomElement)); + + console.log(newSize); + newWidth = newSize.width; + newHeight = newSize.height; + autoScale = parseInt(newSize.autoScale); + // This is so that we don't waste bandwidth and let the browser do all the scaling. + if (autoScale > 100) autoScale = 100; + if (autoScale) { + newSrc = oldSrc.replace(/scale=\d+/i, 'scale='+autoScale); + } + } else { + newWidth = this.width * newscale / SCALE_BASE; + newHeight = this.height * newscale / SCALE_BASE; + img.width(newWidth); + img.height(newHeight); + if (newscale > 100) newscale = 100; + newSrc = oldSrc.replace(/scale=\d+/i, 'scale='+newscale); + } + img.setAttribute('src', newSrc); + }; this.start = function(delay) { // Step 1 make sure we are streaming instead of a static image - var stream = $j('#liveStream'+this.id); - if (!stream.length) { - console.log('No live stream'); - return; - } - stream = stream[0]; - if ( !stream ) { - console.log('No live stream'); - return; - } - if ( !stream.src ) { + const stream = this.getElement(); + if (!stream) return; + + if (!stream.src) { // Website Monitors won't have an img tag console.log('No src for #liveStream'+this.id); console.log(stream); @@ -38,7 +89,7 @@ function MonitorStream(monitorData) { src += '&connkey='+this.connKey; } if ( stream.src != src ) { - console.log("Setting to streaming"); + console.log("Setting to streaming: " + src); stream.src = ''; stream.src = src; } From 6f3e22f2a0ed27140512d13d785bf7401d6729df Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:21:12 -0500 Subject: [PATCH 114/174] If no bottom element is specified, take the last child of content in scaleToFit --- web/skins/classic/js/skin.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index 6ede08479..a12005e76 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -584,10 +584,21 @@ function scaleToFit(baseWidth, baseHeight, scaleEl, bottomEl) { $j(window).on('resize', endOfResize); //set delayed scaling when Scale to Fit is selected var ratio = baseWidth / baseHeight; var container = $j('#content'); + if (!container) { + console.error("No container found"); + return; + } + + if (!bottomEl || !bottomEl.length) { + bottomEl = $j(container[0].lastElementChild); + } + //console.log(bottomEl); var viewPort = $j(window); - // jquery does not provide a bottom offet, and offset dows not include margins. outerHeight true minus false gives total vertical margins. + // jquery does not provide a bottom offset, and offset does not include margins. outerHeight true minus false gives total vertical margins. var bottomLoc = bottomEl.offset().top + (bottomEl.outerHeight(true) - bottomEl.outerHeight()) + bottomEl.outerHeight(true); + //console.log("bottomLoc: " + bottomEl.offset().top + " + (" + bottomEl.outerHeight(true) + ' - ' + bottomEl.outerHeight() +') + '+bottomEl.outerHeight(true)); var newHeight = viewPort.height() - (bottomLoc - scaleEl.outerHeight(true)); + //console.log("newHeight = " + viewPort.height() +" - " + bottomLoc + ' - ' + scaleEl.outerHeight(true)); var newWidth = ratio * newHeight; if (newWidth > container.innerWidth()) { newWidth = container.innerWidth(); @@ -598,13 +609,15 @@ function scaleToFit(baseWidth, baseHeight, scaleEl, bottomEl) { return parseInt($j(this).val()); }).get(); scales.shift(); - var closest; + var closest = null; $j(scales).each(function() { //Set zms scale to nearest regular scale. Zoom does not like arbitrary scale values. if (closest == null || Math.abs(this - autoScale) < Math.abs(closest - autoScale)) { closest = this.valueOf(); } }); - autoScale = closest; + if (closest) { + autoScale = closest; + } return {width: Math.floor(newWidth), height: Math.floor(newHeight), autoScale: autoScale}; } From a7fd65d844134b2be36dfa303b606763c6b54800 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:21:38 -0500 Subject: [PATCH 115/174] Put SCALE_BASE in skin.js.php as it is used in many places. --- web/skins/classic/js/skin.js.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/skins/classic/js/skin.js.php b/web/skins/classic/js/skin.js.php index 802a21095..87e08310e 100644 --- a/web/skins/classic/js/skin.js.php +++ b/web/skins/classic/js/skin.js.php @@ -54,6 +54,7 @@ foreach ( $perms as $perm ) { ?> var ANIMATE_THUMBS = ; +var SCALE_BASE = ; var refreshParent = Date: Wed, 10 Nov 2021 14:22:05 -0500 Subject: [PATCH 116/174] Implement Exit Fullscreen using same button --- web/skins/classic/views/js/watch.js | 14 ++++++++++++-- web/skins/classic/views/js/watch.js.php | 6 +++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 5ba4b407c..324e7f7e0 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -971,8 +971,18 @@ function initPage() { } // initPage function watchFullscreen() { - const content = document.getElementById('content'); - openFullscreen(content); + const btn = document.getElementById('fullscreenBtn'); + console.log(btn); + if (btn.firstElementChild.innerHTML=='fullscreen') { + const content = document.getElementById('content'); + openFullscreen(content); + btn.firstElementChild.innerHTML='fullscreen_exit'; + btn.setAttribute('title', translate["Exit Fullscreen"]); + } else { + closeFullscreen(); + btn.firstElementChild.innerHTML='fullscreen'; + btn.setAttribute('title', translate["Fullscreen"]); + } } // Kick everything off diff --git a/web/skins/classic/views/js/watch.js.php b/web/skins/classic/views/js/watch.js.php index 258a1da73..5b4568dfc 100644 --- a/web/skins/classic/views/js/watch.js.php +++ b/web/skins/classic/views/js/watch.js.php @@ -97,9 +97,13 @@ foreach( dbFetchAll( 'SELECT * FROM ControlPresets WHERE MonitorId = ?', NULL, a $labels[$row['Preset']] = $row['Label']; } -foreach ( $labels as $index=>$label ) { +foreach ($labels as $index=>$label) { ?> labels[] = ''; +var translate = { + "Fullscreen": "", + "Exit Fullscreen": "", +}; From 529e889d9912ca015277931e7988f32c39599061 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:23:36 -0500 Subject: [PATCH 117/174] remove extra , --- web/ajax/event.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ajax/event.php b/web/ajax/event.php index 906fe255a..a0b9cb57a 100644 --- a/web/ajax/event.php +++ b/web/ajax/event.php @@ -93,7 +93,7 @@ if ( canView('Events') or canView('Snapshots') ) { $exportFormat, $exportCompress, $exportStructure, - (!empty($_REQUEST['exportFile'])?$_REQUEST['exportFile']:'zmExport'), + (!empty($_REQUEST['exportFile'])?$_REQUEST['exportFile']:'zmExport') )) { ajaxResponse(array('exportFile'=>$exportFile)); } else { From ac03a88550357aa3ed56f2fa68bdda93f93ad2d7 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:25:12 -0500 Subject: [PATCH 118/174] Include url_to_zms in monitorData --- web/skins/classic/views/js/zone.js.php | 1 + web/skins/classic/views/js/zones.js.php | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/zone.js.php b/web/skins/classic/views/js/zone.js.php index fc6616327..37eb6db82 100644 --- a/web/skins/classic/views/js/zone.js.php +++ b/web/skins/classic/views/js/zone.js.php @@ -66,6 +66,7 @@ monitorData[monitorData.length] = { 'width': ViewWidth() ?>, 'height':ViewHeight() ?>, 'url': 'UrlToIndex( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>', + 'url_to_zms': 'UrlToZMS( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>', 'type': 'Type() ?>', 'refresh': 'Refresh() ?>' }; diff --git a/web/skins/classic/views/js/zones.js.php b/web/skins/classic/views/js/zones.js.php index 180a19d81..338095552 100644 --- a/web/skins/classic/views/js/zones.js.php +++ b/web/skins/classic/views/js/zones.js.php @@ -9,6 +9,7 @@ monitorData[monitorData.length] = { 'width': ViewWidth() ?>, 'height':ViewHeight() ?>, 'url': 'UrlToIndex( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>', + 'url_to_zms': 'UrlToZMS( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>', 'type': 'Type() ?>', 'refresh': 'Refresh() ?>' }; @@ -24,7 +25,7 @@ var STATE_TAPE = ; var stateStrings = new Array(); stateStrings[STATE_IDLE] = ""; -stateStrings[STATE_PREALARM] = ""; +stateStrings[STATE_PREALARM] = ""; stateStrings[STATE_ALARM] = ""; stateStrings[STATE_ALERT] = ""; stateStrings[STATE_TAPE] = ""; From 795c5bb7d728dbe0f7ae68d346dd0f67827009ce Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:25:29 -0500 Subject: [PATCH 119/174] setScale to auto --- web/skins/classic/views/js/zone.js | 1 + web/skins/classic/views/js/zones.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/web/skins/classic/views/js/zone.js b/web/skins/classic/views/js/zone.js index 6282cbf8a..58c286b43 100644 --- a/web/skins/classic/views/js/zone.js +++ b/web/skins/classic/views/js/zone.js @@ -661,6 +661,7 @@ function initPage() { // Start the fps and status updates. give a random delay so that we don't assault the server var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout ); + monitors[i].setScale('auto'); monitors[i].start(delay); } diff --git a/web/skins/classic/views/js/zones.js b/web/skins/classic/views/js/zones.js index 0ad91942d..67dcb094a 100644 --- a/web/skins/classic/views/js/zones.js +++ b/web/skins/classic/views/js/zones.js @@ -12,6 +12,7 @@ function initPage() { // Start the fps and status updates. give a random delay so that we don't assault the server var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout ); + monitors[i].setScale('auto'); monitors[i].start(delay); } @@ -31,5 +32,12 @@ function initPage() { }); } +function streamCmdQuit() { + for ( var i = 0, length = monitorData.length; i < length; i++ ) { + monitors[i] = new MonitorStream(monitorData[i]); + monitors[i].stop(); + } +} + window.addEventListener('DOMContentLoaded', initPage); From 8872b8be6325a0f90ec5de3c93770fb93f37ac39 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 14:25:45 -0500 Subject: [PATCH 120/174] spacing --- web/skins/classic/views/zones.php | 67 +++++++++++++++---------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/web/skins/classic/views/zones.php b/web/skins/classic/views/zones.php index f457ad2fc..423326a98 100644 --- a/web/skins/classic/views/zones.php +++ b/web/skins/classic/views/zones.php @@ -80,15 +80,14 @@ xhtmlHeaders(__FILE__, translate('Zones')); Sorry, your browser does not support inline SVG @@ -96,37 +95,37 @@ xhtmlHeaders(__FILE__, translate('Zones'));  -  fps -
- - - - - - - - - - - - - - - - - - - -
 / ViewWidth()*$monitor->ViewHeight()) ) ?> disabled="disabled"/>
-
- - -
-
-
+
+ + + + + + + + + + + + + + + + + + + +
 / ViewWidth()*$monitor->ViewHeight()) ) ?> disabled="disabled"/>
+
+ + +
+
+
Date: Wed, 10 Nov 2021 16:53:07 -0500 Subject: [PATCH 121/174] Use event->StartTime instead of GetVideoWriterStartTime. Add some parenthesis to make logic clearer and add more info to debug statements --- src/zm_monitor.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index b6e69a19f..d808ddba0 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1916,7 +1916,7 @@ bool Monitor::Analyse() { if (event) { Debug(2, "Have event %" PRIu64 " in record", event->Id()); - if (section_length != Seconds(0) && (timestamp - GetVideoWriterStartTime() >= section_length) + if (section_length != Seconds(0) && (timestamp - event->StartTime() >= section_length) && ((function == MOCORD && event_close_mode != CLOSE_TIME) || (function == RECORD && event_close_mode == CLOSE_TIME) || std::chrono::duration_cast(timestamp.time_since_epoch()) % section_length == Seconds(0))) { @@ -1925,8 +1925,8 @@ bool Monitor::Analyse() { image_count, event->Id(), static_cast(std::chrono::duration_cast(timestamp.time_since_epoch()).count()), - static_cast(std::chrono::duration_cast(GetVideoWriterStartTime().time_since_epoch()).count()), - static_cast(std::chrono::duration_cast(timestamp - GetVideoWriterStartTime()).count()), + static_cast(std::chrono::duration_cast(event->StartTime().time_since_epoch()).count()), + static_cast(std::chrono::duration_cast(timestamp - event->StartTime()).count()), static_cast(Seconds(section_length).count())); closeEvent(); } // end if section_length @@ -2009,21 +2009,22 @@ bool Monitor::Analyse() { // If we should end then previous continuous event and start a new non-continuous event if (event && event->Frames() && !event->AlarmFrames() - && event_close_mode == CLOSE_ALARM - && timestamp - GetVideoWriterStartTime() >= min_section_length - && (!pre_event_count || Event::PreAlarmCount() >= alarm_frame_count - 1)) { + && (event_close_mode == CLOSE_ALARM) + && ((timestamp - event->StartTime()) >= min_section_length) + && ((!pre_event_count) || (Event::PreAlarmCount() >= alarm_frame_count - 1))) { Info("%s: %03d - Closing event %" PRIu64 ", continuous end, alarm begins", name.c_str(), image_count, event->Id()); closeEvent(); } else if (event) { // This is so if we need more than 1 alarm frame before going into alarm, so it is basically if we have enough alarm frames Debug(3, - "pre_alarm_count in event %d, event frames %d, alarm frames %d event length %" PRIi64 " >=? %" PRIi64 " min", - Event::PreAlarmCount(), + "pre_alarm_count in event %d of %d, event frames %d, alarm frames %d event length %" PRIi64 " >=? %" PRIi64 " min close mode is ALARM? %d", + Event::PreAlarmCount(), pre_event_count, event->Frames(), event->AlarmFrames(), - static_cast(std::chrono::duration_cast(timestamp - GetVideoWriterStartTime()).count()), - static_cast(Seconds(min_section_length).count())); + static_cast(std::chrono::duration_cast(timestamp - event->StartTime()).count()), + static_cast(Seconds(min_section_length).count()), + (event_close_mode == CLOSE_ALARM)); } if ((!pre_event_count) || (Event::PreAlarmCount() >= alarm_frame_count-1)) { // lets construct alarm cause. It will contain cause + names of zones alarmed @@ -2120,8 +2121,10 @@ bool Monitor::Analyse() { Info("%s: %03d - Gone into alert state", name.c_str(), analysis_image_count); shared_data->state = state = ALERT; } else if (state == ALERT) { - if (analysis_image_count - last_alarm_count > post_event_count - && timestamp - GetVideoWriterStartTime() >= min_section_length) { + if ( + ((analysis_image_count - last_alarm_count) > post_event_count) + && + ((timestamp - event->StartTime()) >= min_section_length)) { Info("%s: %03d - Left alarm state (%" PRIu64 ") - %d(%d) images", name.c_str(), analysis_image_count, event->Id(), event->Frames(), event->AlarmFrames()); //if ( function != MOCORD || event_close_mode == CLOSE_ALARM || event->Cause() == SIGNAL_CAUSE ) @@ -2168,7 +2171,6 @@ bool Monitor::Analyse() { } // end if savejpegs // incremement pre alarm image count - //have_pre_alarmed_frames ++; Event::AddPreAlarmFrame(snap->image, timestamp, score, nullptr); } else if (state == ALARM) { for (const Zone &zone : zones) { @@ -2183,7 +2185,7 @@ bool Monitor::Analyse() { if (event) { if (noteSetMap.size() > 0) event->updateNotes(noteSetMap); - if (section_length != Seconds(0) && (timestamp - GetVideoWriterStartTime() >= section_length)) { + if (section_length != Seconds(0) && (timestamp - event->StartTime() >= section_length)) { Warning("%s: %03d - event %" PRIu64 ", has exceeded desired section length. %" PRIi64 " - %" PRIi64 " = %" PRIi64 " >= %" PRIi64, name.c_str(), analysis_image_count, event->Id(), static_cast(std::chrono::duration_cast(timestamp.time_since_epoch()).count()), From e35dc3902ef5f10268603412f190fe3adeb6172c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 16:53:29 -0500 Subject: [PATCH 122/174] Make state enum start at 0 as we are indexing into an array for StateStrings --- src/zm_monitor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 56785405f..5b9a2ce46 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -100,7 +100,7 @@ public: } Deinterlace; typedef enum { - UNKNOWN=-1, + UNKNOWN, IDLE, PREALARM, ALARM, From c84f42e2804519bc6e11a1bb58b579af9bc97f65 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Nov 2021 17:05:46 -0500 Subject: [PATCH 123/174] Set to never timeout while generating video --- web/skins/classic/views/js/video.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/skins/classic/views/js/video.js b/web/skins/classic/views/js/video.js index 970119f4f..c764f33b5 100644 --- a/web/skins/classic/views/js/video.js +++ b/web/skins/classic/views/js/video.js @@ -16,6 +16,9 @@ function generateVideoResponse( data, responseText ) { } function generateVideo() { + $j.ajaxSetup({ + timeout: 0 + }); var form = $j('#videoForm').serialize(); $j.getJSON(thisUrl + '?view=request&request=event&action=video', form) .done(generateVideoResponse) From d00430f799c450f7f213e9aff364b26c6a7ac6bb Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 15 Nov 2021 09:47:11 -0500 Subject: [PATCH 124/174] Add ModelId to MonitorPresets --- db/zm_create.sql.in | 1 + db/zm_update-1.37.3.sql | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index ecc2d477d..9a048886d 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -412,6 +412,7 @@ CREATE TABLE `Models` ( DROP TABLE IF EXISTS `MonitorPresets`; CREATE TABLE `MonitorPresets` ( `Id` int(10) unsigned NOT NULL auto_increment, + `ModelId` int unsigned, FOREIGN KEY (`ModelId`) REFERENCES `Models` (Id), `Name` varchar(64) NOT NULL default '', `Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL','WebSite','NVSocket','VNC') NOT NULL default 'Local', `Device` tinytext, diff --git a/db/zm_update-1.37.3.sql b/db/zm_update-1.37.3.sql index 341c5e162..9002ce8e2 100644 --- a/db/zm_update-1.37.3.sql +++ b/db/zm_update-1.37.3.sql @@ -45,3 +45,26 @@ SET @s = (SELECT IF( PREPARE stmt FROM @s; EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'MonitorPresets' + AND column_name = 'ModelId' + ) > 0, +"SELECT 'Column ModelId already exists in MonitorPresets'", +"ALTER TABLE `MonitorPresets` ADD `ModelId` int(10) unsigned AFTER `Id`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema = DATABASE() + AND table_name = 'MonitorPresets' + AND column_name = 'ModelId' + ) > 0, +"SELECT 'FOREIGN KEY for ModelId already exists in MonitorPresets'", +"ALTER TABLE `MonitorPresets` ADD FOREIGN KEY (`ModelId`) REFERENCES `Models` (Id)" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; From e63222d7337edfa8643e0e9064bbf83253e30266 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 15 Nov 2021 16:30:03 -0500 Subject: [PATCH 125/174] Add IGNORE so it does UPSERT --- db/manufacturers.sql | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/db/manufacturers.sql b/db/manufacturers.sql index be15f9c01..3761f5cbe 100644 --- a/db/manufacturers.sql +++ b/db/manufacturers.sql @@ -1,24 +1,24 @@ -INSERT INTO Manufacturers VALUES (1, 'Acti'); -INSERT INTO Manufacturers VALUES (2, 'Amcrest'); -INSERT INTO Manufacturers VALUES (3, 'Airlink101'); -INSERT INTO Manufacturers VALUES (4, 'Arecont Vision'); -INSERT INTO Manufacturers VALUES (5, 'Axis'); -INSERT INTO Manufacturers VALUES (6, 'Dahua'); -INSERT INTO Manufacturers VALUES (7, 'D-Link'); -INSERT INTO Manufacturers VALUES (8, 'Edimax'); -INSERT INTO Manufacturers VALUES (9, 'Foscam'); -INSERT INTO Manufacturers VALUES (10, 'Gadspot'); -INSERT INTO Manufacturers VALUES (11, 'GrandStream'); -INSERT INTO Manufacturers VALUES (12, 'HikVision'); -INSERT INTO Manufacturers VALUES (13, 'JVC'); -INSERT INTO Manufacturers VALUES (14, 'Maginon'); -INSERT INTO Manufacturers VALUES (15, 'Mobotix'); -INSERT INTO Manufacturers VALUES (16, 'Oncam Grandeye'); -INSERT INTO Manufacturers VALUES (17, 'Panasonic'); -INSERT INTO Manufacturers VALUES (18, 'Pelco'); -INSERT INTO Manufacturers VALUES (19, 'Sony'); -INSERT INTO Manufacturers VALUES (20, 'TP-Link'); -INSERT INTO Manufacturers VALUES (21, 'Trendnet'); -INSERT INTO Manufacturers VALUES (22, 'VisionTek'); -INSERT INTO Manufacturers VALUES (23, 'Vivotek'); -INSERT INTO Manufacturers VALUES (24, 'Wansview'); +INSERT IGNORE INTO Manufacturers VALUES (1, 'Acti'); +INSERT IGNORE INTO Manufacturers VALUES (2, 'Amcrest'); +INSERT IGNORE INTO Manufacturers VALUES (3, 'Airlink101'); +INSERT IGNORE INTO Manufacturers VALUES (4, 'Arecont Vision'); +INSERT IGNORE INTO Manufacturers VALUES (5, 'Axis'); +INSERT IGNORE INTO Manufacturers VALUES (6, 'Dahua'); +INSERT IGNORE INTO Manufacturers VALUES (7, 'D-Link'); +INSERT IGNORE INTO Manufacturers VALUES (8, 'Edimax'); +INSERT IGNORE INTO Manufacturers VALUES (9, 'Foscam'); +INSERT IGNORE INTO Manufacturers VALUES (10, 'Gadspot'); +INSERT IGNORE INTO Manufacturers VALUES (11, 'GrandStream'); +INSERT IGNORE INTO Manufacturers VALUES (12, 'HikVision'); +INSERT IGNORE INTO Manufacturers VALUES (13, 'JVC'); +INSERT IGNORE INTO Manufacturers VALUES (14, 'Maginon'); +INSERT IGNORE INTO Manufacturers VALUES (15, 'Mobotix'); +INSERT IGNORE INTO Manufacturers VALUES (16, 'Oncam Grandeye'); +INSERT IGNORE INTO Manufacturers VALUES (17, 'Panasonic'); +INSERT IGNORE INTO Manufacturers VALUES (18, 'Pelco'); +INSERT IGNORE INTO Manufacturers VALUES (19, 'Sony'); +INSERT IGNORE INTO Manufacturers VALUES (20, 'TP-Link'); +INSERT IGNORE INTO Manufacturers VALUES (21, 'Trendnet'); +INSERT IGNORE INTO Manufacturers VALUES (22, 'VisionTek'); +INSERT IGNORE INTO Manufacturers VALUES (23, 'Vivotek'); +INSERT IGNORE INTO Manufacturers VALUES (24, 'Wansview'); From 4e9a56624d8d7f86f3ad83059044f77599af42a1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 15 Nov 2021 16:30:17 -0500 Subject: [PATCH 126/174] Use UPSERTS and add some more models --- db/models.sql | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/db/models.sql b/db/models.sql index b7150d816..ffafb76a8 100644 --- a/db/models.sql +++ b/db/models.sql @@ -1,30 +1,41 @@ /* INSERT INTO Manufacturers VALUES (1, 'Acti'); */ -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A21'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A23'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A24'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A28'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A31'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A310'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A311'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A32'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A41'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A415'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A416'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A418'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A42'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A421'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A43'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A45'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A46'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A48'); -INSERT INTO Models (ManufacturerId,Name) VALUES (1, 'A74'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A21'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A23'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A24'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A28'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A31'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A310'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A311'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A32'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A41'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A415'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A416'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A418'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A42'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A421'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A43'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A45'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A46'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A48'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (1, 'A74'); /* INSERT INTO Manufacturers VALUES (2, 'Amcrest'); +*/ +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (2, 'IP8M-T2499EW'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (2, 'ASH42-B'); +/* INSERT INTO Manufacturers VALUES (3, 'Airlink101'); INSERT INTO Manufacturers VALUES (4, 'Arecont Vision'); INSERT INTO Manufacturers VALUES (5, 'Axis'); INSERT INTO Manufacturers VALUES (6, 'Dahua'); INSERT INTO Manufacturers VALUES (7, 'D-Link'); +*/ +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (7, 'DCS-930L'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (7, 'DCS-932L'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (7, 'DCS-933L'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (7, 'DCS-942L'); +INSERT IGNORE INTO Models (ManufacturerId,Name) VALUES (7, 'DCS-5020L'); +/* INSERT INTO Manufacturers VALUES (8, 'Edimax'); INSERT INTO Manufacturers VALUES (9, 'Foscam'); INSERT INTO Manufacturers VALUES (10, 'Gadspot'); From 6cbc4c0a7af6d1e977997283a4f7e214842966be Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 15 Nov 2021 16:30:39 -0500 Subject: [PATCH 127/174] Update MonirorPresets to link to Amcrest cams --- db/zm_update-1.37.3.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/db/zm_update-1.37.3.sql b/db/zm_update-1.37.3.sql index 9002ce8e2..5ae4aa1b1 100644 --- a/db/zm_update-1.37.3.sql +++ b/db/zm_update-1.37.3.sql @@ -68,3 +68,6 @@ SET @s = (SELECT IF( PREPARE stmt FROM @s; EXECUTE stmt; + +UPDATE `MonitorPresets` SET `ModelId`=(SELECT `Id` FROM `Models` WHERE `Name`='IP8M-T2499EW') WHERE `Name` like 'Amcrest, IP8M-T2499EW +%'; From f48511acba1dd033feeab533d502dcc4aadbf45f Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 16 Nov 2021 09:19:42 -0500 Subject: [PATCH 128/174] Add NULL for ModelId column when adding MonitorPresets. --- db/zm_create.sql.in | 150 ++++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 9a048886d..d9d4f96c3 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -974,81 +974,81 @@ INSERT INTO `Controls` VALUES (NULL,'Amcrest HTTP API','Ffmpeg','Amcrest_HTTP',0 -- Add some monitor preset values -- -INSERT into MonitorPresets VALUES (NULL,'Amcrest, IP8M-T2499EW 640x480, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp','NULL',554,'rtsp://:@/cam/realmonitor?channel=1&subtype=1',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT into MonitorPresets VALUES (NULL,'Amcrest, IP8M-T2499EW 3840x2160, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp','NULL',554,'rtsp://:@/cam/realmonitor?channel=1&subtype=0',NULL,3840,2160,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, B&W','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&color=0',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, B&W','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&color=0',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,1,4,NULL,':',100,100); -INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, unicast','Remote','rtsp',0,255,'rtsp','rtpUni','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, multicast','Remote','rtsp',0,255,'rtsp','rtpMulti','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp',0,255,'rtsp','rtpRtsp','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'D-link DCS-930L, 640x480, mjpeg','Remote','http',0,0,'http','simple','',80,'/mjpeg.cgi',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'D-Link DCS-5020L, 640x480, mjpeg','Remote','http',0,0,'http','simple',':@','80','/video.cgi',NULL,640,480,0,NULL,1,'34',NULL,':@',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http',0,0,'http','simple','',80,'/GetData.cgi',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'IP Webcam by Pavel Khlebovich 1920x1080','Remote','/dev/video','0',255,'http','simple','','8080','/video','',1920,1080,0,NULL,0,'0','','',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'VEO Observer, jpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Blue Net Video Server, jpeg','Remote','http',0,0,'http','simple','',80,'/cgi-bin/image.cgi?control=0&id=admin&passwd=admin',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT into MonitorPresets VALUES (NULL,'ACTi IP, mpeg4, unicast','Remote',NULL,NULL,NULL,'rtsp','rtpUni','',7070,'','/track',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp:///axis-media/media.amp?videocodec=h264',NULL,NULL,NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Vivotek FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://:554/live.sdp',NULL,NULL,NULL,352,240,NULL,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp:///axis-media/media.amp',NULL,NULL,NULL,640,480,NULL,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'ACTi TCM FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://admin:123456@:7070',NULL,NULL,NULL,320,240,NULL,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240, max 5 FPS','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480, max 5 FPS','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240, max 5 FPS','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480, max 5 FPS','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240, max 5 FPS','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480, max 5 FPS','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240, max 5 FPS','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480, max 5 FPS','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Remote ZoneMinder','Remote',NULL,NULL,NULL,'http','simple','',80,'/cgi-bin/nph-zms?mode=jpeg&monitor=&scale=100&maxfps=5&buffer=0',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI8620 FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://:@:554/11',NULL,704,576,0,NULL,1,'10','','',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI8608W FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://:@:554/11',NULL,640,480,0,NULL,1,'11','','',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI9821W FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://:@:88/videoMain',NULL,1280,720,0,NULL,1,'12','','',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Loftek Sentinel PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,'','80','/videostream.cgi?user=&pwd=&resolution=32&rate=11',NULL,640,480,4,NULL,1,'13','',':@',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Airlink 777W PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,':@','80','/cgi/mjpg/mjpg.cgi',NULL,640,480,4,NULL,1,'7','',':@',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','/dev/video','0',255,'','rtpMulti','','80','rtsp://:554/11','',1920,1080,0,0.00,1,'16','-speed=64',':',100,33); -INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1280x720, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp',NULL,554,'rtsp:///tcp_live/ch0_0',NULL,1280,720,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1920x1080, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp',NULL,554,'rtsp:///tcp_live/ch0_0',NULL,1920,1080,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,NULL,'Amcrest, IP8M-T2499EW 640x480, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp','NULL',554,'rtsp://:@/cam/realmonitor?channel=1&subtype=1',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,NULL,'Amcrest, IP8M-T2499EW 3840x2160, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp','NULL',554,'rtsp://:@/cam/realmonitor?channel=1&subtype=0',NULL,3840,2160,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 320x240, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 320x240, mpjpeg, B&W','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&color=0',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP, 640x480, mpjpeg, B&W','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&color=0',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP PTZ, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP PTZ, 320x240, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP PTZ, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP PTZ, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP PTZ, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,1,4,NULL,':',100,100); +INSERT into MonitorPresets VALUES (NULL,NULL,'Axis IP, mpeg4, unicast','Remote','rtsp',0,255,'rtsp','rtpUni','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,NULL,'Axis IP, mpeg4, multicast','Remote','rtsp',0,255,'rtsp','rtpMulti','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp',0,255,'rtsp','rtpRtsp','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'D-link DCS-930L, 640x480, mjpeg','Remote','http',0,0,'http','simple','',80,'/mjpeg.cgi',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'D-Link DCS-5020L, 640x480, mjpeg','Remote','http',0,0,'http','simple',':@','80','/video.cgi',NULL,640,480,0,NULL,1,'34',NULL,':@',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP PTZ, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP PTZ, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP PTZ, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Panasonic IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Gadspot IP, jpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Gadspot IP, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Gadspot IP, mpjpeg','Remote','http',0,0,'http','simple','',80,'/GetData.cgi',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Gadspot IP, mpjpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'IP Webcam by Pavel Khlebovich 1920x1080','Remote','/dev/video','0',255,'http','simple','','8080','/video','',1920,1080,0,NULL,0,'0','','',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'VEO Observer, jpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Blue Net Video Server, jpeg','Remote','http',0,0,'http','simple','',80,'/cgi-bin/image.cgi?control=0&id=admin&passwd=admin',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,NULL,'ACTi IP, mpeg4, unicast','Remote',NULL,NULL,NULL,'rtsp','rtpUni','',7070,'','/track',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp:///axis-media/media.amp?videocodec=h264',NULL,NULL,NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Vivotek FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://:554/live.sdp',NULL,NULL,NULL,352,240,NULL,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Axis FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp:///axis-media/media.amp',NULL,NULL,NULL,640,480,NULL,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'ACTi TCM FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://admin:123456@:7070',NULL,NULL,NULL,320,240,NULL,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L2), PAL, 320x240','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L2), PAL, 320x240, max 5 FPS','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L2), PAL, 640x480','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L2), PAL, 640x480, max 5 FPS','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L2), NTSC, 320x240','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L2), NTSC, 320x240, max 5 FPS','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L2), NTSC, 640x480','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L2), NTSC, 640x480, max 5 FPS','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L1), PAL, 320x240','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L1), PAL, 320x240, max 5 FPS','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L1), PAL, 640x480','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L1), PAL, 640x480, max 5 FPS','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L1), NTSC, 320x240','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L1), NTSC, 320x240, max 5 FPS','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L1), NTSC, 640x480','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'BTTV Video (V4L1), NTSC, 640x480, max 5 FPS','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Remote ZoneMinder','Remote',NULL,NULL,NULL,'http','simple','',80,'/cgi-bin/nph-zms?mode=jpeg&monitor=&scale=100&maxfps=5&buffer=0',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Foscam FI8620 FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://:@:554/11',NULL,704,576,0,NULL,1,'10','','',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Foscam FI8608W FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://:@:554/11',NULL,640,480,0,NULL,1,'11','','',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Foscam FI9821W FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://:@:88/videoMain',NULL,1280,720,0,NULL,1,'12','','',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Loftek Sentinel PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,'','80','/videostream.cgi?user=&pwd=&resolution=32&rate=11',NULL,640,480,4,NULL,1,'13','',':@',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Airlink 777W PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,':@','80','/cgi/mjpg/mjpg.cgi',NULL,640,480,4,NULL,1,'7','',':@',100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'SunEyes SP-P1802SWPTZ','Libvlc','/dev/video','0',255,'','rtpMulti','','80','rtsp://:554/11','',1920,1080,0,0.00,1,'16','-speed=64',':',100,33); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Qihan IP, 1280x720, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp',NULL,554,'rtsp:///tcp_live/ch0_0',NULL,1280,720,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,NULL,'Qihan IP, 1920x1080, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp',NULL,554,'rtsp:///tcp_live/ch0_0',NULL,1920,1080,3,NULL,0,NULL,NULL,NULL,100,100); -- -- Add some zone preset values From 20629fdf5a77505708842f2f910822799102e641 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 16 Nov 2021 09:20:14 -0500 Subject: [PATCH 129/174] Include Manufacturer and Model in telemetry --- scripts/zmtelemetry.pl.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/zmtelemetry.pl.in b/scripts/zmtelemetry.pl.in index a3debabdb..c164df7e4 100644 --- a/scripts/zmtelemetry.pl.in +++ b/scripts/zmtelemetry.pl.in @@ -263,7 +263,10 @@ sub countQuery { sub getMonitorRef { my $dbh = shift; - my $sql = 'SELECT `Id`,`Name`,`Type`,`Function`,`Width`,`Height`,`Colours`,`MaxFPS`,`AlarmMaxFPS` FROM `Monitors`'; + my $sql = 'SELECT `Id`,`Name`,`Type`,`Function`,`Width`,`Height`,`Colours`,`MaxFPS`,`AlarmMaxFPS`, + (SELECT Name FROM Manufacturers WHERE Manufacturers.Id = ManufacturerId), + (SELECT Name FROM Models WHERE Models.Id = ModelId) + FROM `Monitors`'; my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); my $arrayref = $sth->fetchall_arrayref({}); From 78a803abf87bd724dcaa69de4401b561a847b8a5 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 16 Nov 2021 09:47:34 -0500 Subject: [PATCH 130/174] Add Model and Manufacturer to telemetry listing --- web/lang/en_gb.php | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index 8b412cd39..8c6ce9adb 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -663,8 +663,33 @@ $SLANG = array( 'PrivacyCookiesText' => 'Whether you use a web browser or a mobile app to communicate with the ZoneMinder server, a ZMSESSID cookie is created on the client to uniquely identify a session with the ZoneMinder server. ZmCSS and zmSkin cookies are created to remember your style and skin choices.', 'PrivacyTelemetry' => 'Telemetry', 'PrivacyTelemetryText' => 'Because ZoneMinder is open-source, anyone can install it without registering. This makes it difficult to answer questions such as: how many systems are out there, what is the largest system out there, what kind of systems are out there, or where are these systems located? Knowing the answers to these questions, helps users who ask us these questions, and it helps us set priorities based on the majority user base.', - 'PrivacyTelemetryList' => 'The ZoneMinder Telemetry daemon collects the following data about your system:
  • A unique identifier (UUID)
  • City based location is gathered by querying ipinfo.io. City, region, country, latitude, and longitude parameters are saved. The latitude and longitude coordinates are accurate down to the city or town level only!
  • Current time
  • Total number of monitors
  • Total number of events
  • System architecture
  • Operating system kernel, distro, and distro version
  • Version of ZoneMinder
  • Total amount of memory
  • Number of cpu cores
', - 'PrivacyMonitorList' => 'The following configuration parameters from each monitor are collected:
  • Id
  • Name
  • Type
  • Function
  • Width
  • Height
  • Colours
  • MaxFPS
  • AlarmMaxFPS
', + 'PrivacyTelemetryList' => 'The ZoneMinder Telemetry daemon collects the following data about your system: +
    +
  • A unique identifier (UUID)
  • +
  • City based location is gathered by querying ipinfo.io. City, region, country, latitude, and longitude parameters are saved. The latitude and longitude coordinates are accurate down to the city or town level only!
  • +
  • Current time
  • +
  • Total number of monitors
  • +
  • Total number of events
  • +
  • System architecture
  • +
  • Operating system kernel, distro, and distro version
  • +
  • Version of ZoneMinder
  • +
  • Total amount of memory
  • +
  • Number of cpu cores
  • +
', + 'PrivacyMonitorList' => 'The following configuration parameters from each monitor are collected: +
    +
  • Id
  • +
  • Name
  • +
  • Manufacturer
  • +
  • Model
  • +
  • Type
  • +
  • Function
  • +
  • Width
  • +
  • Height
  • +
  • Colours
  • +
  • MaxFPS
  • +
  • AlarmMaxFPS
  • +
', 'PrivacyConclusionText' => 'We are NOT collecting any image specific data from your cameras. We don’t know what your cameras are watching. This data will not be sold or used for any purpose not stated herein. By clicking accept, you agree to send us this data to help make ZoneMinder a better product. By clicking decline, you can still freely use ZoneMinder and all its features.', 'Probe' => 'Probe', 'ProfileProbe' => 'Stream Probe', From 03897bf68e10a0c2a47172947dbeb45d3bd4cc3d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 16 Nov 2021 09:49:49 -0500 Subject: [PATCH 131/174] Add privacy to options tabs so we can get back to it. --- web/skins/classic/views/options.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/options.php b/web/skins/classic/views/options.php index 22b164202..25cad40cc 100644 --- a/web/skins/classic/views/options.php +++ b/web/skins/classic/views/options.php @@ -44,8 +44,9 @@ $tabs['medband'] = translate('MediumBW'); $tabs['lowband'] = translate('LowBW'); $tabs['users'] = translate('Users'); $tabs['control'] = translate('Control'); +$tabs['privacy'] = translate('Privacy'); -if ( isset($_REQUEST['tab']) ) +if (isset($_REQUEST['tab'])) $tab = validHtmlStr($_REQUEST['tab']); else $tab = 'system'; @@ -53,7 +54,6 @@ else $focusWindow = true; xhtmlHeaders(__FILE__, translate('Options')); - ?> @@ -62,7 +62,7 @@ xhtmlHeaders(__FILE__, translate('Options'));