Merge branch 'master' into storageareas

This commit is contained in:
Isaac Connor 2018-12-14 10:16:08 -05:00
commit 0bfe1007c8
21 changed files with 164 additions and 69 deletions

27
.github/support.yml vendored Normal file
View File

@ -0,0 +1,27 @@
# Configuration for support-requests - https://github.com/dessant/support-requests
# Label used to mark issues as support requests
supportLabel: support
# Comment to post on issues marked as support requests, `{issue-author}` is an
# optional placeholder. Set to `false` to disable
supportComment: >
:wave: @{issue-author}, we use the issue tracker exclusively for bug reports.
However, this issue appears to be a support request, a feature request, or
attempts to ask a question.
Please use our support channels to get help with or discuss this project:
- The [ZoneMinder-Chat Slack channel](https://zoneminder-chat.herokuapp.com/)
- The [ZoneMinder Forum](https://forums.zoneminder.com/)
# Close issues marked as support requests
close: true
# Lock issues marked as support requests
lock: true
# Assign `off-topic` as the reason for locking. Set to `false` to disable
setLockReason: true
# Repository to extend settings from
# _extends: repo

View File

@ -127,7 +127,8 @@ mark_as_advanced(
ZM_PATH_ARP
ZM_CONFIG_DIR
ZM_CONFIG_SUBDIR
ZM_SYSTEMD)
ZM_SYSTEMD
ZM_MANPAGE_DEST_PREFIX)
set(ZM_RUNDIR "/var/run/zm" CACHE PATH
"Location of transient process files, default: /var/run/zm")
@ -210,6 +211,10 @@ set(ZM_TARGET_DISTRO "" CACHE STRING
"Build ZoneMinder for a specific distribution. Currently, valid names are: fc27, fc26, el7, OS13, FreeBSD")
set(ZM_SYSTEMD "OFF" CACHE BOOL
"Set to ON to force building ZM with systemd support. default: OFF")
set(ZM_MANPAGE_DEST_PREFIX "share/man" CACHE PATH
"Relative path used to install ZoneMinder's Man pages into a
non-standard folder. Most Linux users will not need to change this.
BSD users may need to set this.")
# Reassign some variables if a target distro has been specified
if((ZM_TARGET_DISTRO MATCHES "^el") OR (ZM_TARGET_DISTRO MATCHES "^fc"))

View File

@ -21,7 +21,7 @@
# To use it, include this file in CMakeLists.txt and
# invoke POD2MAN(<podfile> <manfile> <section>)
MACRO(POD2MAN PODFILE MANFILE SECTION)
MACRO(POD2MAN PODFILE MANFILE SECTION MANPAGE_DEST_PREFIX)
FIND_PROGRAM(POD2MAN pod2man)
FIND_PROGRAM(GZIP gzip)
@ -58,9 +58,9 @@ MACRO(POD2MAN PODFILE MANFILE SECTION)
INSTALL(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${MANFILE}.${SECTION}.gz
DESTINATION share/man/man${SECTION}
DESTINATION ${MANPAGE_DEST_PREFIX}/man${SECTION}
)
ENDMACRO(POD2MAN PODFILE MANFILE SECTION)
ENDMACRO(POD2MAN PODFILE MANFILE SECTION MANPAGE_DEST_PREFIX)
MACRO(ADD_MANPAGE_TARGET)
# It is not possible add a dependency to target 'install'

View File

@ -496,7 +496,6 @@ CREATE TABLE `Monitors` (
`TrackDelay` smallint(5) unsigned,
`ReturnLocation` tinyint(3) NOT NULL default '-1',
`ReturnDelay` smallint(5) unsigned,
`DefaultView` enum('Events','Control') NOT NULL default 'Events',
`DefaultRate` smallint(5) unsigned NOT NULL default '100',
`DefaultScale` smallint(5) unsigned NOT NULL default '100',
`SignalCheckPoints` INT UNSIGNED NOT NULL default '0',

21
db/zm_update-1.33.0.sql Normal file
View File

@ -0,0 +1,21 @@
--
-- This updates a 1.32.3 database to 1.33.0
--
--
-- Remove DefaultView from Monitors table.
--
SET @s = (SELECT IF(
(SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Monitors'
AND table_schema = DATABASE()
AND column_name = 'DefaultView'
) > 0,
"ALTER TABLE Monitors DROP COLUMN DefaultView",
"SELECT 'Column DefaultView no longer exists in Monitors'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -23,7 +23,7 @@
%global _hardened_build 1
Name: zoneminder
Version: 1.32.3
Version: 1.33.0
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
@ -411,6 +411,9 @@ EOF
%dir %attr(755,nginx,nginx) %{_localstatedir}/spool/zoneminder-upload
%changelog
* Tue Dec 11 2018 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.0-1
- Bump tp 1.33.0 Development
* Sat Dec 08 2018 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.32.3-1
- 1.32.3 Release
- Break into sub-packages

View File

@ -32,7 +32,7 @@ configure_file(zm.in "${CMAKE_CURRENT_BINARY_DIR}/zm" @ONLY)
file(GLOB perlscripts "*.pl")
FOREACH(PERLSCRIPT ${perlscripts})
get_filename_component(PERLSCRIPTNAME ${PERLSCRIPT} NAME)
POD2MAN(${PERLSCRIPT} zoneminder-${PERLSCRIPTNAME} 8)
POD2MAN(${PERLSCRIPT} zoneminder-${PERLSCRIPTNAME} 8 ${ZM_MANPAGE_DEST_PREFIX})
ENDFOREACH(PERLSCRIPT ${perlscripts})
# Install the perl scripts

View File

@ -1202,6 +1202,20 @@ our @options = (
category => 'logging',
},
{
name => 'ZM_LOG_FFMPEG',
default => 'yes',
description => 'Log FFMPEG messages',
help => q`
When enabled (default is on), this option will log FFMPEG messages.
FFMPEG messages can be useful when debugging streaming issues. However,
depending on your distro and FFMPEG version, this may also result in
more logs than you'd typically like to see. If all your streams are working
well, you may choose to turn this off.
`,
type => $types{boolean},
category => 'logging',
},
{
name => 'ZM_LOG_DEBUG',
default => 'no',
description => 'Switch debugging on',

View File

@ -310,7 +310,7 @@ sub reinitialise {
# Bit of a nasty hack to reopen connections to log files and the DB
my $syslogLevel = $this->syslogLevel();
$this->syslogLevel( NOLOG );
$this->syslogLevel(NOLOG);
$this->syslogLevel($syslogLevel) if $syslogLevel > NOLOG;
my $logfileLevel = $this->fileLevel();
@ -321,11 +321,10 @@ sub reinitialise {
$this->databaseLevel(NOLOG);
$this->databaseLevel($databaseLevel) if $databaseLevel > NOLOG;
my $screenLevel = $this->termLevel();
$this->{hasTerm} = -t STDERR;
my $termLevel = $this->termLevel();
$this->termLevel(NOLOG);
$this->termLevel($screenLevel) if $screenLevel > NOLOG;
$this->{sth} = undef;
$this->termLevel($termLevel) if $termLevel > NOLOG;
}
# Prevents undefined logging levels
@ -439,16 +438,13 @@ sub databaseLevel {
my $databaseLevel = shift;
if ( defined($databaseLevel) ) {
$databaseLevel = $this->limit($databaseLevel);
if ( $this->{databaseLevel} != $databaseLevel ) {
if ( ( $databaseLevel > NOLOG ) and ( $this->{databaseLevel} <= NOLOG ) ) {
if ( ! ( $ZoneMinder::Database::dbh or ZoneMinder::Database::zmDbConnect() ) ) {
Warning("Failed connecting to db. Not using database logging.");
$this->{databaseLevel} = NOLOG;
return NOLOG;
}
}
$this->{databaseLevel} = $databaseLevel;
if ( $databaseLevel > NOLOG ) {
$this->{dbh} = ZoneMinder::Database::zmDbConnect();
} else {
undef($this->{dbh});
}
$this->{sth} = undef;
$this->{databaseLevel} = $databaseLevel;
}
return $this->{databaseLevel};
}

View File

@ -21,7 +21,7 @@ target_link_libraries(zms zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS})
# Generate man files for the binaries destined for the bin folder
FOREACH(CBINARY zma zmc zmu)
POD2MAN(${CMAKE_CURRENT_SOURCE_DIR}/${CBINARY}.cpp zoneminder-${CBINARY} 8)
POD2MAN(${CMAKE_CURRENT_SOURCE_DIR}/${CBINARY}.cpp zoneminder-${CBINARY} 8 ${ZM_MANPAGE_DEST_PREFIX})
ENDFOREACH(CBINARY zma zmc zmu)
install(TARGETS zmc zma zmu RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

View File

@ -117,6 +117,7 @@ Event::Event(
alarm_frames = 0;
tot_score = 0;
max_score = 0;
alarm_frame_written = false;
char id_file[PATH_MAX];
@ -174,7 +175,7 @@ Event::Event(
Error("Can't mkdir %s: %s", path, strerror(errno));
}
} else {
snprintf(path, sizeof(path), "/%" PRIu64, id);
path_ptr += snprintf(path_ptr, sizeof(path), "/%" PRIu64, id);
if ( mkdir(path, 0755) ) {
if ( errno != EEXIST )
Error("Can't mkdir %s: %s", path, strerror(errno));
@ -563,6 +564,13 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
snprintf(snapshot_file, sizeof(snapshot_file), "%s/snapshot.jpg", path);
WriteFrameImage(image, timestamp, snapshot_file);
}
// The first frame with a score will be the frame that alarmed the event
if (!alarm_frame_written && score > 0) {
alarm_frame_written = true;
char alarm_file[PATH_MAX];
snprintf(alarm_file, sizeof(alarm_file), "%s/alarm.jpg", path);
WriteFrameImage(image, timestamp, alarm_file);
}
}
if ( videowriter != NULL ) {
Debug(3, "Writing video");

View File

@ -86,6 +86,7 @@ class Event {
bool videoEvent;
int frames;
int alarm_frames;
bool alarm_frame_written;
unsigned int tot_score;
unsigned int max_score;
char path[PATH_MAX];

View File

@ -34,15 +34,18 @@ void log_libav_callback( void *ptr, int level, const char *fmt, va_list vargs )
} else if ( level == AV_LOG_FATAL ) { // 8
log_level = Logger::FATAL;
} else if ( level == AV_LOG_ERROR ) { // 16
log_level = Logger::ERROR;
log_level = Logger::WARNING; // ffmpeg outputs a lot of errors that don't really affect anything.
//log_level = Logger::ERROR;
} else if ( level == AV_LOG_WARNING ) { //24
log_level = Logger::WARNING;
} else if ( level == AV_LOG_INFO ) { //32
log_level = Logger::INFO;
} else if ( level == AV_LOG_VERBOSE ) { //40
//log_level = Logger::WARNING;
} else if ( level == AV_LOG_INFO ) { //32
log_level = Logger::DEBUG1;
} else if ( level == AV_LOG_DEBUG ) { //48
//log_level = Logger::INFO;
} else if ( level == AV_LOG_VERBOSE ) { //40
log_level = Logger::DEBUG2;
} else if ( level == AV_LOG_DEBUG ) { //48
log_level = Logger::DEBUG3;
#ifdef AV_LOG_TRACE
} else if ( level == AV_LOG_TRACE ) {
log_level = Logger::DEBUG8;
@ -58,7 +61,6 @@ void log_libav_callback( void *ptr, int level, const char *fmt, va_list vargs )
if ( log ) {
char logString[8192];
vsnprintf(logString, sizeof(logString)-1, fmt, vargs);
log->logPrint(false, __FILE__, __LINE__, log_level, logString);
}
}
@ -71,7 +73,10 @@ void FFMPEGInit() {
av_log_set_level( AV_LOG_DEBUG );
else
av_log_set_level( AV_LOG_QUIET );
av_log_set_callback(log_libav_callback);
if ( config.log_ffmpeg )
av_log_set_callback(log_libav_callback);
else
Info("Not enabling ffmpeg logs, as LOG_FFMPEG is disabled in options");
#if LIBAVCODEC_VERSION_CHECK(58, 18, 0, 64, 0)
#else
av_register_all();

View File

@ -1 +1 @@
1.32.3
1.33.0

View File

@ -62,7 +62,12 @@ class Server {
if ( isset($this->{'Protocol'}) and ( $this->{'Protocol'} != '' ) ) {
return $this->{'Protocol'};
}
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? 'https' : 'http';
return (
( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' )
or
( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and ( $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) )
) ? 'https' : 'http';
}
public function Port( $new = '' ) {
@ -72,6 +77,11 @@ class Server {
if ( isset($this->{'Port'}) and $this->{'Port'} ) {
return $this->{'Port'};
}
if ( isset($_SERVER['HTTP_X_FORWARDED_PORT']) ) {
return $_SERVER['HTTP_X_FORWARDED_PORT'];
}
return $_SERVER['SERVER_PORT'];
}

View File

@ -474,7 +474,8 @@ if ( canEdit('Monitors') ) {
$maxSeq = dbFetchOne('SELECT MAX(Sequence) AS MaxSequence FROM Monitors', 'MaxSequence');
$changes[] = 'Sequence = '.($maxSeq+1);
if ( dbQuery('INSERT INTO Monitors SET '.implode(', ', $changes)) ) {
$sql = 'INSERT INTO Monitors SET '.implode(', ', $changes);
if ( dbQuery($sql) ) {
$mid = dbInsertId();
$zoneArea = $_REQUEST['newMonitor']['Width'] * $_REQUEST['newMonitor']['Height'];
dbQuery("INSERT INTO Zones SET MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, sprintf( "%d,%d %d,%d %d,%d %d,%d", 0, 0, $_REQUEST['newMonitor']['Width']-1, 0, $_REQUEST['newMonitor']['Width']-1, $_REQUEST['newMonitor']['Height']-1, 0, $_REQUEST['newMonitor']['Height']-1 ), $zoneArea, intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*2)/100) ) );
@ -486,6 +487,7 @@ if ( canEdit('Monitors') ) {
} else {
Error('Error saving new Monitor.');
$error_message = dbError($sql);
return;
}
} else {

View File

@ -169,6 +169,7 @@ if ( !is_writable(ZM_DIR_EVENTS) || !is_writable(ZM_DIR_IMAGES) ) {
}
# Globals
$error_message = null;
$redirect = null;
$view = null;
if ( isset($_REQUEST['view']) )

View File

@ -201,6 +201,23 @@ echo output_link_if_exists( array(
<?php
} // end function xhtmlHeaders( $file, $title )
// Outputs an opening body tag, and any additional content that should go at the very top, like warnings and error messages.
function getBodyTopHTML() {
echo '
<body>
<noscript>
<div style="background-color:red;color:white;font-size:x-large;">
'. ZM_WEB_TITLE .' requires Javascript. Please enable Javascript in your browser for this site.
</div>
</noscript>
';
global $error_message;
if ( $error_message ) {
echo '<div class="error">'.$error_message.'</div>';
}
} // end function getBodyTopHTML
function getNavBarHTML($reload = null) {
# Provide a facility to turn off the headers if you put headers=0 into the url
if ( isset($_REQUEST['navbar']) and $_REQUEST['navbar']=='0' )
@ -228,11 +245,6 @@ function getNavBarHTML($reload = null) {
$running = daemonCheck();
$status = $running?translate('Running'):translate('Stopped');
?>
<noscript>
<div style="background-color:red;color:white;font-size:x-large;">
<?php echo ZM_WEB_TITLE ?> requires Javascript. Please enable Javascript in your browser for this site.
</div>
</noscript>
<div class="navbar navbar-inverse navbar-static-top">
<div class="container-fluid">
<div class="navbar-header">

View File

@ -158,8 +158,8 @@ if ( $show_storage_areas ) $left_columns += 1;
xhtmlHeaders( __FILE__, translate('Console') );
getBodyTopHTML();
?>
<body>
<form name="monitorForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="hidden" name="view" value="<?php echo $view ?>"/>
<input type="hidden" name="action" value=""/>

View File

@ -113,7 +113,6 @@ if ( ! $monitor ) {
'FPSReportInterval' => 100,
'RefBlendPerc' => 6,
'AlarmRefBlendPerc' => 6,
'DefaultView' => 'Events',
'DefaultRate' => '100',
'DefaultScale' => '100',
'SignalCheckPoints' => '10',
@ -454,8 +453,8 @@ $savejpegopts = array(
xhtmlHeaders(__FILE__, translate('Monitor')." - ".validHtmlStr($monitor->Name()) );
getBodyTopHTML();
?>
<body>
<div id="page">
<div id="header">
<?php
@ -657,7 +656,6 @@ if ( $tab != 'misc' ) {
<input type="hidden" name="newMonitor[MotionFrameSkip]" value="<?php echo validHtmlStr($monitor->MotionFrameSkip()) ?>"/>
<input type="hidden" name="newMonitor[AnalysisUpdateDelay]" value="<?php echo validHtmlStr($monitor->AnalysisUpdateDelay()) ?>"/>
<input type="hidden" name="newMonitor[FPSReportInterval]" value="<?php echo validHtmlStr($monitor->FPSReportInterval()) ?>"/>
<input type="hidden" name="newMonitor[DefaultView]" value="<?php echo validHtmlStr($monitor->DefaultView()) ?>"/>
<input type="hidden" name="newMonitor[DefaultRate]" value="<?php echo validHtmlStr($monitor->DefaultRate()) ?>"/>
<input type="hidden" name="newMonitor[DefaultScale]" value="<?php echo validHtmlStr($monitor->DefaultScale()) ?>"/>
<input type="hidden" name="newMonitor[WebColour]" value="<?php echo validHtmlStr($monitor->WebColour()) ?>"/>
@ -1010,17 +1008,6 @@ if ( $monitor->Type() == 'Local' ) {
<tr><td><?php echo translate('MotionFrameSkip') ?></td><td><input type="text" name="newMonitor[MotionFrameSkip]" value="<?php echo validHtmlStr($monitor->MotionFrameSkip()) ?>" size="6"/></td></tr>
<tr><td><?php echo translate('AnalysisUpdateDelay') ?></td><td><input type="text" name="newMonitor[AnalysisUpdateDelay]" value="<?php echo validHtmlStr($monitor->AnalysisUpdateDelay()) ?>" size="6"/></td></tr>
<tr><td><?php echo translate('FPSReportInterval') ?></td><td><input type="text" name="newMonitor[FPSReportInterval]" value="<?php echo validHtmlStr($monitor->FPSReportInterval()) ?>" size="6"/></td></tr>
<tr><td><?php echo translate('DefaultView') ?></td><td><select name="newMonitor[DefaultView]">
<?php
foreach ( getEnumValues( 'Monitors', 'DefaultView' ) as $opt_view ) {
if ( $opt_view == 'Control' && ( !ZM_OPT_CONTROL || !$monitor->Controllable()) )
continue;
?>
<option value="<?php echo $opt_view ?>"<?php if ( $opt_view == $monitor->DefaultView()) { ?> selected="selected"<?php } ?>><?php echo $opt_view ?></option>
<?php
}
?>
</select></td></tr>
<tr><td><?php echo translate('DefaultRate') ?></td><td><?php echo htmlSelect( "newMonitor[DefaultRate]", $rates, $monitor->DefaultRate() ); ?></td></tr>
<tr><td><?php echo translate('DefaultScale') ?></td><td><?php echo htmlSelect( "newMonitor[DefaultScale]", $scales, $monitor->DefaultScale() ); ?></td></tr>
<tr>

View File

@ -69,7 +69,7 @@ if ( empty($_REQUEST['path']) ) {
}
if ( !empty($_REQUEST['eid']) ) {
Logger::Debug("Loading by eid");
Logger::Debug("Loading by eid");
$Event = Event::find_one(array('Id'=>$_REQUEST['eid']));
if ( !$Event ) {
header('HTTP/1.0 404 Not Found');
@ -77,24 +77,28 @@ Logger::Debug("Loading by eid");
return;
}
# if alarm, get the fid of the first alarmed frame if available and let the
# fid= code continue processing it. Sort it to get the first alarmed frame
if ( $_REQUEST['fid'] == 'alarm' ) {
# look for first alarmed frame
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'Type'=>'Alarm'),
array('order'=>'FrameId ASC'));
if ( !$Frame ) # no alarms
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'])); # first frame
if ( !$Frame ) {
Warning("No frame found for event " + $_REQUEST['eid']);
$Frame = new Frame();
$Frame->Delta(1);
$Frame->FrameId('snapshot');
if ( !$Frame ) { # no alarms, get first one I find
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid']));
if ( !$Frame ) {
Warning("No frame found for event " + $_REQUEST['eid']);
$Frame = new Frame();
$Frame->Delta(1);
$Frame->FrameId(1);
}
}
$Monitor = $Event->Monitor();
if ( $Monitor->SaveJPEGs() & 1 ) {
# If we store Frames as jpgs, then we don't store an alarmed snapshot
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
} else {
$path = $Event->Path().'/alarm.jpg';
}
$_REQUEST['fid']=$Frame->FrameId();
}
if ( $_REQUEST['fid'] == 'snapshot' ) {
else if ( $_REQUEST['fid'] == 'snapshot' ) {
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'Score'=>$Event->MaxScore()));
if ( !$Frame )
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid']));
@ -130,14 +134,14 @@ Logger::Debug("Loading by eid");
$percentage = ($Frame->FrameId() - $previousBulkFrame['FrameId']) / ($nextBulkFrame['FrameId'] - $previousBulkFrame['FrameId']);
$Frame->Delta($previousBulkFrame['Delta'] + floor( 100* ( $nextBulkFrame['Delta'] - $previousBulkFrame['Delta'] ) * $percentage )/100);
Logger::Debug("Got virtual frame from Bulk Frames previous delta: " . $previousBulkFrame['Delta'] . " + nextdelta:" . $nextBulkFrame['Delta'] . ' - ' . $previousBulkFrame['Delta'] . ' * ' . $percentage );
Logger::Debug("Got virtual frame from Bulk Frames previous delta: " . $previousBulkFrame['Delta'] . " + nextdelta:" . $nextBulkFrame['Delta'] . ' - ' . $previousBulkFrame['Delta'] . ' * ' . $percentage );
} else {
Fatal('No Frame found for event('.$_REQUEST['eid'].') and frame id('.$_REQUEST['fid'].')');
}
}
// Frame can be non-existent. We have Bulk frames. So now we should try to load the bulk frame
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
Logger::Debug("Path: $path");
Logger::Debug("Path: $path");
}
} else {