mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-09-22 18:45:43 -04:00
Reverts the previous commit's always-on measurement. Decoding audio for every monitor that has it spends CPU on a number almost nothing reads, which is the wrong trade even though it did solve the chicken and egg of picking a threshold without ever seeing a level. Measure when something is actually going to use the reading instead: - AudioDetection is on, as before, so nothing changes for a monitor that scores on audio; or - somebody asked. SharedData gains audio_level_until, a wall clock second the capture thread keeps measuring up to. The monitor editor's new level meter pushes it forward while it is on screen and the measurement lapses a few seconds after the page is left, so nothing has to send a stop and a crashed browser cannot leave a monitor decoding forever. When the reading stops being wanted the decoder is released and the published level and peak are cleared, so a stale number is not left looking current and an old peak does not land on the next frame row written. audio_level_until is carved out of analysis_pad rather than appended, so SharedData stays 888 bytes and no existing offset moves; the static_asserts, Memory.pm and Monitor.php are updated together and all three now agree the field is at +880. The meter itself is on the audio settings, shown whether or not AudioDetection is checked, because the level is what you need in order to choose a threshold. It draws the threshold currently in the input as a mark on the bar so a reading can be judged against it before saving, and a monitor whose zmc is not running reads "no reading" rather than a confident 0, which would be indistinguishable from silence. Frames.AudioLevel is therefore 0 again on monitors that do not score on audio. That is what the graph already treats as "no audio data", so it draws no line rather than a flat one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JpiSWBmtQkR5bcgpHWY4ME
70 lines
2.9 KiB
PHP
70 lines
2.9 KiB
PHP
<?php
|
|
ini_set('display_errors', '0');
|
|
|
|
if ( canView('Monitors') || (isset($_REQUEST['mid']) && $_REQUEST['mid'] !== '' && canView('Monitors', $_REQUEST['mid'])) ) {
|
|
$mid = isset($_REQUEST['mid']) ? $_REQUEST['mid'] : null;
|
|
if ($mid === null || $mid === '') {
|
|
ajaxError(translate('RequestMissing') . ' "mid".');
|
|
}
|
|
|
|
$action = $_REQUEST['action'] ?? '';
|
|
if ($action === '') {
|
|
ajaxError(translate('RequestMissing') . ' "action".');
|
|
}
|
|
|
|
switch ( $action ) {
|
|
case 'validateName' :
|
|
require_once('includes/Monitor.php');
|
|
$monitor = new ZM\Monitor($mid);
|
|
$filterRegexp = $monitor->getDefaults()['Name']['filter_regexp'];
|
|
$result = true;
|
|
$badChars = [];
|
|
$message = '';
|
|
|
|
if (isset($_REQUEST['monitorName']) && is_string($_REQUEST['monitorName']) && $_REQUEST['monitorName'] !== '') {
|
|
$monitorName = $_REQUEST['monitorName'];
|
|
$trimmedMonitorName = trim($monitorName);
|
|
$cleanedMonitorName = preg_replace($filterRegexp, '', $trimmedMonitorName);
|
|
if ($trimmedMonitorName != $cleanedMonitorName){
|
|
preg_match_all($filterRegexp, $trimmedMonitorName, $badChars);
|
|
$result = false;
|
|
$message = translate('BadNameCharsList') . ' "' . implode('","', array_unique($badChars[0])) . '".~~' . translate('BadNameChars');
|
|
}
|
|
ajaxResponse(array('response'=>$result, 'monitorName'=>$monitorName, 'cleanedMonitorName'=>$cleanedMonitorName, 'badChars'=>$badChars, 'messageBadNameChars'=>$message));
|
|
} else {
|
|
ajaxError(translate('ErrorVerifyingMonitorName'));
|
|
}
|
|
break;
|
|
case 'audioLevel' :
|
|
// Live reading for the level meter in the monitor editor's audio
|
|
// settings. Polling this is also what keeps zmc measuring: a monitor with
|
|
// AudioDetection off does not decode audio until asked, and stops again a
|
|
// few seconds after the polling does. See Monitor::AudioLevelWanted.
|
|
require_once('includes/Monitor.php');
|
|
$monitor = new ZM\Monitor($mid);
|
|
if (!$monitor->Id()) {
|
|
ajaxError('Not found: monitor id '.validHtmlStr($mid));
|
|
break;
|
|
}
|
|
if (!$monitor->canView()) {
|
|
ajaxError(translate('insufficientPermissionsUser').' "'.validHtmlStr($user->Username()).'"');
|
|
break;
|
|
}
|
|
|
|
$monitor->requestAudioLevel();
|
|
$level = $monitor->audioLevel();
|
|
ajaxResponse(array(
|
|
// null rather than 0 when zmc is not running, so the meter can say so
|
|
// instead of showing a confident silent reading.
|
|
'level' => is_null($level) ? null : intval($level),
|
|
'alarm' => $monitor->audioAlarm(),
|
|
'threshold' => intval($monitor->AudioThreshold()),
|
|
'detection' => $monitor->AudioDetection() ? true : false,
|
|
));
|
|
break;
|
|
} // end switch action
|
|
} // end if canView('Monitors')
|
|
|
|
ajaxError(translate('UnrecognisedAction').' "'.validHtmlStr($_REQUEST['action'] ?? '').'" '.translate('ConjOr').' '.translate('insufficientPermissionsUser').' "'.validHtmlStr($user->Username()).'"');
|
|
?>
|