Merge branch 'release-1.36' of github.com:ZoneMinder/zoneminder into release-1.36

pull/4202/head
Isaac Connor 2024-05-25 09:27:35 -04:00
commit 8f774a0030
8 changed files with 100 additions and 55 deletions

View File

@ -554,6 +554,7 @@ CREATE TABLE `Monitor_Status` (
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0, `CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0, `AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
`CaptureBandwidth` INT NOT NULL default 0, `CaptureBandwidth` INT NOT NULL default 0,
`UpdatedOn` datetime NOT NULL default NOW(),
PRIMARY KEY (`MonitorId`) PRIMARY KEY (`MonitorId`)
) ENGINE=@ZM_MYSQL_ENGINE@; ) ENGINE=@ZM_MYSQL_ENGINE@;

11
db/zm_update-1.36.34.sql Normal file
View File

@ -0,0 +1,11 @@
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitor_Status'
AND column_name = 'UpdatedOn'
) > 0,
"SELECT 'Column UpdatedOn already exists in Monitor_Status'",
"ALTER TABLE `Monitor_Status` ADD `UpdatedOn` datetime NOT NULL default NOW() AFTER CaptureBandwidth"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -50,6 +50,8 @@ while (!$zm_terminate) {
sleep($Config{ZM_STATS_UPDATE_INTERVAL}); sleep($Config{ZM_STATS_UPDATE_INTERVAL});
} }
} }
# Clear out statuses for Monitors that aren't updating themselves.
zmDbDo('DELETE FROM Monitor_Status WHERE UpdatedOn < timestamp(DATE_SUB(NOW(), INTERVAL 1 MINUTE))') or Error($dbh->errstr());;
$dbh->do('DELETE FROM Events_Hour WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 hour)') or Error($dbh->errstr()); $dbh->do('DELETE FROM Events_Hour WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 hour)') or Error($dbh->errstr());
$dbh->do('DELETE FROM Events_Day WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 day)') or Error($dbh->errstr()); $dbh->do('DELETE FROM Events_Day WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 day)') or Error($dbh->errstr());

View File

@ -733,6 +733,22 @@ void Event::Run() {
if (packet) { if (packet) {
Debug(1, "Adding packet %d", packet->image_index); Debug(1, "Adding packet %d", packet->image_index);
this->AddPacket_(packet); this->AddPacket_(packet);
if (packet->image) {
if (monitor->GetOptVideoWriter() == Monitor::PASSTHROUGH) {
if (!save_jpegs) {
Debug(1, "Deleting image data for %d", packet->image_index);
// Don't need raw images anymore
delete packet->image;
packet->image = nullptr;
}
}
if (packet->analysis_image and !(save_jpegs & 2)) {
Debug(1, "Deleting analysis image data for %d", packet->image_index);
delete packet->analysis_image;
packet->analysis_image = nullptr;
}
} // end if packet->image
} }
} // end while } // end while
} // end Run() } // end Run()

View File

@ -1688,7 +1688,7 @@ void Monitor::UpdateFPS() {
last_camera_bytes = new_camera_bytes; last_camera_bytes = new_camera_bytes;
std::string sql = stringtf( std::string sql = stringtf(
"UPDATE LOW_PRIORITY Monitor_Status SET CaptureFPS = %.2lf, CaptureBandwidth=%u, AnalysisFPS = %.2lf WHERE MonitorId=%u", "UPDATE LOW_PRIORITY Monitor_Status SET CaptureFPS = %.2lf, CaptureBandwidth=%u, AnalysisFPS = %.2lf, UpdatedOn=NOW() WHERE MonitorId=%u",
new_capture_fps, new_capture_bandwidth, new_analysis_fps, id); new_capture_fps, new_capture_bandwidth, new_analysis_fps, id);
dbQueue.push(std::move(sql)); dbQueue.push(std::move(sql));
} // now != last_fps_time } // now != last_fps_time
@ -2144,7 +2144,7 @@ bool Monitor::Analyse() {
if (event) { if (event) {
event->AddPacket(snap); event->AddPacket(snap);
} } else {
// In the case where people have pre-alarm frames, the web ui will generate the frame images // In the case where people have pre-alarm frames, the web ui will generate the frame images
// from the mp4. So no one will notice anyways. // from the mp4. So no one will notice anyways.
@ -2163,6 +2163,7 @@ bool Monitor::Analyse() {
snap->analysis_image = nullptr; snap->analysis_image = nullptr;
} }
} }
}
// Free up the decoded frame as well, we won't be using it for anything at this time. // Free up the decoded frame as well, we won't be using it for anything at this time.
if (snap->out_frame) av_frame_free(&snap->out_frame); if (snap->out_frame) av_frame_free(&snap->out_frame);
if (snap->buffer) av_freep(&snap->buffer); if (snap->buffer) av_freep(&snap->buffer);

View File

@ -82,14 +82,6 @@ function initPage() {
$j('#WebSwatch').css('background-color', event.target.value); $j('#WebSwatch').css('background-color', event.target.value);
}; };
}); });
$j('#contentForm').submit(function(event) {
if ( validateForm(this) ) {
$j('#contentButtons').hide();
return true;
} else {
return false;
};
});
// Disable form submit on enter // Disable form submit on enter
$j('#contentForm input').on('keyup keypress', function(e) { $j('#contentForm input').on('keyup keypress', function(e) {
@ -135,7 +127,7 @@ function initPage() {
}); });
document.querySelectorAll('select[name="newMonitor[Type]"]').forEach(function(el) { document.querySelectorAll('select[name="newMonitor[Type]"]').forEach(function(el) {
el.onchange = function() { el.onchange = function() {
var form = document.getElementById('contentForm'); const form = document.getElementById('contentForm');
form.tab.value = 'general'; form.tab.value = 'general';
form.submit(); form.submit();
}; };

View File

@ -36,9 +36,10 @@ rtspStreamNames[\''.validJsStr($row['RTSPStreamName']).'\'] = true;
} # end if query } # end if query
?> ?>
function validateForm( form ) { function validateForm() {
var errors = new Array(); const form = document.getElementById('contentForm');
var warnings = new Array(); const errors = new Array();
const warnings = new Array();
const elements = form.elements; const elements = form.elements;
// No monitor input should have whitespace at beginning or end, so strip them out first. // No monitor input should have whitespace at beginning or end, so strip them out first.
@ -48,20 +49,41 @@ function validateForm( form ) {
} }
} }
if ( elements['newMonitor[Name]'].value.search( /[^\w\-\.\(\)\:\/ ]/ ) >= 0 ) if ( elements['newMonitor[Name]'].value.search( /[^\w\-\.\(\)\:\/ ]/ ) >= 0 ) {
errors[errors.length] = "<?php echo translate('BadNameChars') ?>"; errors[errors.length] = "<?php echo translate('BadNameChars') ?>";
else if ( monitorNames[form.elements['newMonitor[Name]'].value] ) } else if ( monitorNames[form.elements['newMonitor[Name]'].value] ) {
errors[errors.length] = "<?php echo translate('DuplicateMonitorName') ?>"; errors[errors.length] = "<?php echo translate('DuplicateMonitorName') ?>";
}
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 (errors.length) {
$j('#general-tab').tab('show');
alert(errors.join("\n"));
return false;
}
if ( form.elements['newMonitor[Type]'].value == 'Local' ) { if ( form.elements['newMonitor[Type]'].value == 'Local' ) {
if ( !form.elements['newMonitor[Palette]'].value || !form.elements['newMonitor[Palette]'].value.match( /^\d+$/ ) ) if ( !form.elements['newMonitor[Palette]'].value || !form.elements['newMonitor[Palette]'].value.match( /^\d+$/ ) ) {
errors[errors.length] = "<?php echo translate('BadPalette') ?>"; errors[errors.length] = "<?php echo translate('BadPalette') ?>";
if ( !form.elements['newMonitor[Device]'].value ) }
if ( !form.elements['newMonitor[Device]'].value ) {
errors[errors.length] = "<?php echo translate('BadDevice') ?>"; errors[errors.length] = "<?php echo translate('BadDevice') ?>";
if ( !form.elements['newMonitor[Channel]'].value || !form.elements['newMonitor[Channel]'].value.match( /^\d+$/ ) ) }
if ( !form.elements['newMonitor[Channel]'].value || !form.elements['newMonitor[Channel]'].value.match( /^\d+$/ ) ) {
errors[errors.length] = "<?php echo translate('BadChannel') ?>"; errors[errors.length] = "<?php echo translate('BadChannel') ?>";
if ( !form.elements['newMonitor[Format]'].value || !form.elements['newMonitor[Format]'].value.match( /^\d+$/ ) ) }
if ( !form.elements['newMonitor[Format]'].value || !form.elements['newMonitor[Format]'].value.match( /^\d+$/ ) ) {
errors[errors.length] = "<?php echo translate('BadFormat') ?>"; errors[errors.length] = "<?php echo translate('BadFormat') ?>";
}
if ( form.elements['newMonitor[VideoWriter]'].value == 2 /* Passthrough */ ) if ( form.elements['newMonitor[VideoWriter]'].value == 2 /* Passthrough */ )
errors[errors.length] = "<?php echo translate('BadPassthrough') ?>"; errors[errors.length] = "<?php echo translate('BadPassthrough') ?>";
} else if ( form.elements['newMonitor[Type]'].value == 'Remote' ) { } else if ( form.elements['newMonitor[Type]'].value == 'Remote' ) {
@ -99,31 +121,23 @@ function validateForm( form ) {
if ( form.elements['newMonitor[Path]'].value.search(/^https?:\/\//i) ) if ( form.elements['newMonitor[Path]'].value.search(/^https?:\/\//i) )
errors[errors.length] = "<?php echo translate('BadWebSitePath') ?>"; errors[errors.length] = "<?php echo translate('BadWebSitePath') ?>";
} }
if (form.elements['newMonitor[VideoWriter]'].value == '1' /* Encode */) {
var parameters = form.elements['newMonitor[EncoderParameters]'].value.replace(/[^#a-zA-Z]/g, "");
if (parameters == '' || parameters == '#Linesbeginningwith#areacomment#Forchangingqualityusethecrfoption#isbestisworstquality#crf' ) {
warnings[warnings.length] = '<?php echo translate('BadEncoderParameters') ?>';
}
}
if ( form.elements['newMonitor[Type]'].value != 'WebSite' ) { 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 ) ) 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') ?>"; errors[errors.length] = "<?php echo translate('BadColours') ?>";
if ( !form.elements['newMonitor[Width]'].value || !(parseInt(form.elements['newMonitor[Width]'].value) > 0 ) ) if ( !form.elements['newMonitor[Width]'].value || !(parseInt(form.elements['newMonitor[Width]'].value) > 0 ) )
errors[errors.length] = "<?php echo translate('BadWidth') ?>"; errors[errors.length] = "<?php echo translate('BadWidth') ?>";
if ( !form.elements['newMonitor[Height]'].value || !(parseInt(form.elements['newMonitor[Height]'].value) > 0 ) ) if ( !form.elements['newMonitor[Height]'].value || !(parseInt(form.elements['newMonitor[Height]'].value) > 0 ) )
errors[errors.length] = "<?php echo translate('BadHeight') ?>"; errors[errors.length] = "<?php echo translate('BadHeight') ?>";
}
if (errors.length) {
$j('#source-tab').tab('show');
alert(errors.join("\n"));
return false;
}
if ( form.elements['newMonitor[Type]'].value != 'WebSite' ) {
if ( !form.elements['newMonitor[LabelX]'].value || !(parseInt(form.elements['newMonitor[LabelX]'].value) >= 0 ) ) if ( !form.elements['newMonitor[LabelX]'].value || !(parseInt(form.elements['newMonitor[LabelX]'].value) >= 0 ) )
errors[errors.length] = "<?php echo translate('BadLabelX') ?>"; errors[errors.length] = "<?php echo translate('BadLabelX') ?>";
if ( !form.elements['newMonitor[LabelY]'].value || !(parseInt(form.elements['newMonitor[LabelY]'].value) >= 0 ) ) if ( !form.elements['newMonitor[LabelY]'].value || !(parseInt(form.elements['newMonitor[LabelY]'].value) >= 0 ) )
@ -142,7 +156,7 @@ function validateForm( form ) {
errors[errors.length] = "<?php echo translate('BadPostEventCount') ?>"; errors[errors.length] = "<?php echo translate('BadPostEventCount') ?>";
if ( !form.elements['newMonitor[StreamReplayBuffer]'].value || !(parseInt(form.elements['newMonitor[StreamReplayBuffer]'].value) >= 0 ) ) if ( !form.elements['newMonitor[StreamReplayBuffer]'].value || !(parseInt(form.elements['newMonitor[StreamReplayBuffer]'].value) >= 0 ) )
errors[errors.length] = "<?php echo translate('BadStreamReplayBuffer') ?>"; errors[errors.length] = "<?php echo translate('BadStreamReplayBuffer') ?>";
if (form.elements['newMonitor[PreEventCount]'].value > form.elements['newMonitor[MaxImageBufferCount]'].value) if (parseInt(form.elements['newMonitor[MaxImageBufferCount]'].value) && (parseInt(form.elements['newMonitor[PreEventCount]'].value) > parseInt(form.elements['newMonitor[MaxImageBufferCount]'].value)))
errors[errors.length] = "<?php echo translate('BadPreEventCountMaxImageBufferCount') ?>"; errors[errors.length] = "<?php echo translate('BadPreEventCountMaxImageBufferCount') ?>";
if ( !form.elements['newMonitor[AlarmFrameCount]'].value || !(parseInt(form.elements['newMonitor[AlarmFrameCount]'].value) > 0 ) ) if ( !form.elements['newMonitor[AlarmFrameCount]'].value || !(parseInt(form.elements['newMonitor[AlarmFrameCount]'].value) > 0 ) )
@ -175,6 +189,12 @@ function validateForm( form ) {
return false; return false;
} }
if (form.elements['newMonitor[VideoWriter]'].value == '1' /* Encode */) {
var parameters = form.elements['newMonitor[EncoderParameters]'].value.replace(/[^#a-zA-Z]/g, "");
if (parameters == '' || parameters == '#Linesbeginningwith#areacomment#Forchangingqualityusethecrfoption#isbestisworstquality#crf' ) {
warnings[warnings.length] = '<?php echo translate('BadEncoderParameters') ?>';
}
}
if ( (form.elements['newMonitor[Function]'].value != 'Monitor') && (form.elements['newMonitor[Function]'].value != 'None') ) { if ( (form.elements['newMonitor[Function]'].value != 'Monitor') && (form.elements['newMonitor[Function]'].value != 'None') ) {
if ( (form.elements['newMonitor[SaveJPEGs]'].value == '0') && (form.elements['newMonitor[VideoWriter]'].value == '0') ) { if ( (form.elements['newMonitor[SaveJPEGs]'].value == '0') && (form.elements['newMonitor[VideoWriter]'].value == '0') ) {
warnings[warnings.length] = "<?php echo translate('BadNoSaveJPEGsOrVideoWriter'); ?>"; warnings[warnings.length] = "<?php echo translate('BadNoSaveJPEGsOrVideoWriter'); ?>";
@ -185,7 +205,8 @@ function validateForm( form ) {
return false; return false;
} }
} }
form.elements['action'].value='save';
form.submit();
return true; return true;
} }

View File

@ -1315,7 +1315,8 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL
?> ?>
</div><!--tab-content--> </div><!--tab-content-->
<div id="contentButtons" class="pr-3"> <div id="contentButtons" class="pr-3">
<button type="submit" name="action" value="save"<?php echo canEdit('Monitors') ? '' : ' disabled="disabled"' ?>><?php echo translate('Save') ?></button> <input type="hidden" name="action"/>
<button type="button" data-on-click="validateForm" <?php echo canEdit('Monitors') ? '' : ' disabled="disabled"' ?>><?php echo translate('Save') ?></button>
<button type="button" id="cancelBtn"><?php echo translate('Cancel') ?></button> <button type="button" id="cancelBtn"><?php echo translate('Cancel') ?></button>
</div> </div>
</form> </form>