Merge ../ZoneMinder.master

This commit is contained in:
Isaac Connor 2018-04-26 21:58:01 -04:00
commit a35412f71d
23 changed files with 406 additions and 234 deletions

View File

@ -63,7 +63,7 @@ DROP TABLE IF EXISTS `Controls`;
CREATE TABLE `Controls` (
`Id` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(64) NOT NULL default '',
`Type` enum('Local','Remote','Ffmpeg','Libvlc','cURL') NOT NULL default 'Local',
`Type` enum('Local','Remote','Ffmpeg','Libvlc','cURL','WebSite') NOT NULL default 'Local',
`Protocol` varchar(64) default NULL,
`CanWake` tinyint(3) unsigned NOT NULL default '0',
`CanSleep` tinyint(3) unsigned NOT NULL default '0',

24
db/zm_update-1.31.43.sql Normal file
View File

@ -0,0 +1,24 @@
--
-- This updates a 1.31.42 database to 1.31.43
--
-- Add WebSite enum to Monitor.Type
-- Add Refresh column to Monitors table
--
ALTER TABLE `zm`.`Monitors`
CHANGE COLUMN `Type` `Type` ENUM('Local', 'Remote', 'File', 'Ffmpeg', 'Libvlc', 'cURL', 'WebSite') NOT NULL DEFAULT 'Local' ;
SET @s = (SELECT IF(
(SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Monitors'
AND table_schema = DATABASE()
AND column_name = 'Refresh'
) > 0,
"SELECT 'Column Refresh exists in Monitors'",
"ALTER TABLE Monitors ADD `Refresh` int(10) unsigned default NULL"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -26,7 +26,7 @@
%global _hardened_build 1
Name: zoneminder
Version: 1.31.42
Version: 1.31.43
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons

View File

@ -147,6 +147,23 @@ Keep aspect ratio
Orientation
As per local devices.
WebSite
^^^^^^^
This Source Type allows one to configure an arbitrary website as a non-reocrdable, fully interactive, monitor in ZoneMinder. Note that sites with self-signed certificates will not display until the end user first manually navigates to the site and accpets the unsigned certificate. Also note that some sites will set an X-Frame option in the header, which discourages their site from being displayed within a frame. ZoneMinder will detect this condition and present a warning in the log. When this occurs, the end user can choose to install a browser plugin or extension to workaround this issue.
Website URL
Enter the full http or https url to the desired website.
Width (pixels)
Chose a desired width in pixels that gives an acceptable appearance. This may take some expirimentation.
Height (pixels)
Chose a desired height in pixels that gives an acceptable appearance. This may take some expirimentation.
Web Site Refresh
If the website in question has static content, optionally enter a time period in seconds for ZoneMinder to refresh the content.
Timestamp Tab
-------------

View File

@ -2946,6 +2946,23 @@ our @options = (
type => $types{boolean},
category => 'web',
},
{
name => 'ZM_WEB_XFRAME_WARN',
default => 'yes',
description => 'Warn when website X-Frame-Options is set to sameorigin',
help => q`
When creating a Web Site monitor, if the target web site has
X-Frame-Options set to sameorigin in the header, the site will
not display in ZoneMinder. This is a design feature in most modern
browsers. When this condiction has occured, ZoneMinder will write a
warning to the log file. To get around this, one can install a browser
plugin or extension to ignore X-Frame headers, and then the page will
display properly. Once the plugin or extenstion has ben installed,
the end user may choose to turn this warning off.
`,
type => $types{boolean},
category => 'web',
},
{
name => 'ZM_WEB_H_REFRESH_MAIN',
default => '60',

View File

@ -211,7 +211,7 @@ if ( $command =~ /^(?:start|restart)$/ ) {
my $res = $sth->execute( @values )
or Fatal( "Can't execute: ".$sth->errstr() );
while( my $monitor = $sth->fetchrow_hashref() ) {
if ( $monitor->{Function} ne 'None' ) {
if ( $monitor->{Function} ne 'None' && $monitor->{Type} ne 'WebSite' ) {
if ( $monitor->{Type} eq 'Local' ) {
runCommand( "zmdc.pl start zmc -d $monitor->{Device}" );
} else {

View File

@ -84,6 +84,7 @@ while( 1 ) {
while( my $monitor = $sth->fetchrow_hashref() ) {
my $now = time();
next if $monitor->{Function} eq 'None';
next if $monitor->{Type} eq 'WebSite';
my $restart = 0;
if ( zmMemVerify( $monitor ) ) {
# Check we have got an image recently

View File

@ -1 +1 @@
1.31.42
1.31.43

View File

@ -299,10 +299,12 @@ if ( isset($_REQUEST['object']) and $_REQUEST['object'] == 'Monitor' ) {
continue;
}
$Monitor = new Monitor( $mid );
if ( $Monitor->Type() != 'WebSite' ) {
$Monitor->zmaControl('stop');
$Monitor->zmcControl('stop');
}
$Monitor->save( $_REQUEST['newMonitor'] );
if ($Monitor->Function() != 'None' ) {
if ($Monitor->Function() != 'None' && $Monitor->Type() != 'WebSite' ) {
$Monitor->zmcControl('start');
if ( $Monitor->Enabled() ) {
$Monitor->zmaControl('start');
@ -330,7 +332,7 @@ if ( !empty($_REQUEST['mid']) && canEdit( 'Monitors', $_REQUEST['mid'] ) ) {
$monitor['Function'] = $newFunction;
$monitor['Enabled'] = $newEnabled;
if ( daemonCheck() ) {
if ( daemonCheck() && $monitor['Type'] != 'WebSite' ) {
$restart = ($oldFunction == 'None') || ($newFunction == 'None') || ($newEnabled != $oldEnabled);
zmaControl( $monitor, 'stop' );
zmcControl( $monitor, $restart?'restart':'' );
@ -371,7 +373,7 @@ if ( !empty($_REQUEST['mid']) && canEdit( 'Monitors', $_REQUEST['mid'] ) ) {
} else {
dbQuery( 'INSERT INTO Zones SET MonitorId=?, '.implode( ', ', $changes ), array( $mid ) );
}
if ( daemonCheck() ) {
if ( daemonCheck() && $monitor['Type'] != 'WebSite' ) {
if ( $_REQUEST['newZone']['Type'] == 'Privacy' ) {
zmaControl( $monitor, 'stop' );
zmcControl( $monitor, 'restart' );
@ -399,7 +401,7 @@ if ( !empty($_REQUEST['mid']) && canEdit( 'Monitors', $_REQUEST['mid'] ) ) {
}
}
if($changes>0) {
if ( daemonCheck() ) {
if ( daemonCheck() && $monitor['Type'] != 'WebSite' ) {
zmaControl( $mid, 'restart' );
}
$refreshParent = true;
@ -424,7 +426,7 @@ if ( !empty($_REQUEST['mid']) && canEdit( 'Monitors', $_REQUEST['mid'] ) ) {
$deletedZid = 1;
}
if ( $deletedZid ) {
if ( daemonCheck() ) {
if ( daemonCheck() && $monitor['Type'] != 'WebSite' ) {
if ( $zone['Type'] == 'Privacy' ) {
zmaControl( $mid, 'stop' );
zmcControl( $mid, 'restart' );
@ -492,8 +494,10 @@ if ( canEdit( 'Monitors' ) ) {
if ( $mid ) {
# If we change anything that changes the shared mem size, zma can complain. So let's stop first.
if ( $monitor['Type'] != 'WebSite' ) {
zmaControl( $monitor, 'stop' );
zmcControl( $monitor, 'stop' );
}
dbQuery( 'UPDATE Monitors SET '.implode( ', ', $changes ).' WHERE Id=?', array($mid) );
// Groups will be added below
if ( isset($changes['Name']) or isset($changes['StorageId']) ) {
@ -606,8 +610,10 @@ if ( canEdit( 'Monitors' ) ) {
$new_monitor = new Monitor($mid);
//fixDevices();
if ( $monitor['Type'] != 'WebSite' ) {
$new_monitor->zmcControl('start');
$new_monitor->zmaControl('start');
}
if ( $new_monitor->Controllable() ) {
require_once( 'control_functions.php' );

View File

@ -280,6 +280,27 @@ function getImageStill( $id, $src, $width, $height, $title='' ) {
return '<img id="'.$id.'" src="'.$src.'" alt="'.$title.'"'.(validInt($width)?' width="'.$width.'"':'').(validInt($height)?' height="'.$height.'"':'').'/>';
}
function getWebSiteUrl( $id, $src, $width, $height, $title='' ) {
# Prevent unsightly warnings when php cannot verify the ssl certificate
stream_context_set_default( [
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
]);
# The End User can turn off the following warning under Options -> Web
if ( ZM_WEB_XFRAME_WARN ) {
$header = get_headers($src, 1);
# If the target website has set X-Frame-Options, check it for "sameorigin" and warn the end user
if (array_key_exists('X-Frame-Options', $header)) {
$header = $header['X-Frame-Options'];
if ( stripos($header, 'sameorigin') === 0 )
Warning("Web site $src has X-Frame-Options set to sameorigin. An X-Frame-Options browser plugin is required to display this site.");
}
}
return '<object id="'.$id.'" data="'.$src.'" alt="'.$title.'" width="'.$width.'" height="'.$height.'"></object>';
}
function outputControlStill( $src, $width, $height, $monitor, $scale, $target ) {
?>
<form name="ctrlForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>" target="<?php echo $target ?>">
@ -486,7 +507,7 @@ function getFormChanges( $values, $newValues, $types=false, $columns=false ) {
$types = array();
foreach( $newValues as $key=>$value ) {
if ( $columns && !$columns[$key] )
if ( $columns && !isset($columns[$key]) )
continue;
if ( !isset($types[$key]) )
@ -496,10 +517,10 @@ function getFormChanges( $values, $newValues, $types=false, $columns=false ) {
case 'set' :
{
if ( is_array($newValues[$key]) ) {
if ( join(',',$newValues[$key]) != $values[$key] ) {
if ( (!isset($values[$key])) or ( join(',',$newValues[$key]) != $values[$key] ) ) {
$changes[$key] = "`$key` = ".dbEscape(join(',',$newValues[$key]));
}
} elseif ( $values[$key] ) {
} else if ( (!isset($values[$key])) or $values[$key] ) {
$changes[$key] = "`$key` = ''";
}
break;
@ -548,7 +569,7 @@ function getFormChanges( $values, $newValues, $types=false, $columns=false ) {
}
case 'raw' :
{
if ( $values[$key] != $value ) {
if ( (!isset($values[$key])) or ($values[$key] != $value) ) {
$changes[$key] = $key . ' = '.dbEscape($value);
}
break;
@ -2128,8 +2149,14 @@ function getStreamHTML( $monitor, $options = array() ) {
$options['buffer'] = $monitor->StreamReplayBuffer();
//Warning("width: " . $options['width'] . ' height: ' . $options['height']. ' scale: ' . $options['scale'] );
if ( $monitor->Type() == "WebSite" ) {
return getWebSiteUrl( 'liveStream'.$monitor->Id(), $monitor->Path(),
( isset($options['width']) ? $options['width'] : NULL ),
( isset($options['height']) ? $options['height'] : NULL ),
$monitor->Name()
);
//FIXME, the width and height of the image need to be scaled.
if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
} else if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
$streamSrc = $monitor->getStreamSrc( array(
'mode'=>'mpeg',
'scale'=>(isset($options['scale'])?$options['scale']:100),

View File

@ -174,8 +174,10 @@ $SLANG = array(
'BadSectionLength' => 'Section length must be an integer of 30 or more',
'BadSignalCheckColour' => 'Signal check colour must be a valid RGB colour string',
'BadStreamReplayBuffer' => 'Stream replay buffer must be an integer of zero or more',
'BadSourceType' => 'Source Type \"Web Site\" requires the Function to be set to \"Monitor\"',
'BadWarmupCount' => 'Warmup frames must be an integer of zero or more',
'BadWebColour' => 'Web colour must be a valid web colour string',
'BadWebSitePath' => 'Please enter a complete website url, including the http:// or https:// prefix.',
'BadWidth' => 'Width must be set to a valid value',
'Bandwidth' => 'Bandwidth',
'BandwidthHead' => 'Bandwidth', // This is the end of the bandwidth status on the top of the console, different in many language due to phrasing
@ -768,6 +770,7 @@ $SLANG = array(
'Watch' => 'Watch',
'WebColour' => 'Web Colour',
'Web' => 'Web',
'WebSiteUrl' => 'Website URL',
'Week' => 'Week',
'WhiteBalance' => 'White Balance',
'White' => 'White',

View File

@ -110,6 +110,9 @@ $status_counts = array();
for ( $i = 0; $i < count($displayMonitors); $i++ ) {
$monitor = &$displayMonitors[$i];
if ( ! $monitor['Status'] ) {
if ( $monitor['Type'] == 'WebSite' )
$monitor['Status'] = 'Running';
else
$monitor['Status'] = 'NotRunning';
}
if ( !isset($status_counts[$monitor['Status']]) )
@ -220,7 +223,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
?>
<tr id="<?php echo 'monitor_id-'.$monitor['Id'] ?>" title="<?php echo $monitor['Id'] ?>">
<?php
if ( (!$monitor['Status']) or ($monitor['Status'] == 'NotRunning') ) {
if ( (!$monitor['Status'] || $monitor['Status'] == 'NotRunning') && $monitor['Type']!='WebSite' ) {
$source_class = 'errorText';
} else {
if ( $monitor['CaptureFPS'] == '0.00' ) {
@ -238,7 +241,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
if ( !$monitor['Enabled'] )
$fclass .= ' disabledText';
$scale = max( reScale( SCALE_BASE, $monitor['DefaultScale'], ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
$stream_available = canView('Stream') && $monitor['CaptureFPS'] && $monitor['Function'] != 'None';
$stream_available = canView('Stream') and $monitor['Type']=='WebSite' or ($monitor['CaptureFPS'] && $monitor['Function'] != 'None');
$dot_class=$source_class;
if ( $fclass != 'infoText' ) $dot_class=$fclass;
@ -293,7 +296,7 @@ if ( $fclass != 'infoText' ) $dot_class=$fclass;
}
} elseif ( $monitor['Type'] == 'File' || $monitor['Type'] == 'cURL' ) {
$source = preg_replace( '/^.*\//', '', $monitor['Path'] );
} elseif ( $monitor['Type'] == 'Ffmpeg' || $monitor['Type'] == 'Libvlc' ) {
} elseif ( $monitor['Type'] == 'Ffmpeg' || $monitor['Type'] == 'Libvlc' || $monitor['Type'] == 'WebSite' ) {
$url_parts = parse_url( $monitor['Path'] );
unset($url_parts['user']);
unset($url_parts['pass']);

View File

@ -54,14 +54,6 @@ function validateForm( form ) {
else if ( monitorNames[form.elements['newMonitor[Name]'].value] )
errors[errors.length] = "<?php echo translate('DuplicateMonitorName') ?>";
if ( form.elements['newMonitor[AnalysisFPSLimit]'].value && !(parseFloat(form.elements['newMonitor[AnalysisFPSLimit]'].value) > 0 ) )
errors[errors.length] = "<?php echo translate('BadAnalysisFPS') ?>";
if ( form.elements['newMonitor[MaxFPS]'].value && !(parseFloat(form.elements['newMonitor[MaxFPS]'].value) > 0 ) )
errors[errors.length] = "<?php echo translate('BadMaxFPS') ?>";
if ( form.elements['newMonitor[AlarmMaxFPS]'].value && !(parseFloat(form.elements['newMonitor[AlarmMaxFPS]'].value) > 0 ) )
errors[errors.length] = "<?php echo translate('BadAlarmMaxFPS') ?>";
if ( !form.elements['newMonitor[RefBlendPerc]'].value || (parseInt(form.elements['newMonitor[RefBlendPerc]'].value) > 100 ) || (parseInt(form.elements['newMonitor[RefBlendPerc]'].value) < 0 ) )
errors[errors.length] = "<?php echo translate('BadRefBlendPerc') ?>";
if ( form.elements['newMonitor[Type]'].value == 'Local' ) {
if ( !form.elements['newMonitor[Palette]'].value || !form.elements['newMonitor[Palette]'].value.match( /^\d+$/ ) )
errors[errors.length] = "<?php echo translate('BadPalette') ?>";
@ -81,7 +73,24 @@ function validateForm( form ) {
} else if ( form.elements['newMonitor[Type]'].value == 'File' ) {
if ( !form.elements['newMonitor[Path]'].value )
errors[errors.length] = "<?php echo translate('BadPath') ?>";
} else if ( form.elements['newMonitor[Type]'].value == 'WebSite' ) {
if ( form.elements['newMonitor[Function]'].value != 'Monitor' && form.elements['newMonitor[Function]'].value != 'None')
errors[errors.length] = "<?php echo translate('BadSourceType') ?>";
if ( form.elements['newMonitor[Path]'].value.search(/^https?:\/\//i) )
errors[errors.length] = "<?php echo translate('BadWebSitePath') ?>";
}
if ( form.elements['newMonitor[Type]'].value != 'WebSite' ) {
if ( form.elements['newMonitor[AnalysisFPSLimit]'].value && !(parseFloat(form.elements['newMonitor[AnalysisFPSLimit]'].value) > 0 ) )
errors[errors.length] = "<?php echo translate('BadAnalysisFPS') ?>";
if ( form.elements['newMonitor[MaxFPS]'].value && !(parseFloat(form.elements['newMonitor[MaxFPS]'].value) > 0 ) )
errors[errors.length] = "<?php echo translate('BadMaxFPS') ?>";
if ( form.elements['newMonitor[AlarmMaxFPS]'].value && !(parseFloat(form.elements['newMonitor[AlarmMaxFPS]'].value) > 0 ) )
errors[errors.length] = "<?php echo translate('BadAlarmMaxFPS') ?>";
if ( !form.elements['newMonitor[RefBlendPerc]'].value || (parseInt(form.elements['newMonitor[RefBlendPerc]'].value) > 100 ) || (parseInt(form.elements['newMonitor[RefBlendPerc]'].value) < 0 ) )
errors[errors.length] = "<?php echo translate('BadRefBlendPerc') ?>";
if ( !form.elements['newMonitor[Colours]'].value || (parseInt(form.elements['newMonitor[Colours]'].value) != 1 && parseInt(form.elements['newMonitor[Colours]'].value) != 3 && parseInt(form.elements['newMonitor[Colours]'].value) != 4 ) )
errors[errors.length] = "<?php echo translate('BadColours') ?>";
if ( !form.elements['newMonitor[Width]'].value || !(parseInt(form.elements['newMonitor[Width]'].value) > 0 ) )
@ -120,6 +129,8 @@ function validateForm( form ) {
if ( !form.elements['newMonitor[WebColour]'].value || !form.elements['newMonitor[WebColour]'].value.match( /^[#0-9a-zA-Z]+$/ ) )
errors[errors.length] = "<?php echo translate('BadWebColour') ?>";
}
if ( errors.length ) {
alert( errors.join( "\n" ) );
return( false );

View File

@ -12,6 +12,15 @@ function Monitor( monitorData ) {
if ( auth_hash )
this.streamCmdParms += '&auth='+auth_hash;
this.streamCmdTimer = null;
this.type = monitorData.type;
this.refresh = monitorData.refresh;
this.start = function( delay ) {
if ( this.streamCmdQuery )
this.streamCmdTimer = this.streamCmdQuery.delay( delay, this );
else
console.log("No streamCmdQuery");
};
this.setStateClass = function( element, stateClass ) {
if ( !element.hasClass( stateClass ) ) {
@ -68,7 +77,7 @@ function Monitor( monitorData ) {
else
stateClass = "idle";
if ( !COMPACT_MONTAGE ) {
if ( (!COMPACT_MONTAGE) && (this.type != 'WebSite') ) {
$('fpsValue'+this.id).set( 'text', this.status.fps );
$('stateValue'+this.id).set( 'text', stateStrings[this.alarmState] );
this.setStateClass( $('monitorState'+this.id), stateClass );
@ -137,9 +146,12 @@ function Monitor( monitorData ) {
this.streamCmdReq.cancel();
}
//console.log("Starting CmdQuery for " + this.connKey );
if ( this.type != 'WebSite' ) {
this.streamCmdReq.send( this.streamCmdParms+"&command="+CMD_QUERY );
}
};
if ( this.type != 'WebSite' ) {
this.streamCmdReq = new Request.JSON( {
url: this.server_url,
method: 'get',
@ -150,11 +162,12 @@ function Monitor( monitorData ) {
onFailure: this.onFailure.bind(this),
link: 'cancel'
} );
console.log("queueing for " + this.id + " " + this.connKey );
requestQueue.addRequest( "cmdReq"+this.id, this.streamCmdReq );
}
}
function selectLayout( element ) {
layout = $j(element).val();
@ -378,15 +391,26 @@ function cancel_layout(button) {
selectLayout('#zmMontageLayout');
}
function reloadWebSite(ndx) {
document.getElementById('imageFeed'+ndx).innerHTML = document.getElementById('imageFeed'+ndx).innerHTML;
}
var monitors = new Array();
function initPage() {
console.log("initPage");
for ( var i = 0; i < monitorData.length; i++ ) {
monitors[i] = new Monitor(monitorData[i]);
var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout );
var interval = monitors[i].refresh;
monitors[i].start( delay );
if ( monitors[i].type == 'WebSite' && interval > 0 ) {
setInterval(reloadWebSite, interval*1000, i);
}
}
selectLayout('#zmMontageLayout');
for ( var i = 0; i < monitorData.length; i++ ) {
if ( monitors[i].type == 'WebSite' )
continue;
var delay = Math.round( (Math.random()+0.75)*statusRefreshTimeout );
console.log("Delay for monitor " + monitorData[i].id + " is " + delay );
monitors[i].streamCmdQuery.delay( delay, monitors[i] );

View File

@ -36,7 +36,9 @@ monitorData[monitorData.length] = {
'width': <?php echo $monitor->Width() ?>,
'height':<?php echo $monitor->Height() ?>,
'server_url': '<?php echo $monitor->Server()->Url().$_SERVER['PHP_SELF'] ?>',
'onclick': function(){createPopup( '?view=watch&mid=<?php echo $monitor->Id() ?>', 'zmWatch<?php echo $monitor->Id() ?>', 'watch', <?php echo reScale( $monitor->Width(), $monitor->PopupScale() ); ?>, <?php echo reScale( $monitor->Height(), $monitor->PopupScale() ); ?> );}
'onclick': function(){createPopup( '?view=watch&mid=<?php echo $monitor->Id() ?>', 'zmWatch<?php echo $monitor->Id() ?>', 'watch', <?php echo reScale( $monitor->Width(), $monitor->PopupScale() ); ?>, <?php echo reScale( $monitor->Height(), $monitor->PopupScale() ); ?> );},
'type': '<?php echo $monitor->Type() ?>',
'refresh': '<?php echo $monitor->Refresh() ?>'
};
<?php
} // end foreach monitor

View File

@ -105,6 +105,7 @@ function setAlarmState( currentAlarmState ) {
lastAlarmState = alarmState;
}
if ( monitorType != 'WebSite' ) {
var streamCmdParms = "view=request&request=stream&connkey="+connKey;
if ( auth_hash )
streamCmdParms += '&auth='+auth_hash;
@ -117,6 +118,7 @@ var streamCmdReq = new Request.JSON( {
onFailure: getStreamCmdFailure
} );
var streamCmdTimer = null;
}
var streamStatus;
@ -350,11 +352,13 @@ function streamCmdQuery() {
streamCmdReq.send( streamCmdParms+"&command="+CMD_QUERY );
}
if ( monitorType != 'WebSite' ) {
var statusCmdParms = "view=request&request=status&entity=monitor&id="+monitorId+"&element[]=Status&element[]=FrameRate";
if ( auth_hash )
statusCmdParms += '&auth='+auth_hash;
var statusCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'get', data: statusCmdParms, timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStatusCmdResponse } );
var statusCmdTimer = null;
}
function getStatusCmdResponse( respObj, respText ) {
watchdogOk("status");
@ -377,6 +381,7 @@ function statusCmdQuery() {
statusCmdReq.send();
}
if ( monitorType != 'WebSite' ) {
var alarmCmdParms = "view=request&request=alarm&id="+monitorId;
if ( auth_hash )
alarmCmdParms += '&auth='+auth_hash;
@ -389,6 +394,7 @@ var alarmCmdReq = new Request.JSON( {
onTimeout: streamCmdQuery
} );
var alarmCmdFirst = true;
}
function getAlarmCmdResponse( respObj, respText ) {
checkStreamForErrors("getAlarmCmdResponse", respObj);
@ -428,12 +434,14 @@ function deleteEvent( event, eventId ) {
event.stop();
}
if ( monitorType != 'WebSite' ) {
var eventCmdParms = "view=request&request=status&entity=events&id="+monitorId+"&count="+maxDisplayEvents+"&sort=Id%20desc";
if ( auth_hash )
eventCmdParms += '&auth='+auth_hash;
var eventCmdReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, data: eventCmdParms, link: 'cancel', onSuccess: getEventCmdResponse, onTimeout: eventCmdQuery } );
var eventCmdTimer = null;
var eventCmdFirst = true;
}
function highlightRow( row ) {
$(row).toggleClass( 'highlight' );
@ -536,10 +544,12 @@ function eventCmdQuery() {
eventCmdReq.send();
}
if ( monitorType != 'WebSite' ) {
var controlParms = "view=request&request=control&id="+monitorId;
if ( auth_hash )
controlParms += '&auth='+auth_hash;
var controlReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getControlResponse } );
}
function getControlResponse( respObj, respText ) {
if ( !respObj )
@ -652,6 +662,7 @@ function watchdogOk( type ) {
}
function initPage() {
if ( monitorType != 'WebSite' ) {
if ( streamMode == "single" ) {
statusCmdTimer = statusCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
watchdogCheck.pass('status').periodical(statusRefreshTimeout*2);
@ -680,6 +691,9 @@ function initPage() {
if (window.history.length == 1) {
$j('#closeControl').html('');
}
} else if ( monitorRefresh > 0 ) {
var myReload = setInterval(reloadWebSite, monitorRefresh*1000);
}
}
// Kick everything off

View File

@ -49,6 +49,8 @@ var monitorId = <?php echo $monitor->Id() ?>;
var monitorWidth = <?php echo $monitor->Width() ?>;
var monitorHeight = <?php echo $monitor->Height() ?>;
var monitorUrl = '<?php echo ( $monitor->Server()->Url() . ( ZM_MIN_STREAMING_PORT ? ':'. (ZM_MIN_STREAMING_PORT+$monitor->Id()) : '' ) ) ?>';
var monitorType = '<?php echo ( $monitor->Type() ) ?>';
var monitorRefresh = '<?php echo ( $monitor->Refresh() ) ?>';
var scale = '<?php echo $scale ?>';

View File

@ -26,23 +26,6 @@ if ( !canView( 'Monitors' ) ) {
return;
}
$tabs = array();
$tabs['general'] = translate('General');
$tabs['source'] = translate('Source');
$tabs['storage'] = translate('Storage');
$tabs['timestamp'] = translate('Timestamp');
$tabs['buffers'] = translate('Buffers');
if ( ZM_OPT_CONTROL && canView( 'Control' ) )
$tabs['control'] = translate('Control');
if ( ZM_OPT_X10 )
$tabs['x10'] = translate('X10');
$tabs['misc'] = translate('Misc');
if ( isset($_REQUEST['tab']) )
$tab = validHtmlStr($_REQUEST['tab']);
else
$tab = 'general';
$Server = null;
if ( defined( 'ZM_SERVER_ID' ) ) {
$Server = dbFetchOne( 'SELECT * FROM Servers WHERE Id=?', NULL, array( ZM_SERVER_ID ) );
@ -142,6 +125,7 @@ if ( ! $monitor ) {
'V4LCapturesPerFrame' => 1,
'ServerId' => 'auto',
'StorageId' => '1',
'Refresh' => '',
) );
} # end if $_REQUEST['dupID']
} # end if $_REQUEST['mid']
@ -212,6 +196,7 @@ $sourceTypes = array(
'Ffmpeg' => translate('Ffmpeg'),
'Libvlc' => translate('Libvlc'),
'cURL' => 'cURL (HTTP(S) only)',
'WebSite'=> 'Web Site',
'NVSocket' => translate('NVSocket')
);
if ( !ZM_HAS_V4L )
@ -507,6 +492,25 @@ if ( canEdit( 'Monitors' ) ) {
<div id="content">
<ul class="tabList">
<?php
$tabs = array();
$tabs['general'] = translate('General');
$tabs['source'] = translate('Source');
if ( $monitor->Type() != 'WebSite' ) {
$tabs['storage'] = translate('Storage');
$tabs['timestamp'] = translate('Timestamp');
$tabs['buffers'] = translate('Buffers');
if ( ZM_OPT_CONTROL && canView( 'Control' ) )
$tabs['control'] = translate('Control');
if ( ZM_OPT_X10 )
$tabs['x10'] = translate('X10');
$tabs['misc'] = translate('Misc');
}
if ( isset($_REQUEST['tab']) )
$tab = validHtmlStr($_REQUEST['tab']);
else
$tab = 'general';
foreach ( $tabs as $name=>$value ) {
if ( $tab == $name ) {
?>
@ -578,7 +582,7 @@ if ( $tab != 'source' || ($monitor->Type()!= 'Ffmpeg' && $monitor->Type()!= 'Lib
<input type="hidden" name="newMonitor[Options]" value="<?php echo validHtmlStr($monitor->Options()) ?>"/>
<?php
}
if ( $tab != 'source' || ($monitor->Type()!= 'Remote' && $monitor->Type()!= 'File' && $monitor->Type()!= 'Ffmpeg' && $monitor->Type()!= 'Libvlc' && $monitor->Type()!= 'cURL') ) {
if ( $tab != 'source' || ($monitor->Type()!= 'Remote' && $monitor->Type()!= 'File' && $monitor->Type()!= 'Ffmpeg' && $monitor->Type()!= 'Libvlc' && $monitor->Type()!= 'cURL' && $monitor->Type() != 'WebSite') ) {
?>
<input type="hidden" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/>
<input type="hidden" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>"/>
@ -708,6 +712,9 @@ switch ( $tab ) {
?>
</select></td></tr>
<tr><td><?php echo translate('Enabled') ?></td><td><input type="checkbox" name="newMonitor[Enabled]" value="1"<?php if ( $monitor->Enabled() ) { ?> checked="checked"<?php } ?>/></td></tr>
<?php
if ( $monitor->Type != 'WebSite' ) {
?>
<tr>
<td><?php echo translate('LinkedMonitors') ?></td>
<td>
@ -797,6 +804,7 @@ echo htmlOptions(Group::get_dropdown_options( ), $monitor->GroupIds() );
?>
</td></tr>
<?php
}
break;
}
case 'source' :
@ -863,6 +871,13 @@ include('_monitor_source_nvsocket.php');
<tr><td><?php echo 'URL' ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
<tr><td><?php echo 'Username' ?></td><td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>" size="12"/></td></tr>
<tr><td><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>" size="12"/></td></tr>
<?php
} elseif ( $monitor->Type() == 'WebSite' ) {
?>
<tr><td><?php echo translate('WebSiteUrl') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
<tr><td><?php echo translate('Width') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" size="4";"/></td></tr>
<tr><td><?php echo translate('Height') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" size="4";"/></td></tr>
<tr><td><?php echo 'Web Site Refresh (Optional)' ?></td><td><input type="number" name="newMonitor[Refresh]" value="<?php echo $monitor->Refresh()?>"/></td></tr>
<?php
} elseif ( $monitor->Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) {
?>
@ -871,7 +886,7 @@ include('_monitor_source_nvsocket.php');
<tr><td><?php echo translate('Options') ?>&nbsp;(<?php echo makePopupLink( '?view=optionhelp&amp;option=OPTIONS_'.strtoupper($monitor->Type()), 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td><td><input type="text" name="newMonitor[Options]" value="<?php echo validHtmlStr($monitor->Options()) ?>" size="36"/></td></tr>
<?php
}
if ( $monitor->Type() != 'NVSocket' ) {
if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
?>
<tr><td><?php echo translate('TargetColorspace') ?></td><td><?php echo htmlSelect('newMonitor[Colours]', $Colours, $monitor->Colours() ); ?>
</td></tr>
@ -885,7 +900,7 @@ if ( $monitor->Type() == 'Local' ) {
?>
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
<?php
} else {
} else if ( $monitor->Type() != 'WebSite' ) {
?>
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
<?php

View File

@ -204,7 +204,11 @@ foreach ( $monitors as $monitor ) {
}
}
if ( $monitor->Type() == "WebSite" ) {
echo getWebSiteUrl( 'liveStream'.$monitor->Id(), $monitor->Path(), reScale( $monitor->Width(), $scale ), reScale( $monitor->Height(), $scale ), $monitor->Name() );
} else {
echo getStreamHTML( $monitor, $monitor_options );
}
if ( $showZones ) {
$height = null;
$width = null;
@ -255,7 +259,7 @@ foreach ( $monitors as $monitor ) {
<?php } # end if showZones ?>
</div>
<?php
if ( !ZM_WEB_COMPACT_MONTAGE ) {
if ( (!ZM_WEB_COMPACT_MONTAGE) && ($monitor->Type() != 'WebSite') ) {
?>
<div id="monitorState<?php echo $monitor->Id() ?>" class="monitorState idle"><?php echo translate('State') ?>:&nbsp;<span id="stateValue<?php echo $monitor->Id() ?>"></span>&nbsp;-&nbsp;<span id="fpsValue<?php echo $monitor->Id() ?>"></span>&nbsp;fps</div>
<?php

View File

@ -207,7 +207,7 @@ $frameSql .= ' ORDER BY Id DESC';
$monitors = array();
foreach( $displayMonitors as $row ) {
if ( $row['Function'] == 'None' )
if ( $row['Function'] == 'None' || $row['Type'] == 'WebSite' )
continue;
$Monitor = new Monitor( $row );
$monitors[] = $Monitor;

View File

@ -41,7 +41,7 @@ if ( ! visibleMonitor( $mid ) ) {
$monitor = new Monitor( $mid );
#Whether to show the controls button
$showPtzControls = ( ZM_OPT_CONTROL && $monitor->Controllable() && canView( 'Control' ) );
$showPtzControls = ( ZM_OPT_CONTROL && $monitor->Controllable() && canView('Control') && $monitor->Type() != 'WebSite' );
if ( isset( $_REQUEST['scale'] ) ) {
$scale = validInt($_REQUEST['scale']);
@ -80,6 +80,7 @@ if ( canView( 'Control' ) && $monitor->Type() == 'Local' ) {
</div>
<div id="content">
<div id="imageFeed"><?php echo getStreamHTML( $monitor, array('scale'=>$scale) ); ?></div>
<?php if ( $monitor->Type() != 'WebSite' ) { ?>
<div id="monitorStatus">
<?php if ( canEdit( 'Monitors' ) ) { ?>
<div id="enableDisableAlarms"><a id="enableAlarmsLink" href="#" onclick="cmdEnableAlarms(); return( false );" class="hidden"><?php echo translate('EnableAlarms') ?></a><a id="disableAlarmsLink" href="#" onclick="cmdDisableAlarms(); return( false );" class="hidden"><?php echo translate('DisableAlarms') ?></a></div>
@ -129,6 +130,7 @@ if ( $streamMode == 'jpeg' ) {
<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>
<?php } // end if $monitor->Type() != 'WebSite' ?>
<?php
if ( $showPtzControls ) {
foreach ( getSkinIncludes( 'includes/control_functions.php' ) as $includeFile )
@ -139,7 +141,7 @@ if ( $showPtzControls ) {
</div>
<?php
}
if ( canView( 'Events' ) ) {
if ( canView( 'Events' ) && $monitor->Type() != 'WebSite' ) {
?>
<div id="events">
<table id="eventList" cellspacing="0">