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,
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
`CaptureBandwidth` INT NOT NULL default 0,
`UpdatedOn` datetime NOT NULL default NOW(),
PRIMARY KEY (`MonitorId`)
) 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});
}
}
# 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_Day WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 day)') or Error($dbh->errstr());

View File

@ -733,6 +733,22 @@ void Event::Run() {
if (packet) {
Debug(1, "Adding packet %d", packet->image_index);
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 Run()

View File

@ -1688,7 +1688,7 @@ void Monitor::UpdateFPS() {
last_camera_bytes = new_camera_bytes;
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);
dbQueue.push(std::move(sql));
} // now != last_fps_time
@ -2144,7 +2144,7 @@ bool Monitor::Analyse() {
if (event) {
event->AddPacket(snap);
}
} else {
// 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.
@ -2163,6 +2163,7 @@ bool Monitor::Analyse() {
snap->analysis_image = nullptr;
}
}
}
// 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->buffer) av_freep(&snap->buffer);

View File

@ -82,14 +82,6 @@ function initPage() {
$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
$j('#contentForm input').on('keyup keypress', function(e) {
@ -135,7 +127,7 @@ function initPage() {
});
document.querySelectorAll('select[name="newMonitor[Type]"]').forEach(function(el) {
el.onchange = function() {
var form = document.getElementById('contentForm');
const form = document.getElementById('contentForm');
form.tab.value = 'general';
form.submit();
};

View File

@ -36,9 +36,10 @@ rtspStreamNames[\''.validJsStr($row['RTSPStreamName']).'\'] = true;
} # end if query
?>
function validateForm( form ) {
var errors = new Array();
var warnings = new Array();
function validateForm() {
const form = document.getElementById('contentForm');
const errors = new Array();
const warnings = new Array();
const elements = form.elements;
// 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') ?>";
else if ( monitorNames[form.elements['newMonitor[Name]'].value] )
} else if ( monitorNames[form.elements['newMonitor[Name]'].value] ) {
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[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') ?>";
if ( !form.elements['newMonitor[Device]'].value )
}
if ( !form.elements['newMonitor[Device]'].value ) {
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') ?>";
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') ?>";
}
if ( form.elements['newMonitor[VideoWriter]'].value == 2 /* Passthrough */ )
errors[errors.length] = "<?php echo translate('BadPassthrough') ?>";
} else if ( form.elements['newMonitor[Type]'].value == 'Remote' ) {
@ -99,31 +121,23 @@ function validateForm( form ) {
if ( form.elements['newMonitor[Path]'].value.search(/^https?:\/\//i) )
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[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 ) )
errors[errors.length] = "<?php echo translate('BadWidth') ?>";
if ( !form.elements['newMonitor[Height]'].value || !(parseInt(form.elements['newMonitor[Height]'].value) > 0 ) )
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 ) )
errors[errors.length] = "<?php echo translate('BadLabelX') ?>";
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') ?>";
if ( !form.elements['newMonitor[StreamReplayBuffer]'].value || !(parseInt(form.elements['newMonitor[StreamReplayBuffer]'].value) >= 0 ) )
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') ?>";
if ( !form.elements['newMonitor[AlarmFrameCount]'].value || !(parseInt(form.elements['newMonitor[AlarmFrameCount]'].value) > 0 ) )
@ -175,6 +189,12 @@ function validateForm( form ) {
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[SaveJPEGs]'].value == '0') && (form.elements['newMonitor[VideoWriter]'].value == '0') ) {
warnings[warnings.length] = "<?php echo translate('BadNoSaveJPEGsOrVideoWriter'); ?>";
@ -185,7 +205,8 @@ function validateForm( form ) {
return false;
}
}
form.elements['action'].value='save';
form.submit();
return true;
}

View File

@ -1315,7 +1315,8 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL
?>
</div><!--tab-content-->
<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>
</div>
</form>