Merge branch 'master' of github.com:ZoneMinder/zoneminder
This commit is contained in:
commit
cfcc39defb
|
@ -283,6 +283,7 @@ CREATE TABLE `Filters` (
|
|||
`Id` int(10) unsigned NOT NULL auto_increment,
|
||||
`Name` varchar(64) NOT NULL default '',
|
||||
`UserId` int(10) unsigned,
|
||||
`ExecuteInterval` int(10) unsigned NOT NULL default '60',
|
||||
`Query_json` text NOT NULL,
|
||||
`AutoArchive` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoUnarchive` tinyint(3) unsigned NOT NULL default '0',
|
||||
|
|
|
@ -56,7 +56,7 @@ EXECUTE stmt;
|
|||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||
AND table_name = 'Monitor_Status'
|
||||
AND column_name = 'DayEvents'
|
||||
AND column_name = 'DayEventDiskSpace'
|
||||
) > 0,
|
||||
"ALTER TABLE `Monitor_Status` DROP `DayEventDiskSpace`",
|
||||
"SELECT 'Column DayEventDiskSpace already removed from Monitor_Status'"
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
--
|
||||
-- Update Filters table to have a ExecuteInterval Column
|
||||
--
|
||||
|
||||
SELECT 'Checking for ExecuteInterval in Filters';
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Filters'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'ExecuteInterval'
|
||||
) > 0,
|
||||
"SELECT 'Column ExecuteInterval already exists in Filters'",
|
||||
"ALTER TABLE Filters ADD COLUMN `ExecuteInterval` int(10) unsigned NOT NULL default '60' AFTER `UserId`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
|
@ -36,7 +36,7 @@
|
|||
%global _hardened_build 1
|
||||
|
||||
Name: zoneminder
|
||||
Version: 1.37.5
|
||||
Version: 1.37.6
|
||||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
|
|
|
@ -56,6 +56,7 @@ $primary_key = 'Id';
|
|||
%fields = map { $_ => $_ } qw(
|
||||
Id
|
||||
Name
|
||||
ExecuteInterval
|
||||
Query_json
|
||||
AutoArchive
|
||||
AutoUnarchive
|
||||
|
@ -106,7 +107,6 @@ sub Execute {
|
|||
$sql =~ s/zmSystemLoad/$load/g;
|
||||
}
|
||||
|
||||
$sql .= ' FOR UPDATE' if $$self{LockRows};
|
||||
|
||||
Debug("Filter::Execute SQL ($sql)");
|
||||
my $sth = $ZoneMinder::Database::dbh->prepare_cached($sql)
|
||||
|
@ -371,10 +371,7 @@ sub Sql {
|
|||
if ( @auto_terms ) {
|
||||
$sql .= ' AND ( '.join(' or ', @auto_terms).' )';
|
||||
}
|
||||
if ( !$filter_expr->{sort_field} ) {
|
||||
$filter_expr->{sort_field} = 'StartDateTime';
|
||||
$filter_expr->{sort_asc} = 0;
|
||||
}
|
||||
|
||||
my $sort_column = '';
|
||||
if ( $filter_expr->{sort_field} eq 'Id' ) {
|
||||
$sort_column = 'E.Id';
|
||||
|
@ -406,14 +403,23 @@ sub Sql {
|
|||
$sort_column = 'E.MaxScore';
|
||||
} elsif ( $filter_expr->{sort_field} eq 'DiskSpace' ) {
|
||||
$sort_column = 'E.DiskSpace';
|
||||
} else {
|
||||
$sort_column = 'E.StartDateTime';
|
||||
} elsif ( $filter_expr->{sort_field} ne '' ) {
|
||||
$sort_column = 'E.'.$filter_expr->{sort_field};
|
||||
}
|
||||
my $sort_order = $filter_expr->{sort_asc} ? 'ASC' : 'DESC';
|
||||
$sql .= ' ORDER BY '.$sort_column.' '.$sort_order;
|
||||
if ( $filter_expr->{limit} ) {
|
||||
if ( $sort_column ne '' ) {
|
||||
$sql .= ' ORDER BY '.$sort_column.' '.($filter_expr->{sort_asc} ? 'ASC' : 'DESC');
|
||||
}
|
||||
if ($filter_expr->{limit}) {
|
||||
$sql .= ' LIMIT 0,'.$filter_expr->{limit};
|
||||
}
|
||||
if ($$self{LockRows}) {
|
||||
$sql .= ' FOR UPDATE OF E'
|
||||
} else {
|
||||
$sql .= ' FOR SHARE OF E'
|
||||
}
|
||||
if ($filter_expr->{skip_locked}) {
|
||||
$sql .= ' SKIP LOCKED';
|
||||
}
|
||||
$self->{Sql} = $sql;
|
||||
} # end if has Sql
|
||||
return $self->{Sql};
|
||||
|
|
|
@ -42,6 +42,7 @@ our @ISA = qw(Exporter ZoneMinder::Base);
|
|||
# will save memory.
|
||||
our %EXPORT_TAGS = (
|
||||
constants => [ qw(
|
||||
STATE_UNKNOWN
|
||||
STATE_IDLE
|
||||
STATE_PREALARM
|
||||
STATE_ALARM
|
||||
|
@ -98,11 +99,12 @@ our $VERSION = $ZoneMinder::Base::VERSION;
|
|||
use ZoneMinder::Config qw(:all);
|
||||
use ZoneMinder::Logger qw(:all);
|
||||
|
||||
use constant STATE_IDLE => 0;
|
||||
use constant STATE_PREALARM => 1;
|
||||
use constant STATE_ALARM => 2;
|
||||
use constant STATE_ALERT => 3;
|
||||
use constant STATE_TAPE => 4;
|
||||
use constant STATE_UNKNOWN => 0;
|
||||
use constant STATE_IDLE => 1;
|
||||
use constant STATE_PREALARM => 2;
|
||||
use constant STATE_ALARM => 3;
|
||||
use constant STATE_ALERT => 4;
|
||||
use constant STATE_TAPE => 5;
|
||||
|
||||
use constant ACTION_GET => 1;
|
||||
use constant ACTION_SET => 2;
|
||||
|
|
|
@ -138,7 +138,6 @@ $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
|
|||
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
|
||||
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
|
||||
|
||||
my $delay = $Config{ZM_FILTER_EXECUTE_INTERVAL};
|
||||
my $event_id = 0;
|
||||
|
||||
if (!EVENT_PATH) {
|
||||
|
@ -174,6 +173,7 @@ my @filters;
|
|||
my $last_action = 0;
|
||||
|
||||
while (!$zm_terminate) {
|
||||
my $delay = $Config{ZM_FILTER_EXECUTE_INTERVAL};
|
||||
my $now = time;
|
||||
if (($now - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY}) {
|
||||
Debug('Reloading filters');
|
||||
|
@ -183,6 +183,15 @@ while (!$zm_terminate) {
|
|||
|
||||
foreach my $filter (@filters) {
|
||||
last if $zm_terminate;
|
||||
|
||||
my $elapsed = ($now - $$filter{last_ran});
|
||||
if ($$filter{last_ran} and ($elapsed < $$filter{ExecuteInterval})) {
|
||||
my $filter_delay = $$filter{ExecuteInterval} - ($now - $$filter{last_ran});
|
||||
$delay = $filter_delay if $filter_delay < $delay;
|
||||
Debug("Setting delay to $delay because ExecuteInterval=$$filter{ExecuteInterval} and $elapsed have elapsed");
|
||||
next;
|
||||
}
|
||||
|
||||
if ($$filter{Concurrent} and !($filter_id or $filter_name)) {
|
||||
my ( $proc ) = $0 =~ /(\S+)/;
|
||||
my ( $id ) = $$filter{Id} =~ /(\d+)/;
|
||||
|
@ -191,8 +200,9 @@ while (!$zm_terminate) {
|
|||
system(qq`$proc --filter_id $id &`);
|
||||
} else {
|
||||
checkFilter($filter);
|
||||
$$filter{last_ran} = $now;
|
||||
}
|
||||
}
|
||||
} # end foreach filter
|
||||
|
||||
last if (!$daemon and ($filter_name or $filter_id)) or $zm_terminate;
|
||||
|
||||
|
@ -362,11 +372,6 @@ sub checkFilter {
|
|||
} # end if AutoCopy
|
||||
|
||||
if ( $filter->{UpdateDiskSpace} ) {
|
||||
if ( $$filter{LockRows} ) {
|
||||
$ZoneMinder::Database::dbh->begin_work();
|
||||
$Event->lock_and_load();
|
||||
}
|
||||
|
||||
my $old_diskspace = $$Event{DiskSpace};
|
||||
my $new_diskspace = $Event->DiskSpace(undef);
|
||||
|
||||
|
|
|
@ -166,13 +166,9 @@ while (!$zm_terminate) {
|
|||
foreach my $connection ( values(%spawned_connections) ) {
|
||||
if ( vec($rout, $connection->fileno(), 1) ) {
|
||||
Debug('Got input from spawned connection '
|
||||
.$connection->name()
|
||||
.' ('
|
||||
.$connection->fileno()
|
||||
.')'
|
||||
);
|
||||
.$connection->name().' ('.$connection->fileno().')');
|
||||
my $messages = $connection->getMessages();
|
||||
if ( defined($messages) ) {
|
||||
if (defined($messages)) {
|
||||
foreach my $message ( @$messages ) {
|
||||
handleMessage($connection, $message);
|
||||
}
|
||||
|
@ -199,34 +195,32 @@ while (!$zm_terminate) {
|
|||
# Check polled connections
|
||||
foreach my $connection ( @in_poll_connections ) {
|
||||
my $messages = $connection->getMessages();
|
||||
if ( defined($messages) ) {
|
||||
foreach my $message ( @$messages ) {
|
||||
handleMessage($connection, $message);
|
||||
}
|
||||
if (defined($messages)) {
|
||||
foreach my $message (@$messages) { handleMessage($connection, $message) };
|
||||
}
|
||||
}
|
||||
|
||||
# Check for alarms that might have happened
|
||||
my @out_messages;
|
||||
foreach my $monitor ( values %monitors ) {
|
||||
if ($$monitor{Function} eq 'None') {
|
||||
$monitor_reload_time = 0;
|
||||
next;
|
||||
}
|
||||
|
||||
if ( ! zmMemVerify($monitor) ) {
|
||||
if (!zmMemVerify($monitor)) {
|
||||
# Our attempt to verify the memory handle failed. We should reload the monitors.
|
||||
# Don't need to zmMemInvalidate because the monitor reload will do it.
|
||||
push @needsReload, $monitor;
|
||||
next;
|
||||
}
|
||||
|
||||
my ( $state, $last_event ) = zmMemRead( $monitor,
|
||||
[
|
||||
my ($state, $last_event) = zmMemRead($monitor, [
|
||||
'shared_data:state',
|
||||
'shared_data:last_event'
|
||||
]
|
||||
);
|
||||
]);
|
||||
|
||||
#print( "$monitor->{Id}: S:$state, LE:$last_event" );
|
||||
#print( "$monitor->{Id}: mS:$monitor->{LastState}, mLE:$monitor->{LastEvent}" );
|
||||
if ( $state == STATE_ALARM or $state == STATE_ALERT ) {
|
||||
if ($state == STATE_ALARM or $state == STATE_ALERT) {
|
||||
# In alarm state
|
||||
if ( !defined($monitor->{LastEvent})
|
||||
or ($last_event != $monitor->{LastEvent})
|
||||
|
|
|
@ -65,7 +65,7 @@ unsigned int Buffer::expand(unsigned int count) {
|
|||
int Buffer::read_into(int sd, unsigned int bytes) {
|
||||
// Make sure there is enough space
|
||||
this->expand(bytes);
|
||||
Debug(3, "Reading %u btes", bytes);
|
||||
Debug(3, "Reading %u bytes", bytes);
|
||||
int bytes_read = ::read(sd, mTail, bytes);
|
||||
if (bytes_read > 0) {
|
||||
mTail += bytes_read;
|
||||
|
|
45
src/zm_rgb.h
45
src/zm_rgb.h
|
@ -118,39 +118,32 @@ constexpr Rgb kRGBTransparent = 0x01000000;
|
|||
|
||||
/* Convert RGB colour value into BGR\ARGB\ABGR */
|
||||
inline Rgb rgb_convert(Rgb p_col, int p_subpixorder) {
|
||||
Rgb result;
|
||||
|
||||
switch(p_subpixorder) {
|
||||
Rgb result = 0;
|
||||
|
||||
switch (p_subpixorder) {
|
||||
case ZM_SUBPIX_ORDER_BGR:
|
||||
case ZM_SUBPIX_ORDER_BGRA:
|
||||
{
|
||||
BLUE_PTR_BGRA(&result) = BLUE_VAL_RGBA(p_col);
|
||||
GREEN_PTR_BGRA(&result) = GREEN_VAL_RGBA(p_col);
|
||||
RED_PTR_BGRA(&result) = RED_VAL_RGBA(p_col);
|
||||
}
|
||||
break;
|
||||
BLUE_PTR_BGRA(&result) = BLUE_VAL_RGBA(p_col);
|
||||
GREEN_PTR_BGRA(&result) = GREEN_VAL_RGBA(p_col);
|
||||
RED_PTR_BGRA(&result) = RED_VAL_RGBA(p_col);
|
||||
break;
|
||||
case ZM_SUBPIX_ORDER_ARGB:
|
||||
{
|
||||
BLUE_PTR_ARGB(&result) = BLUE_VAL_RGBA(p_col);
|
||||
GREEN_PTR_ARGB(&result) = GREEN_VAL_RGBA(p_col);
|
||||
RED_PTR_ARGB(&result) = RED_VAL_RGBA(p_col);
|
||||
}
|
||||
break;
|
||||
BLUE_PTR_ARGB(&result) = BLUE_VAL_RGBA(p_col);
|
||||
GREEN_PTR_ARGB(&result) = GREEN_VAL_RGBA(p_col);
|
||||
RED_PTR_ARGB(&result) = RED_VAL_RGBA(p_col);
|
||||
break;
|
||||
case ZM_SUBPIX_ORDER_ABGR:
|
||||
{
|
||||
BLUE_PTR_ABGR(&result) = BLUE_VAL_RGBA(p_col);
|
||||
GREEN_PTR_ABGR(&result) = GREEN_VAL_RGBA(p_col);
|
||||
RED_PTR_ABGR(&result) = RED_VAL_RGBA(p_col);
|
||||
}
|
||||
break;
|
||||
/* Grayscale */
|
||||
BLUE_PTR_ABGR(&result) = BLUE_VAL_RGBA(p_col);
|
||||
GREEN_PTR_ABGR(&result) = GREEN_VAL_RGBA(p_col);
|
||||
RED_PTR_ABGR(&result) = RED_VAL_RGBA(p_col);
|
||||
break;
|
||||
/* Grayscale */
|
||||
case ZM_SUBPIX_ORDER_NONE:
|
||||
result = p_col & 0xff;
|
||||
break;
|
||||
result = p_col & 0xff;
|
||||
break;
|
||||
default:
|
||||
return p_col;
|
||||
break;
|
||||
result = p_col;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -365,6 +365,7 @@ int main(int argc, char *argv[]) {
|
|||
monitor->Id());
|
||||
zmDbDo(sql);
|
||||
}
|
||||
monitors.clear();
|
||||
|
||||
Image::Deinitialise();
|
||||
Debug(1, "terminating");
|
||||
|
|
|
@ -218,8 +218,8 @@ rm .gitignore
|
|||
cd ../
|
||||
|
||||
|
||||
if [ ! -e "$DIRECTORY.orig.tar.gz" ]; then
|
||||
read -p "$DIRECTORY.orig.tar.gz does not exist, create it? [Y/n]"
|
||||
if [ -e "$DIRECTORY.orig.tar.gz" ]; then
|
||||
read -p "$DIRECTORY.orig.tar.gz exists, overwrite it? [Y/n]"
|
||||
if [[ "$REPLY" == "" || "$REPLY" == [yY] ]]; then
|
||||
tar zcf $DIRECTORY.orig.tar.gz $DIRECTORY.orig
|
||||
fi;
|
||||
|
|
|
@ -48,7 +48,7 @@ if (isset($_REQUEST['order'])) {
|
|||
} else if (strtolower($_REQUEST['order']) == 'desc') {
|
||||
$order = 'DESC';
|
||||
} else {
|
||||
Warning("Invalid value for order " . $_REQUEST['order']);
|
||||
Warning('Invalid value for order ' . $_REQUEST['order']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,18 +170,23 @@ 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))) {
|
||||
ZM\Error('Invalid sort field: ' . $sort);
|
||||
$sort = 'Id';
|
||||
if ( $sort != '' ) {
|
||||
if (!in_array($sort, array_merge($columns, $col_alt))) {
|
||||
ZM\Error('Invalid sort field: ' . $sort);
|
||||
$sort = '';
|
||||
} else if ( $sort == 'Monitor' ) {
|
||||
$sort = 'M.Name';
|
||||
} else {
|
||||
$sort = 'E.'.$sort;
|
||||
}
|
||||
}
|
||||
|
||||
$values = array();
|
||||
$likes = array();
|
||||
$where = $filter->sql()?' WHERE ('.$filter->sql().')' : '';
|
||||
|
||||
$sort = $sort == 'Monitor' ? 'M.Name' : 'E.'.$sort;
|
||||
$col_str = 'E.*, M.Name AS Monitor';
|
||||
$sql = 'SELECT ' .$col_str. ' FROM `Events` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY '.$sort.' '.$order;
|
||||
$sql = 'SELECT ' .$col_str. ' FROM `Events` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.($sort?' ORDER BY '.$sort.' '.$order:'');
|
||||
|
||||
$storage_areas = ZM\Storage::find();
|
||||
$StorageById = array();
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<?php
|
||||
//require_once('includes/Filter.php');
|
||||
require_once('includes/Filter.php');
|
||||
$fid = validInt($_REQUEST['fid']);
|
||||
if ( !$fid ) {
|
||||
if (!$fid) {
|
||||
echo '<div class="error">No filter id specified.</div>';
|
||||
} else {
|
||||
$filter = new ZM\Filter($_REQUEST['fid']);
|
||||
if ( ! $filter->Id() ) {
|
||||
if (!$filter->Id()) {
|
||||
echo '<div class="error">Filter not found for id '.$_REQUEST['fid'].'</div>';
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,16 @@
|
|||
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
|
||||
echo getCSRFinputHTML();
|
||||
?>
|
||||
<p><label>SQL</label><?php echo $filter->sql() ?></p>
|
||||
<p><label>SQL</label>
|
||||
<?php
|
||||
$sql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale<br/>FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId)<br/>WHERE<br/>';
|
||||
$sql .= $filter->sql();
|
||||
$sql .= $filter->sort_field() ? ' ORDER BY '.$filter->sort_field(). ' ' .($filter->sort_asc() ? 'ASC' : 'DESC') : '';
|
||||
$sql .= $filter->limit() ? ' LIMIT '.$filter->limit() : '';
|
||||
$sql .= $filter->skip_locked() ? ' SKIP LOCKED' : '';
|
||||
|
||||
echo $sql;
|
||||
?></p>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel')?> </button>
|
||||
</div>
|
||||
|
|
|
@ -321,12 +321,20 @@ class MonitorsController extends AppController {
|
|||
}
|
||||
|
||||
$monitor = $this->Monitor->find('first', array(
|
||||
'fields' => array('Id', 'Type', 'Device'),
|
||||
'fields' => array('Id', 'Type', 'Device', 'Function'),
|
||||
'conditions' => array('Id' => $id)
|
||||
));
|
||||
|
||||
// Clean up the returned array
|
||||
$monitor = Set::extract('/Monitor/.', $monitor);
|
||||
if ($monitor[0]['Function'] == 'None') {
|
||||
$this->set(array(
|
||||
'status' => false,
|
||||
'statustext' => 'Monitor function is set to None',
|
||||
'_serialize' => array('status','statustext'),
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass -d for local, otherwise -m
|
||||
if ( $monitor[0]['Type'] == 'Local' ) {
|
||||
|
|
|
@ -9,6 +9,8 @@ class Filter extends ZM_Object {
|
|||
protected $defaults = array(
|
||||
'Id' => null,
|
||||
'Name' => '',
|
||||
'UserId' => 0,
|
||||
'ExecuteInterval' => 60,
|
||||
'AutoExecute' => 0,
|
||||
'AutoExecuteCmd' => '',
|
||||
'AutoEmail' => 0,
|
||||
|
@ -26,7 +28,6 @@ class Filter extends ZM_Object {
|
|||
'AutoCopy' => 0,
|
||||
'AutoCopyTo' => 0,
|
||||
'UpdateDiskSpace' => 0,
|
||||
'UserId' => 0,
|
||||
'Background' => 0,
|
||||
'Concurrent' => 0,
|
||||
'Query_json' => '',
|
||||
|
@ -62,6 +63,7 @@ class Filter extends ZM_Object {
|
|||
} # end foreach term
|
||||
$this->_querystring .= $separator.urlencode($objectname.'[Query][sort_asc]').'='.$this->sort_asc();
|
||||
$this->_querystring .= $separator.urlencode($objectname.'[Query][sort_field]').'='.$this->sort_field();
|
||||
$this->_querystring .= $separator.urlencode($objectname.'[Query][skip_locked]').'='.$this->skip_locked();
|
||||
$this->_querystring .= $separator.urlencode($objectname.'[Query][limit]').'='.$this->limit();
|
||||
if ( $this->Id() ) {
|
||||
$this->_querystring .= $separator.$objectname.urlencode('[Id]').'='.$this->Id();
|
||||
|
@ -207,18 +209,29 @@ class Filter extends ZM_Object {
|
|||
}
|
||||
|
||||
public function sort_asc( ) {
|
||||
if ( func_num_args( ) ) {
|
||||
if (func_num_args()) {
|
||||
$Query = $this->Query();
|
||||
$Query['sort_asc'] = func_get_arg(0);
|
||||
$this->Query($Query);
|
||||
}
|
||||
if ( isset( $this->Query()['sort_asc'] ) ) {
|
||||
if (isset($this->Query()['sort_asc'])) {
|
||||
return $this->{'Query'}['sort_asc'];
|
||||
}
|
||||
return ZM_WEB_EVENT_SORT_ORDER == 'asc' ? 1 : 0;
|
||||
#return $this->defaults{'sort_asc'};
|
||||
}
|
||||
|
||||
public function skip_locked() {
|
||||
if (func_num_args()) {
|
||||
$Query = $this->Query();
|
||||
$Query['skip_locked'] = func_get_arg(0);
|
||||
$this->Query($Query);
|
||||
}
|
||||
if (isset($this->Query()['skip_locked']))
|
||||
return $this->{'Query'}['skip_locked'];
|
||||
return false;
|
||||
}
|
||||
|
||||
public function limit( ) {
|
||||
if ( func_num_args( ) ) {
|
||||
$Query = $this->Query();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
#menuControls {
|
||||
|
@ -19,19 +21,22 @@
|
|||
#monitorStatus {
|
||||
margin: 4px auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#monitorStatus #enableDisableAlarms {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#monitorStatus #forceCancelAlarm {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#monitorStatus #monitorState {
|
||||
}
|
||||
|
||||
#replayStatus {
|
||||
margin: 3px 0 2px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#replayStatus > span {
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
#dvrControls {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 2px;
|
||||
|
@ -67,15 +72,6 @@
|
|||
cursor: default;
|
||||
}
|
||||
|
||||
#replayStatus {
|
||||
margin: 3px 0 2px;
|
||||
text-align: center;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#replayStatus > span {
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
#events {
|
||||
margin: 0 auto;
|
||||
|
@ -116,3 +112,22 @@ span.alert {
|
|||
background-color: #DCDCDC;
|
||||
}
|
||||
|
||||
.controlHeader {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#viewingFPS,
|
||||
#captureFPS,
|
||||
#analysisFPS
|
||||
{
|
||||
display: inline-block;
|
||||
}
|
||||
#stateValue,
|
||||
#viewingFPSValue,
|
||||
#captureFPSValue,
|
||||
#analysisFPSValue
|
||||
{
|
||||
display: inline-block;
|
||||
min-width: 40px;
|
||||
text-align: right;
|
||||
}
|
||||
|
|
|
@ -367,6 +367,7 @@ for ( $i=0; $i < count($terms); $i++ ) {
|
|||
<?php
|
||||
# Note: The keys need to be actual column names
|
||||
$sort_fields = array(
|
||||
'' => translate('None'),
|
||||
'Id' => translate('AttrId'),
|
||||
'Name' => translate('AttrName'),
|
||||
'Cause' => translate('AttrCause'),
|
||||
|
@ -383,10 +384,18 @@ $sort_fields = array(
|
|||
);
|
||||
echo htmlSelect('filter[Query][sort_field]', $sort_fields, $filter->sort_field());
|
||||
$sort_dirns = array(
|
||||
'1' => translate('SortAsc'),
|
||||
'0' => translate('SortDesc')
|
||||
);
|
||||
echo htmlSelect( 'filter[Query][sort_asc]', $sort_dirns, $filter->sort_asc() );
|
||||
'1' => translate('SortAsc'),
|
||||
'0' => translate('SortDesc')
|
||||
);
|
||||
echo htmlSelect('filter[Query][sort_asc]', $sort_dirns, $filter->sort_asc());
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<label for="filter[Query][skip_locked]"><?php echo translate('Skip Locked') ?></label>
|
||||
<?php
|
||||
echo htmlSelect('filter[Query][skip_locked]',
|
||||
array('0'=>translate('No'), '1'=>translate('Yes')),
|
||||
$filter->skip_locked());
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
|
@ -468,9 +477,13 @@ if ( ZM_OPT_MESSAGE ) {
|
|||
<div id="optionsTable" class="filterTable">
|
||||
<fieldset><legend><?php echo translate('Options') ?></legend>
|
||||
<p>
|
||||
<label for="background"><?php echo translate('BackgroundFilter') ?></label>
|
||||
<label for="filter[Background]"><?php echo translate('BackgroundFilter') ?></label>
|
||||
<input type="checkbox" id="filter[Background]" name="filter[Background]" value="1"<?php if ( $filter->Background() ) { ?> checked="checked"<?php } ?> data-on-click-this="updateButtons"/>
|
||||
</p>
|
||||
<p>
|
||||
<label for="ExecuteInterval"><?php echo translate('Execute Interval') ?></label>
|
||||
<input type="number" id="filter[ExecuteInterval]" name="filter[ExecuteInterval]" min="0" step="1" value="<?php echo $filter->ExecuteInterval() ?>" />
|
||||
</p>
|
||||
<p>
|
||||
<label for="Concurrent"><?php echo translate('ConcurrentFilter') ?></label>
|
||||
<input type="checkbox" id="filter[Concurrent]" name="filter[Concurrent]" value="1"<?php if ( $filter->Concurrent() ) { ?> checked="checked"<?php } ?> data-on-click-this="updateButtons"/>
|
||||
|
|
|
@ -44,7 +44,7 @@ function ajaxRequest(params) {
|
|||
data.view = 'request';
|
||||
data.request = 'watch';
|
||||
data.mid = monitorId;
|
||||
if ( auth_hash ) data.auth = auth_hash;
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
|
||||
$j.getJSON(thisUrl, data)
|
||||
.done(function(data) {
|
||||
|
@ -94,8 +94,48 @@ function showPtzControls() {
|
|||
showMode = 'control';
|
||||
}
|
||||
|
||||
function changeSize() {
|
||||
var width = $j('#width').val();
|
||||
var height = $j('#height').val();
|
||||
|
||||
// Scale the frame
|
||||
monitor_frame = $j('#imageFeed');
|
||||
if (!monitor_frame) {
|
||||
console.log('Error finding frame');
|
||||
return;
|
||||
}
|
||||
if (width) monitor_frame.css('width', width);
|
||||
if (height) monitor_frame.css('height', height);
|
||||
|
||||
var streamImg = document.getElementById('liveStream'+monitorData[monIdx].id);
|
||||
if (streamImg) {
|
||||
if (streamImg.nodeName == 'IMG') {
|
||||
let src = streamImg.src;
|
||||
streamImg.src = '';
|
||||
src = src.replace(/width=[\.\d]+/i, 'width='+parseInt(width));
|
||||
src = src.replace(/height=[\.\d]+/i, 'height='+parseInt(height));
|
||||
src = src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) ));
|
||||
streamImg.src = src;
|
||||
}
|
||||
streamImg.style.width = width ? width : null;
|
||||
streamImg.style.height = height ? height : null;
|
||||
} else {
|
||||
console.log('Did not find liveStream'+monitorData[monIdx].id);
|
||||
}
|
||||
$j('#scale').val('');
|
||||
setCookie('zmCycleScale', '', 3600);
|
||||
setCookie('zmCycleWidth', width, 3600);
|
||||
setCookie('zmCycleHeight', height, 3600);
|
||||
} // end function changeSize()
|
||||
|
||||
function changeScale() {
|
||||
var scale = $j('#scale').val();
|
||||
$j('#width').val('auto');
|
||||
$j('#height').val('auto');
|
||||
setCookie('zmCycleScale', scale, 3600);
|
||||
setCookie('zmCycleWidth', 'auto', 3600);
|
||||
setCookie('zmCycleHeight', 'auto', 3600);
|
||||
|
||||
var newWidth;
|
||||
var newHeight;
|
||||
var autoScale;
|
||||
|
@ -104,7 +144,7 @@ function changeScale() {
|
|||
// times and what the consequences would be
|
||||
$j(window).off('resize', endOfResize); //remove resize handler when Scale to Fit is not active
|
||||
if (scale == '0' || scale == 'auto') {
|
||||
var newSize = scaleToFit(monitorWidth, monitorHeight, $j('#liveStream'+monitorId), $j('#replayStatus'));
|
||||
const newSize = scaleToFit(monitorWidth, monitorHeight, $j('#liveStream'+monitorId), $j('#replayStatus'));
|
||||
newWidth = newSize.width;
|
||||
newHeight = newSize.height;
|
||||
autoScale = newSize.autoScale;
|
||||
|
@ -118,16 +158,18 @@ function changeScale() {
|
|||
|
||||
var streamImg = $j('#liveStream'+monitorId);
|
||||
if (streamImg) {
|
||||
var oldSrc = streamImg.attr('src');
|
||||
streamImg.attr('src', '');
|
||||
// This is so that we don't waste bandwidth and let the browser do all the scaling.
|
||||
if (autoScale > 100) autoScale = 100;
|
||||
if (scale > 100) scale = 100;
|
||||
var newSrc = oldSrc.replace(/scale=\d+/i, 'scale='+((scale == 'auto' || scale == '0') ? autoScale : scale));
|
||||
if (streamImg.nodeName == 'IMG') {
|
||||
const oldSrc = streamImg.attr('src');
|
||||
streamImg.attr('src', '');
|
||||
// This is so that we don't waste bandwidth and let the browser do all the scaling.
|
||||
if (autoScale > 100) autoScale = 100;
|
||||
if (scale > 100) scale = 100;
|
||||
const newSrc = oldSrc.replace(/scale=\d+/i, 'scale='+((scale == 'auto' || scale == '0') ? autoScale : scale));
|
||||
|
||||
streamImg.width(newWidth);
|
||||
streamImg.height(newHeight);
|
||||
streamImg.attr('src', newSrc);
|
||||
streamImg.width(newWidth);
|
||||
streamImg.height(newHeight);
|
||||
streamImg.attr('src', newSrc);
|
||||
}
|
||||
} else {
|
||||
console.error('No element found for liveStream'+monitorId);
|
||||
}
|
||||
|
@ -200,9 +242,15 @@ function getStreamCmdResponse(respObj, respText) {
|
|||
// The get status command can get backed up, in which case we won't be able to get the semaphore and will exit.
|
||||
if (respObj.status) {
|
||||
streamStatus = respObj.status;
|
||||
$j('#fpsValue').text(streamStatus.fps);
|
||||
$j('#capturefpsValue').text(streamStatus.capturefps);
|
||||
$j('#analysisfpsValue').text(streamStatus.analysisfps);
|
||||
if ($j('#viewingFPSValue').text() != streamStatus.fps) {
|
||||
$j('#viewingFPSValue').text(streamStatus.fps);
|
||||
}
|
||||
if ($j('#captureFPSValue').text() != streamStatus.capturefps) {
|
||||
$j('#captureFPSValue').text(streamStatus.capturefps);
|
||||
}
|
||||
if ($j('#analysisFPSValue').text() != streamStatus.analysisfps) {
|
||||
$j('#analysisFPSValue').text(streamStatus.analysisfps);
|
||||
}
|
||||
|
||||
setAlarmState(streamStatus.state);
|
||||
|
||||
|
@ -287,31 +335,19 @@ function getStreamCmdResponse(respObj, respText) {
|
|||
// Try to reload the image stream.
|
||||
var streamImg = $j('#liveStream'+monitorId);
|
||||
if (streamImg) {
|
||||
var oldSrc = streamImg.attr('src');
|
||||
var newSrc = oldSrc.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
|
||||
if (oldSrc != newSrc) {
|
||||
streamImg.attr('src', newSrc);
|
||||
table.bootstrapTable('refresh');
|
||||
const oldSrc = streamImg.attr('src');
|
||||
if (oldSrc) {
|
||||
const newSrc = oldSrc.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
|
||||
if (oldSrc != newSrc) {
|
||||
streamImg.attr('src', newSrc);
|
||||
table.bootstrapTable('refresh');
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end if have a new auth hash
|
||||
} // end if respObj.status
|
||||
} else {
|
||||
checkStreamForErrors('getStreamCmdResponse', respObj);//log them
|
||||
// Try to reload the image stream.
|
||||
// If it's an auth error, we should reload the whole page.
|
||||
console.log("have error");
|
||||
//window.location.reload();
|
||||
var streamImg = $j('#liveStream'+monitorId);
|
||||
if (streamImg) {
|
||||
var oldSrc = streamImg.attr('src');
|
||||
var newSrc = oldSrc.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) ));
|
||||
|
||||
streamImg.attr('src', newSrc);
|
||||
console.log('Changing livestream src to ' + newSrc);
|
||||
} else {
|
||||
console.log('Unable to find streamImg liveStream');
|
||||
}
|
||||
}
|
||||
|
||||
var streamCmdTimeout = statusRefreshTimeout;
|
||||
|
@ -368,6 +404,7 @@ function streamCmdPlay(action) {
|
|||
}
|
||||
|
||||
function streamCmdReq(data) {
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
$j.getJSON(monitorUrl + '?view=request&request=stream&connkey='+connKey, data)
|
||||
.done(getStreamCmdResponse)
|
||||
.fail(getStreamCmdError);
|
||||
|
@ -386,10 +423,7 @@ function streamCmdStop(action) {
|
|||
setButtonState('fastRevBtn', 'unavail');
|
||||
}
|
||||
if (action) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = CMD_STOP;
|
||||
streamCmdReq(data);
|
||||
streamCmdReq({command: CMD_STOP});
|
||||
}
|
||||
setButtonState('stopBtn', 'unavail');
|
||||
setButtonState('playBtn', 'active');
|
||||
|
@ -407,7 +441,6 @@ function streamCmdFastFwd(action) {
|
|||
}
|
||||
if (action) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = CMD_FASTFWD;
|
||||
streamCmdReq(data);
|
||||
}
|
||||
|
@ -425,7 +458,6 @@ function streamCmdSlowFwd(action) {
|
|||
}
|
||||
if (action) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = CMD_SLOWFWD;
|
||||
streamCmdReq(data);
|
||||
}
|
||||
|
@ -447,7 +479,6 @@ function streamCmdSlowRev(action) {
|
|||
}
|
||||
if (action) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = CMD_SLOWREV;
|
||||
streamCmdReq(data);
|
||||
}
|
||||
|
@ -469,7 +500,6 @@ function streamCmdFastRev(action) {
|
|||
}
|
||||
if (action) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = CMD_FASTREV;
|
||||
streamCmdReq(data);
|
||||
}
|
||||
|
@ -477,7 +507,6 @@ function streamCmdFastRev(action) {
|
|||
|
||||
function streamCmdZoomIn(x, y) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.x = x;
|
||||
data.y = y;
|
||||
data.command = CMD_ZOOMIN;
|
||||
|
@ -486,14 +515,12 @@ function streamCmdZoomIn(x, y) {
|
|||
|
||||
function streamCmdZoomOut() {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = CMD_ZOOMOUT;
|
||||
streamCmdReq(data);
|
||||
}
|
||||
|
||||
function streamCmdScale(scale) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = CMD_SCALE;
|
||||
data.scale = scale;
|
||||
streamCmdReq(data);
|
||||
|
@ -501,7 +528,6 @@ function streamCmdScale(scale) {
|
|||
|
||||
function streamCmdPan(x, y) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.x = x;
|
||||
data.y = y;
|
||||
data.command = CMD_PAN;
|
||||
|
@ -510,11 +536,11 @@ function streamCmdPan(x, y) {
|
|||
|
||||
function streamCmdQuery() {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = CMD_QUERY;
|
||||
streamCmdReq(data);
|
||||
}
|
||||
|
||||
/* getStatusCmd is used when not streaming, since there is no persistent zms */
|
||||
function getStatusCmdResponse(respObj, respText) {
|
||||
watchdogOk('status');
|
||||
if (statusCmdTimer) {
|
||||
|
@ -522,32 +548,33 @@ function getStatusCmdResponse(respObj, respText) {
|
|||
}
|
||||
|
||||
if (respObj.result == 'Ok') {
|
||||
$j('#fpsValue').text(respObj.monitor.FrameRate);
|
||||
$j('#captureFPSValue').text(respObj.monitor.FrameRate);
|
||||
setAlarmState(respObj.monitor.Status);
|
||||
} else {
|
||||
checkStreamForErrors('getStatusCmdResponse', respObj);
|
||||
}
|
||||
|
||||
var statusCmdTimeout = statusRefreshTimeout;
|
||||
if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT ) {
|
||||
if (alarmState == STATE_ALARM || alarmState == STATE_ALERT) {
|
||||
statusCmdTimeout = statusCmdTimeout/5;
|
||||
}
|
||||
statusCmdTimer = setTimeout(statusCmdQuery, statusCmdTimeout);
|
||||
}
|
||||
|
||||
function statusCmdQuery() {
|
||||
$j.getJSON(monitorUrl + '?view=request&request=status&entity=monitor&element[]=Status&element[]=FrameRate&id='+monitorId)
|
||||
$j.getJSON(monitorUrl + '?view=request&request=status&entity=monitor&element[]=Status&element[]=FrameRate&id='+monitorId+'&'+auth_relay)
|
||||
.done(getStatusCmdResponse)
|
||||
.fail(logAjaxFail);
|
||||
|
||||
streamCmdTimer = null;
|
||||
statusCmdTimer = null;
|
||||
}
|
||||
|
||||
function alarmCmdReq(data) {
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
$j.getJSON(monitorUrl + '?view=request&request=alarm&id='+monitorId, data)
|
||||
.done(getAlarmCmdResponse)
|
||||
.fail(function(jqxhr, textStatus, error) {
|
||||
if ( textStatus === "timeout" ) {
|
||||
if (textStatus === 'timeout') {
|
||||
streamCmdQuery();
|
||||
} else {
|
||||
logAjaxFail(jqxhr, textStatus, error);
|
||||
|
@ -561,14 +588,12 @@ function getAlarmCmdResponse(respObj, respText) {
|
|||
|
||||
function cmdDisableAlarms() {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = 'disableAlarms';
|
||||
alarmCmdReq(data);
|
||||
}
|
||||
|
||||
function cmdEnableAlarms() {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = 'enableAlarms';
|
||||
alarmCmdReq(data);
|
||||
}
|
||||
|
@ -583,7 +608,6 @@ function cmdAlarm() {
|
|||
|
||||
function cmdForceAlarm() {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = 'forceAlarm';
|
||||
alarmCmdReq(data);
|
||||
if (window.event) window.event.preventDefault();
|
||||
|
@ -591,7 +615,6 @@ function cmdForceAlarm() {
|
|||
|
||||
function cmdCancelForcedAlarm() {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.command = 'cancelForcedAlarm';
|
||||
alarmCmdReq(data);
|
||||
if (window.event) window.event.preventDefault();
|
||||
|
@ -607,6 +630,7 @@ function cmdForce() {
|
|||
}
|
||||
|
||||
function controlReq(data) {
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
$j.getJSON(monitorUrl + '?view=request&request=control&id='+monitorId, data)
|
||||
.done(getControlResponse)
|
||||
.fail(logAjaxFail);
|
||||
|
@ -639,16 +663,16 @@ function controlCmd(event) {
|
|||
var data = {};
|
||||
|
||||
if (event && (xtell || ytell)) {
|
||||
var target = event.target;
|
||||
var offset = $j(target).offset();
|
||||
var width = $j(target).width();
|
||||
var height = $j(target).height();
|
||||
const target = event.target;
|
||||
const offset = $j(target).offset();
|
||||
const width = $j(target).width();
|
||||
const height = $j(target).height();
|
||||
|
||||
var x = event.pageX - offset.left;
|
||||
var y = event.pageY - offset.top;
|
||||
const x = event.pageX - offset.left;
|
||||
const y = event.pageY - offset.top;
|
||||
|
||||
if (xtell) {
|
||||
var xge = parseInt((x*100)/width);
|
||||
let xge = parseInt((x*100)/width);
|
||||
if (xtell == -1) {
|
||||
xge = 100 - xge;
|
||||
} else if (xtell == 2) {
|
||||
|
@ -657,7 +681,7 @@ function controlCmd(event) {
|
|||
data.xge = xge;
|
||||
}
|
||||
if (ytell) {
|
||||
var yge = parseInt((y*100)/height);
|
||||
let yge = parseInt((y*100)/height);
|
||||
if (ytell == -1) {
|
||||
yge = 100 - yge;
|
||||
} else if (ytell == 2) {
|
||||
|
@ -667,7 +691,6 @@ function controlCmd(event) {
|
|||
}
|
||||
}
|
||||
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.control = control;
|
||||
controlReq(data);
|
||||
|
||||
|
@ -678,7 +701,6 @@ function controlCmd(event) {
|
|||
|
||||
function controlCmdImage(x, y) {
|
||||
var data = {};
|
||||
if (auth_hash) data.auth = auth_hash;
|
||||
data.scale = scale;
|
||||
data.control = imageControlMode;
|
||||
data.x = x;
|
||||
|
@ -768,7 +790,6 @@ function reloadWebSite() {
|
|||
|
||||
function updatePresetLabels() {
|
||||
var lblNdx = $j('#ctrlPresetForm option:selected').val();
|
||||
|
||||
$j('#newLabel').val(labels[lblNdx]);
|
||||
}
|
||||
|
||||
|
@ -878,7 +899,7 @@ function initPage() {
|
|||
// Load the PTZ Preset modal into the DOM
|
||||
if (monitorControllable) getCtrlPresetModal();
|
||||
// Load the settings modal into the DOM
|
||||
if (monitorType == "Local") getSettingsModal();
|
||||
if (monitorType == 'Local') getSettingsModal();
|
||||
}
|
||||
|
||||
if (monitorType != 'WebSite') {
|
||||
|
@ -886,15 +907,12 @@ function initPage() {
|
|||
statusCmdTimer = setTimeout(statusCmdQuery, (Math.random()+0.1)*statusRefreshTimeout);
|
||||
setInterval(watchdogCheck, statusRefreshTimeout*2, 'status');
|
||||
} else {
|
||||
streamCmdTimer = setTimeout(streamCmdQuery, (Math.random()+0.1)*statusRefreshTimeout);
|
||||
setInterval(watchdogCheck, statusRefreshTimeout*2, 'stream');
|
||||
}
|
||||
|
||||
if (canStreamNative || (streamMode == 'single')) {
|
||||
var streamImg = $j('#imageFeed img');
|
||||
if (!streamImg) {
|
||||
streamImg = $j('#imageFeed object');
|
||||
}
|
||||
if (!streamImg) streamImg = $j('#imageFeed object');
|
||||
if (!streamImg) {
|
||||
console.error('No streamImg found for imageFeed');
|
||||
} else {
|
||||
|
@ -905,6 +923,10 @@ function initPage() {
|
|||
streamImg.click(function(event) {
|
||||
handleClick(event);
|
||||
});
|
||||
streamImg.on("error", function(thing) {
|
||||
console.log("Error loading image");
|
||||
console.log(thing);
|
||||
});
|
||||
}
|
||||
} // end if have streamImg
|
||||
} // streamMode native or single
|
||||
|
@ -944,6 +966,18 @@ function initPage() {
|
|||
$j('#settingsModal').modal('show');
|
||||
});
|
||||
|
||||
bindButton('#cyclePlayBtn', 'click', null, cycleStart);
|
||||
bindButton('#cyclePauseBtn', 'click', null, cyclePause);
|
||||
bindButton('#cycleNextBtn', 'click', null, cycleNext);
|
||||
bindButton('#cyclePrevBtn', 'click', null, cyclePrev);
|
||||
bindButton('#cycleToggle', 'click', null, cycleToggle);
|
||||
bindButton('#cyclePeriod', 'change', null, cyclePeriodChange);
|
||||
if (cycle) {
|
||||
cycleStart();
|
||||
} else {
|
||||
cyclePause();
|
||||
}
|
||||
|
||||
// Only enable the settings button for local cameras
|
||||
settingsBtn.prop('disabled', !(canView.Control && (monitorType == 'Local')));
|
||||
|
||||
|
@ -972,7 +1006,6 @@ function initPage() {
|
|||
|
||||
function watchFullscreen() {
|
||||
const btn = document.getElementById('fullscreenBtn');
|
||||
console.log(btn);
|
||||
if (btn.firstElementChild.innerHTML=='fullscreen') {
|
||||
const content = document.getElementById('content');
|
||||
openFullscreen(content);
|
||||
|
@ -985,5 +1018,70 @@ function watchFullscreen() {
|
|||
}
|
||||
}
|
||||
|
||||
var intervalId;
|
||||
var secondsToCycle = 0;
|
||||
|
||||
function nextCycleView() {
|
||||
secondsToCycle --;
|
||||
if (secondsToCycle<=0) {
|
||||
window.location.replace('?view=watch&mid='+nextMid+'&mode='+mode+'&cycle=true');
|
||||
}
|
||||
$j('#secondsToCycle').text(secondsToCycle);
|
||||
}
|
||||
|
||||
function cyclePause() {
|
||||
clearInterval(intervalId);
|
||||
$j('#cyclePauseBtn').hide();
|
||||
$j('#cyclePlayBtn').show();
|
||||
}
|
||||
|
||||
function cycleStart() {
|
||||
secondsToCycle = $j('#cyclePeriod').val();
|
||||
intervalId = setInterval(nextCycleView, 1000);
|
||||
$j('#cyclePauseBtn').show();
|
||||
$j('#cyclePlayBtn').hide();
|
||||
}
|
||||
|
||||
function cycleNext() {
|
||||
monIdx ++;
|
||||
if (monIdx >= monitorData.length) {
|
||||
monIdx = 0;
|
||||
}
|
||||
if (!monitorData[monIdx]) {
|
||||
console.log('No monitorData for ' + monIdx);
|
||||
}
|
||||
window.location.replace('?view=watch&cycle=true&mid='+monitorData[monIdx].id+'&mode='+mode);
|
||||
}
|
||||
|
||||
function cyclePrev() {
|
||||
monIdx --;
|
||||
if (monIdx < 0) {
|
||||
monIdx = monitorData.length - 1;
|
||||
}
|
||||
if (!monitorData[monIdx]) {
|
||||
console.log('No monitorData for ' + monIdx);
|
||||
}
|
||||
window.location.replace('?view=watch&cycle=true&mid='+monitorData[monIdx].id+'&mode='+mode);
|
||||
}
|
||||
|
||||
function cyclePeriodChange() {
|
||||
const cyclePeriodSelect = $j('#cyclePeriod');
|
||||
secondsToCycle = cyclePeriodSelect.val();
|
||||
setCookie('zmCyclePeriod', secondsToCycle, 3600);
|
||||
}
|
||||
function cycleToggle(e) {
|
||||
sidebar = $j('#sidebar');
|
||||
button = $j('#cycleToggle');
|
||||
if (sidebar.is(":visible")) {
|
||||
sidebar.hide();
|
||||
setCookie('zmCycleShow', false, 3600);
|
||||
} else {
|
||||
sidebar.show();
|
||||
setCookie('zmCycleShow', true, 3600);
|
||||
}
|
||||
button.toggleClass('btn-secondary');
|
||||
button.toggleClass('btn-primary');
|
||||
}
|
||||
|
||||
// Kick everything off
|
||||
$j(document).ready(initPage);
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
<?php
|
||||
global $monIdx;
|
||||
global $nextMid;
|
||||
global $options;
|
||||
global $monitors;
|
||||
global $streamMode;
|
||||
global $showPtzControls;
|
||||
global $connkey;
|
||||
global $monitor;
|
||||
global $scale;
|
||||
global $labels;
|
||||
global $cycle;
|
||||
?>
|
||||
//
|
||||
// Import constants
|
||||
//
|
||||
|
||||
var deleteString = "<?php echo translate('Delete') ?>";
|
||||
|
||||
var enableAlarmsStr = "<?php echo translate('EnableAlarms') ?>";
|
||||
var disableAlarmsStr = "<?php echo translate('DisableAlarms') ?>";
|
||||
var forceAlarmStr = "<?php echo translate('ForceAlarm') ?>";
|
||||
var cancelForcedAlarmStr = "<?php echo translate('CancelForcedAlarm') ?>";
|
||||
|
||||
var CMD_NONE = <?php echo CMD_NONE ?>;
|
||||
var CMD_PAUSE = <?php echo CMD_PAUSE ?>;
|
||||
|
@ -34,14 +33,13 @@ var CMD_NEXT = <?php echo CMD_NEXT ?>;
|
|||
var CMD_SEEK = <?php echo CMD_SEEK ?>;
|
||||
var CMD_QUERY = <?php echo CMD_QUERY ?>;
|
||||
|
||||
var SCALE_BASE = <?php echo SCALE_BASE ?>;
|
||||
|
||||
var SOUND_ON_ALARM = <?php echo ZM_WEB_SOUND_ON_ALARM ?>;
|
||||
var POPUP_ON_ALARM = <?php echo ZM_WEB_POPUP_ON_ALARM ?>;
|
||||
var LIST_THUMBS = <?php echo ZM_WEB_LIST_THUMBS?'true':'false' ?>;
|
||||
|
||||
var streamMode = "<?php echo $streamMode ?>";
|
||||
var showMode = "<?php echo ($showPtzControls && !empty($control))?"control":"events" ?>";
|
||||
var cycle = <?php echo $cycle ? 'true' : 'false' ?>;
|
||||
|
||||
var connKey = '<?php echo $connkey ?>';
|
||||
var maxDisplayEvents = <?php echo 2 * MAX_EVENTS ?>;
|
||||
|
@ -55,6 +53,28 @@ var monitorRefresh = '<?php echo $monitor->Refresh() ?>';
|
|||
var monitorStreamReplayBuffer = <?php echo $monitor->StreamReplayBuffer() ?>;
|
||||
var monitorControllable = <?php echo $monitor->Controllable()?'true':'false' ?>;
|
||||
|
||||
var monIdx = '<?php echo $monIdx; ?>';
|
||||
var nextMid = "<?php echo isset($nextMid)?$nextMid:'' ?>";
|
||||
var mode = "<?php echo $options['mode'] ?>";
|
||||
|
||||
var monitorData = new Array();
|
||||
<?php
|
||||
foreach ($monitors as $monitor) {
|
||||
?>
|
||||
monitorData[monitorData.length] = {
|
||||
'id': <?php echo $monitor->Id() ?>,
|
||||
'width': <?php echo $monitor->ViewWidth() ?>,
|
||||
'height':<?php echo $monitor->ViewHeight() ?>,
|
||||
'url': '<?php echo $monitor->UrlToIndex() ?>',
|
||||
'onclick': function(){window.location.assign( '?view=watch&mid=<?php echo $monitor->Id() ?>' );},
|
||||
'type': '<?php echo $monitor->Type() ?>',
|
||||
'refresh': '<?php echo $monitor->Refresh() ?>'
|
||||
};
|
||||
<?php
|
||||
} // end foreach monitor
|
||||
?>
|
||||
|
||||
var SCALE_BASE = <?php echo SCALE_BASE ?>;
|
||||
var scale = '<?php echo $scale ?>';
|
||||
|
||||
var statusRefreshTimeout = <?php echo 1000*ZM_WEB_REFRESH_STATUS ?>;
|
||||
|
@ -63,17 +83,16 @@ var imageRefreshTimeout = <?php echo 1000*ZM_WEB_REFRESH_IMAGE ?>;
|
|||
|
||||
var canStreamNative = <?php echo canStreamNative()?'true':'false' ?>;
|
||||
|
||||
<?php
|
||||
$control = $monitor->Control();
|
||||
if ( $control->CanMoveMap() ) { ?>
|
||||
var imageControlMode = "moveMap";
|
||||
<?php } elseif ( $control->CanMoveRel() ) { ?>
|
||||
var imageControlMode = "movePseudoMap";
|
||||
<?php } elseif ( $control->CanMoveCon() ) { ?>
|
||||
var imageControlMode = "moveConMap";
|
||||
<?php } else { ?>
|
||||
var imageControlMode = null;
|
||||
<?php } ?>
|
||||
var imageControlMode = '<?php
|
||||
$control = $monitor->Control();
|
||||
if ($control->CanMoveMap()) {
|
||||
echo 'moveMap';
|
||||
} else if ($control->CanMoveRel()) {
|
||||
echo 'movePseudoMap';
|
||||
} else if ($control->CanMoveCon()) {
|
||||
echo 'moveConMap';
|
||||
}
|
||||
?>';
|
||||
|
||||
var refreshApplet = <?php echo (canStreamApplet() && $streamMode == "jpeg")?'true':'false' ?>;
|
||||
var appletRefreshTime = <?php echo ZM_RELOAD_CAMBOZOLA ?>;
|
||||
|
@ -81,17 +100,18 @@ var appletRefreshTime = <?php echo ZM_RELOAD_CAMBOZOLA ?>;
|
|||
var labels = new Array();
|
||||
<?php
|
||||
$labels = array();
|
||||
foreach( dbFetchAll( 'SELECT * FROM ControlPresets WHERE MonitorId = ?', NULL, array( $monitor->Id() ) ) as $row ) {
|
||||
$labels[$row['Preset']] = $row['Label'];
|
||||
}
|
||||
|
||||
foreach ($labels as $index=>$label) {
|
||||
?>
|
||||
labels[<?php echo validInt($index) ?>] = '<?php echo validJsStr($label) ?>';
|
||||
<?php
|
||||
foreach (dbFetchAll('SELECT * FROM ControlPresets WHERE MonitorId = ?', NULL, array($monitor->Id())) as $row) {
|
||||
$label = $labels[$row['Preset']] = $row['Label'];
|
||||
echo 'labels['. validInt($index) .'] = '.validJsStr($label).'\'';
|
||||
}
|
||||
?>
|
||||
var deleteString = "<?php echo translate('Delete') ?>";
|
||||
var enableAlarmsStr = "<?php echo translate('EnableAlarms') ?>";
|
||||
var disableAlarmsStr = "<?php echo translate('DisableAlarms') ?>";
|
||||
var forceAlarmStr = "<?php echo translate('ForceAlarm') ?>";
|
||||
var cancelForcedAlarmStr = "<?php echo translate('CancelForcedAlarm') ?>";
|
||||
var translate = {
|
||||
"seconds": "<?php echo translate('seconds') ?>",
|
||||
"Fullscreen": "<?php echo translate('Fullscreen') ?>",
|
||||
"Exit Fullscreen": "<?php echo translate('Exit Fullscreen') ?>",
|
||||
};
|
||||
|
|
|
@ -18,143 +18,296 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView('Stream') ) {
|
||||
if (!canView('Stream')) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
require_once('includes/Monitor.php');
|
||||
|
||||
ob_start();
|
||||
include('_monitor_filters.php');
|
||||
$filterbar = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
if ( !isset($_REQUEST['mid']) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
// This is for input sanitation
|
||||
$mid = intval($_REQUEST['mid']);
|
||||
if ( !visibleMonitor($mid) ) {
|
||||
$mid = isset($_REQUEST['mid']) ? intval($_REQUEST['mid']) : 0;
|
||||
|
||||
$widths = array(
|
||||
'auto' => translate('auto'),
|
||||
'100%' => '100%',
|
||||
'160px' => '160px',
|
||||
'320px' => '320px',
|
||||
'352px' => '352px',
|
||||
'640px' => '640px',
|
||||
'1280px' => '1280px',
|
||||
'1920px' => '1920px'
|
||||
);
|
||||
|
||||
$heights = array(
|
||||
'auto' => translate('auto'),
|
||||
'240px' => '240px',
|
||||
'480px' => '480px',
|
||||
'720px' => '720px',
|
||||
'1080px' => '1080px',
|
||||
);
|
||||
|
||||
$monitors = array();
|
||||
$monitor_index = 0;
|
||||
foreach ($displayMonitors as &$row) {
|
||||
if ($row['Function'] == 'None') continue;
|
||||
if ($mid and ($row['Id'] == $mid)) $monitor_index = count($monitors);
|
||||
$monitors[] = new ZM\Monitor($row);
|
||||
if (!isset($widths[$row['Width'].'px'])) {
|
||||
$widths[$row['Width'].'px'] = $row['Width'].'px';
|
||||
}
|
||||
if (!isset($heights[$row['Height'].'px'])) {
|
||||
$heights[$row['Height'].'px'] = $row['Height'].'px';
|
||||
}
|
||||
unset($row);
|
||||
} # end foreach Monitor
|
||||
|
||||
if (!$mid) {
|
||||
$mid = $monitors[0]->Id();
|
||||
$monitor_index = 0;
|
||||
}
|
||||
|
||||
if (!visibleMonitor($mid)) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
require_once('includes/Monitor.php');
|
||||
$monitor = new ZM\Monitor($mid);
|
||||
|
||||
$nextMid = ($monitor_index == count($monitors)-1) ? $monitors[0]->Id() : $monitors[$monitor_index+1]->Id();
|
||||
$cycle = isset($_REQUEST['cycle']) and ($_REQUEST['cycle'] == 'true');
|
||||
$showCycle = $cycle;
|
||||
ZM\Error("Show cycle: $showCycle");
|
||||
if (isset($_COOKIE['zmCycleShow'])) {
|
||||
$showCycle = $_COOKIE['zmCycleShow'] == 'true';
|
||||
ZM\Error("Show cycle: $showCycle");
|
||||
} else {
|
||||
ZM\Error("Show cycle: not set");
|
||||
}
|
||||
#Whether to show the controls button
|
||||
$showPtzControls = ( ZM_OPT_CONTROL && $monitor->Controllable() && canView('Control') && $monitor->Type() != 'WebSite' );
|
||||
|
||||
if ( isset($_REQUEST['scale']) ) {
|
||||
$options = array();
|
||||
if (empty($_REQUEST['mode'])) {
|
||||
$options['mode'] = canStream() ? 'stream' : 'still';
|
||||
} else {
|
||||
$options['mode'] = validHtmlStr($_REQUEST['mode']);
|
||||
}
|
||||
zm_session_start();
|
||||
|
||||
$period = ZM_WEB_REFRESH_CYCLE;
|
||||
if (isset($_REQUEST['period'])) {
|
||||
$period = validInt($_REQUEST['period']);
|
||||
} else if (isset($_COOKIE['zmCyclePeriod'])) {
|
||||
$period = validInt($_COOKIE['zmCyclePeriod']);
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['scale'])) {
|
||||
$scale = validInt($_REQUEST['scale']);
|
||||
} else if ( isset($_COOKIE['zmWatchScale'.$mid]) ) {
|
||||
$scale = $_COOKIE['zmWatchScale'.$mid];
|
||||
} else {
|
||||
$scale = $monitor->DefaultScale();
|
||||
}
|
||||
$options['scale'] = $scale;
|
||||
|
||||
if (isset($_REQUEST['width'])) {
|
||||
$options['width'] = validInt($_REQUEST['width']);
|
||||
} else if ( isset($_COOKIE['zmCycleWidth']) and $_COOKIE['zmCycleWidth'] ) {
|
||||
$_SESSION['zmCycleWidth'] = $options['width'] = $_COOKIE['zmCycleWidth'];
|
||||
#} elseif ( isset($_SESSION['zmCycleWidth']) and $_SESSION['zmCycleWidth'] ) {
|
||||
#$options['width'] = $_SESSION['zmCycleWidth'];
|
||||
} else {
|
||||
$options['width'] = '';
|
||||
}
|
||||
if (isset($_REQUEST['height'])) {
|
||||
$options['height'] =validInt($_REQUEST['height']);
|
||||
} else if (isset($_COOKIE['zmCycleHeight']) and $_COOKIE['zmCycleHeight']) {
|
||||
$_SESSION['zmCycleHeight'] = $options['height'] = $_COOKIE['zmCycleHeight'];
|
||||
#else if ( isset($_SESSION['zmCycleHeight']) and $_SESSION['zmCycleHeight'] )
|
||||
#$options['height'] = $_SESSION['zmCycleHeight'];
|
||||
} else {
|
||||
$options['height'] = '';
|
||||
}
|
||||
session_write_close();
|
||||
|
||||
$connkey = generateConnKey();
|
||||
|
||||
$streamMode = getStreamMode();
|
||||
|
||||
$popup = ((isset($_REQUEST['popup'])) && ($_REQUEST['popup'] == 1));
|
||||
|
||||
noCacheHeaders();
|
||||
xhtmlHeaders(__FILE__, $monitor->Name().' - '.translate('Feed'));
|
||||
?>
|
||||
<body>
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="header">
|
||||
<div class="controlHeader">
|
||||
<form method="get">
|
||||
<input type="hidden" name="view" value="watch"/>
|
||||
<?php echo $filterbar ?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-row justify-content-between px-3 py-1">
|
||||
<div>
|
||||
<div id="navButtons">
|
||||
<button type="button" id="backBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Back') ?>" disabled><i class="fa fa-arrow-left"></i></button>
|
||||
<button type="button" id="refreshBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Refresh') ?>" ><i class="fa fa-refresh"></i></button>
|
||||
<button type="button" id="settingsBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Settings') ?>" disabled><i class="fa fa-sliders"></i></button>
|
||||
<button type="button" id="enableAlmBtn" class="btn btn-normal" data-on-click="cmdAlarm" data-toggle="tooltip" data-placement="top" title="<?php echo translate('DisableAlarms') ?>" disabled><i class="fa fa-bell"></i></button>
|
||||
<button type="button" id="forceAlmBtn" class="btn btn-danger" data-on-click="cmdForce" data-toggle="tooltip" data-placement="top" title="<?php echo translate('ForceAlarm') ?>" disabled><i class="fa fa-exclamation-circle"></i></button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2><?php echo makeLink('?view=monitor&mid='.$monitor->Id(), validHtmlStr($monitor->Name()), canEdit('Monitors')) ?></h2>
|
||||
<div id="headerButtons">
|
||||
<!--
|
||||
<?php if ( $options['mode'] == 'stream' ) { ?>
|
||||
<a href="?view=<?php echo $view ?>&mode=still&mid=<?php echo $monitor ? $monitor->Id() : '' ?>"><?php echo translate('Stills') ?></a>
|
||||
<?php } else { ?>
|
||||
<a href="?view=<?php echo $view ?>&mode=stream&mid=<?php echo $monitor ? $monitor->Id() : '' ?>"><?php echo translate('Stream') ?></a>
|
||||
<?php } ?>
|
||||
-->
|
||||
<button type="button" id="cycleToggle" class="btn <?php echo $showCycle ? 'btn-primary':'btn-secondary'?>" title="<?php echo translate('Toggle cycle sidebar')?>">
|
||||
<span class="material-icons md-18">view_carousel</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<?php echo translate('Scale').': '.htmlSelect('scale', $scales, $scale, array('id'=>'scale')); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sizeControl">
|
||||
<span id="widthControl">
|
||||
<label><?php echo translate('Width') ?>:</label>
|
||||
<?php echo htmlSelect('width', $widths, $options['width'], array('id'=>'width', 'data-on-change-this'=>'changeSize') ); ?>
|
||||
</span>
|
||||
<span id="heightControl">
|
||||
<label><?php echo translate('Height') ?>:</label>
|
||||
<?php echo htmlSelect('height', $heights, $options['height'], array('id'=>'height', 'data-on-change-this'=>'changeSize') ); ?>
|
||||
</span>
|
||||
<span id="scaleControl">
|
||||
<label><?php echo translate('Scale') ?>:</label>
|
||||
<?php echo htmlSelect('scale', $scales, $options['scale'], array('id'=>'scale', 'data-on-change-this'=>'changeScale') ); ?>
|
||||
</span>
|
||||
</div><!--sizeControl-->
|
||||
</div><!--control header-->
|
||||
</div><!--header-->
|
||||
<?php
|
||||
if ( $monitor->Status() != 'Connected' and $monitor->Type() != 'WebSite' ) {
|
||||
echo '<div class="warning">Monitor is not capturing. We will be unable to provide an image</div>';
|
||||
}
|
||||
?>
|
||||
<div id="content">
|
||||
<div id="imageFeed"
|
||||
<div class="container-fluid h-100">
|
||||
<div class="row flex-nowrap h-100" id="content">
|
||||
<nav id="sidebar" class="h-100"<?php echo $showCycle?'':' style="display:none;"'?>>
|
||||
<div id="cycleButtons" class="buttons">
|
||||
<?php
|
||||
if ( $streamMode == 'jpeg' ) {
|
||||
$seconds = translate('seconds');
|
||||
$minute = translate('minute');
|
||||
$minutes = translate('minutes');
|
||||
$cyclePeriodOptions = array(
|
||||
10 => '10 '.$seconds,
|
||||
30 => '30 '.$seconds,
|
||||
60 => '1 '.$minute,
|
||||
120 => '2 '.$minutes,
|
||||
300 => '5 '.$minutes,
|
||||
);
|
||||
if (!isset($cyclePeriodOptions[ZM_WEB_REFRESH_CYCLE])) {
|
||||
$cyclePeriodOptions[ZM_WEB_REFRESH_CYCLE] = ZM_WEB_REFRESH_CYCLE.' '.$seconds;
|
||||
}
|
||||
echo htmlSelect('cyclePeriod', $cyclePeriodOptions, $period, array('id'=>'cyclePeriod'));
|
||||
?>
|
||||
<span id="secondsToCycle"></span><br/>
|
||||
<button type="button" id="cyclePrevBtn" title="<?php echo translate('PreviousMonitor') ?>">
|
||||
<i class="material-icons md-18">skip_previous</i>
|
||||
</button>
|
||||
<button type="button" id="cyclePauseBtn" title="<?php echo translate('PauseCycle') ?>">
|
||||
<i class="material-icons md-18">pause</i>
|
||||
</button>
|
||||
<button type="button" id="cyclePlayBtn" title="<?php echo translate('PlayCycle') ?>">
|
||||
<i class="material-icons md-18">play_arrow</i>
|
||||
</button>
|
||||
<button type="button" id="cycleNextBtn" title="<?php echo translate('NextMonitor') ?>">
|
||||
<i class="material-icons md-18">skip_next</i>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="nav nav-pills flex-column h-100">
|
||||
<?php
|
||||
foreach ($monitors as $m) {
|
||||
echo '<li class="nav-item"><a class="nav-link'.( $m->Id() == $monitor->Id() ? ' active' : '' ).'" href="?view=watch&mid='.$m->Id().'">'.$m->Name().'</a></li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="container-fluid col-sm-offset-2 h-100 pr-0">
|
||||
<div id="imageFeed"
|
||||
<?php
|
||||
if ($streamMode == 'jpeg') {
|
||||
echo 'title="Click to zoom, shift click to pan, ctrl click to zoom out"';
|
||||
}
|
||||
?>
|
||||
><?php echo getStreamHTML($monitor, array('scale'=>$scale)); ?></div>
|
||||
|
||||
|
||||
<?php if ( $monitor->Type() != 'WebSite' ) { ?>
|
||||
<div id="monitorStatus">
|
||||
<div id="monitorState">
|
||||
<?php echo translate('State') ?>:
|
||||
<span id="stateValue"></span> -
|
||||
<span title="<?php echo translate('Viewing FPS')?>"><span id="fpsValue"></span> fps</span>
|
||||
<span title="<?php echo translate('Capturing FPS')?>"><span id="capturefpsValue"></span> fps</span>
|
||||
<?php if ( $monitor->Function() == 'Modect' or $monitor->Function() == 'Mocord' ) { ?>
|
||||
<span title="<?php echo translate('Analysis FPS')?>"><span id="analysisfpsValue"></span> fps</span>
|
||||
<?php } ?>
|
||||
><?php echo getStreamHTML($monitor, array('scale'=>$scale)); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dvrControls">
|
||||
|
||||
<?php if ($monitor->Type() != 'WebSite') { ?>
|
||||
<div id="monitorStatus">
|
||||
<div id="monitorState">
|
||||
<span><?php echo translate('State') ?>:<span id="stateValue"></span></span>
|
||||
<span id="viewingFPS" title="<?php echo translate('Viewing FPS')?>"><span id="viewingFPSValue"></span> fps</span>
|
||||
<span id="captureFPS" title="<?php echo translate('Capturing FPS')?>"><span id="captureFPSValue"></span> fps</span>
|
||||
<?php if ( $monitor->Function() == 'Modect' or $monitor->Function() == 'Mocord' ) { ?>
|
||||
<span id="analysisFPS" title="<?php echo translate('Analysis FPS')?>"><span id="analysisFPSValue"></span> fps</span>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="replayStatus"<?php echo $streamMode=="single" ? ' class="hidden"' : '' ?>>
|
||||
<span id="mode"><?php echo translate('Mode') ?>: <span id="modeValue"></span></span>
|
||||
<span id="rate"><?php echo translate('Rate') ?>: <span id="rateValue"></span>x</span>
|
||||
<span id="delay"><?php echo translate('Delay') ?>: <span id="delayValue"></span>s</span>
|
||||
<span id="level"><?php echo translate('Buffer') ?>: <span id="levelValue"></span>%</span>
|
||||
<span id="zoom"><?php echo translate('Zoom') ?>: <span id="zoomValue"></span>x</span>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<div id="dvrControls">
|
||||
<?php
|
||||
if ( $streamMode == 'jpeg' ) {
|
||||
if ( $monitor->StreamReplayBuffer() != 0 ) {
|
||||
if ($streamMode == 'jpeg') {
|
||||
if ($monitor->StreamReplayBuffer() != 0) {
|
||||
?>
|
||||
<button type="button" id="fastRevBtn" title="<?php echo translate('Rewind') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdFastRev">
|
||||
<i class="material-icons md-18">fast_rewind</i>
|
||||
</button>
|
||||
<button type="button" id="slowRevBtn" title="<?php echo translate('StepBack') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdSlowRev">
|
||||
<i class="material-icons md-18">chevron_right</i>
|
||||
</button>
|
||||
<button type="button" id="fastRevBtn" title="<?php echo translate('Rewind') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdFastRev">
|
||||
<i class="material-icons md-18">fast_rewind</i>
|
||||
</button>
|
||||
<button type="button" id="slowRevBtn" title="<?php echo translate('StepBack') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdSlowRev">
|
||||
<i class="material-icons md-18">chevron_right</i>
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<button type="button" id="pauseBtn" title="<?php echo translate('Pause') ?>" class="inactive" data-on-click-true="streamCmdPause">
|
||||
<i class="material-icons md-18">pause</i>
|
||||
</button>
|
||||
<button type="button" id="stopBtn" title="<?php echo translate('Stop') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdStop" style="display:none;">
|
||||
<i class="material-icons md-18">stop</i>
|
||||
</button>
|
||||
<button type="button" id="playBtn" title="<?php echo translate('Play') ?>" class="active" disabled="disabled" data-on-click-true="streamCmdPlay">
|
||||
<i class="material-icons md-18">play_arrow</i>
|
||||
</button>
|
||||
<button type="button" id="pauseBtn" title="<?php echo translate('Pause') ?>" class="inactive" data-on-click-true="streamCmdPause">
|
||||
<i class="material-icons md-18">pause</i>
|
||||
</button>
|
||||
<button type="button" id="stopBtn" title="<?php echo translate('Stop') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdStop" style="display:none;">
|
||||
<i class="material-icons md-18">stop</i>
|
||||
</button>
|
||||
<button type="button" id="playBtn" title="<?php echo translate('Play') ?>" class="active" disabled="disabled" data-on-click-true="streamCmdPlay">
|
||||
<i class="material-icons md-18">play_arrow</i>
|
||||
</button>
|
||||
<?php
|
||||
if ( $monitor->StreamReplayBuffer() != 0 ) {
|
||||
if ($monitor->StreamReplayBuffer() != 0) {
|
||||
?>
|
||||
<button type="button" id="slowFwdBtn" title="<?php echo translate('StepForward') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdSlowFwd">
|
||||
<i class="material-icons md-18">chevron_right</i>
|
||||
</button>
|
||||
<button type="button" id="fastFwdBtn" title="<?php echo translate('FastForward') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdFastFwd">
|
||||
<i class="material-icons md-18">fast_forward</i>
|
||||
</button>
|
||||
<button type="button" id="slowFwdBtn" title="<?php echo translate('StepForward') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdSlowFwd">
|
||||
<i class="material-icons md-18">chevron_right</i>
|
||||
</button>
|
||||
<button type="button" id="fastFwdBtn" title="<?php echo translate('FastForward') ?>" class="unavail" disabled="disabled" data-on-click-true="streamCmdFastFwd">
|
||||
<i class="material-icons md-18">fast_forward</i>
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<button type="button" id="zoomOutBtn" title="<?php echo translate('ZoomOut') ?>" class="avail" data-on-click="streamCmdZoomOut">
|
||||
<i class="material-icons md-18">zoom_out</i>
|
||||
</button>
|
||||
<button type="button" id="fullscreenBtn" title="<?php echo translate('Fullscreen') ?>" class="avail" data-on-click="watchFullscreen">
|
||||
<i class="material-icons md-18">fullscreen</i>
|
||||
</button>
|
||||
<button type="button" id="zoomOutBtn" title="<?php echo translate('ZoomOut') ?>" class="avail" data-on-click="streamCmdZoomOut">
|
||||
<i class="material-icons md-18">zoom_out</i>
|
||||
</button>
|
||||
<button type="button" id="fullscreenBtn" title="<?php echo translate('Fullscreen') ?>" class="avail" data-on-click="watchFullscreen">
|
||||
<i class="material-icons md-18">fullscreen</i>
|
||||
</button>
|
||||
<?php
|
||||
} // end if streamMode==jpeg
|
||||
?>
|
||||
</div>
|
||||
<div id="replayStatus"<?php echo $streamMode=="single" ? ' class="hidden"' : '' ?>>
|
||||
<span id="mode"><?php echo translate('Mode') ?>: <span id="modeValue"></span></span>
|
||||
<span id="rate"><?php echo translate('Rate') ?>: <span id="rateValue"></span>x</span>
|
||||
<span id="delay"><?php echo translate('Delay') ?>: <span id="delayValue"></span>s</span>
|
||||
<span id="level"><?php echo translate('Buffer') ?>: <span id="levelValue"></span>%</span>
|
||||
<span id="zoom"><?php echo translate('Zoom') ?>: <span id="zoomValue"></span>x</span>
|
||||
</div><!--dvrButtons-->
|
||||
</div>
|
||||
<?php } // end if $monitor->Type() != 'WebSite' ?>
|
||||
<?php
|
||||
|
@ -208,6 +361,7 @@ if ( canView('Events') && ($monitor->Type() != 'WebSite') ) {
|
|||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
if ( ZM_WEB_SOUND_ON_ALARM ) {
|
||||
|
|
Loading…
Reference in New Issue