diff --git a/.eslintignore b/.eslintignore index c70df40ba..c495c2faa 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,7 +7,7 @@ web/js/videojs.zoomrotate.js web/js/fontfaceobserver.standalone.js web/skins/classic/js/bootstrap-4.5.0.js web/skins/classic/js/bootstrap.bundle.min.js -web/skins/classic/js/bootstrap-table-1.22.3 +web/skins/classic/js/bootstrap-table-1.23.3 web/skins/classic/js/chosen web/skins/classic/js/dateTimePicker web/skins/classic/js/jquery-*.js @@ -16,7 +16,6 @@ web/skins/classic/js/jquery.js web/skins/classic/js/moment.js web/skins/classic/js/video.js web/skins/classic/assets -web/tools/mootools web/js/janus.js web/js/ajaxQueue.js web/js/hls.js diff --git a/.gitignore b/.gitignore index a856b1d5f..ee6ac35e7 100644 --- a/.gitignore +++ b/.gitignore @@ -199,10 +199,6 @@ web/cmake_install.cmake web/events/ web/images/ web/includes/config.php -web/tools/mootools/CMakeFiles/ -web/tools/mootools/cmake_install.cmake -web/tools/mootools/mootools-core.js -web/tools/mootools/mootools-more.js web/undef.log zm.conf zmconfgen.pl diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 84dbe3f59..5bbd3c1ad 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -289,7 +289,7 @@ bool EventStream::loadEventData(uint64_t event_id) { frame.in_db); } // end foreach db row - if (event_data->end_time.time_since_epoch() != Seconds(0)) { + if (event_data->end_time.time_since_epoch() != Seconds(0) and event_data->duration != Seconds(0)) { Microseconds delta; if (!last_frame) { // There were no frames in db diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index f5ee58c1e..68a13d1fe 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -188,7 +188,7 @@ int FfmpegCamera::Capture(std::shared_ptr &zm_packet) { start_read_time = std::chrono::steady_clock::now(); int ret; AVFormatContext *formatContextPtr; - int64_t lastPTS; + int64_t lastPTS = -1; if ( mSecondFormatContext and ( @@ -242,7 +242,7 @@ int FfmpegCamera::Capture(std::shared_ptr &zm_packet) { } return -1; } - if ( packet->stream_index == mAudioStreamId) { + if (packet->stream_index == mAudioStreamId) { lastPTS = mLastAudioPTS; } else if ( packet->stream_index == mVideoStreamId) { lastPTS = mLastVideoPTS; @@ -287,7 +287,7 @@ int FfmpegCamera::Capture(std::shared_ptr &zm_packet) { mFirstVideoPTS = packet->pts; mLastVideoPTS = packet->pts - mFirstVideoPTS; - } else { + } else if (stream == mAudioStream) { if (mFirstAudioPTS == AV_NOPTS_VALUE) mFirstAudioPTS = packet->pts; diff --git a/web/includes/config.php.in b/web/includes/config.php.in index 384d41181..9e91cb583 100644 --- a/web/includes/config.php.in +++ b/web/includes/config.php.in @@ -94,7 +94,6 @@ define('STATE_IDLE', 1); define('STATE_PREALARM', 2); define('STATE_ALARM', 3); define('STATE_ALERT', 4); -define('STATE_TAPE', 5); // // DVR Control Commands diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index a409f51a1..cf1295f98 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -50,7 +50,7 @@ function MonitorStream(monitorData) { }; this.img_onerror = function() { - console.log('Image stream has been stoppd! stopping streamCmd'); + console.log('Image stream has been stopped! stopping streamCmd'); this.streamCmdTimer = clearInterval(this.streamCmdTimer); }; this.img_onload = function() { @@ -375,10 +375,21 @@ function MonitorStream(monitorData) { }; this.pause = function() { - this.streamCommand(CMD_PAUSE); + if (this.element.src) { + this.streamCommand(CMD_PAUSE); + } else { + this.element.pause(); + this.statusCmdTimer = clearInterval(this.statusCmdTimer); + } }; + this.play = function() { - this.streamCommand(CMD_PLAY); + if (this.element.src) { + this.streamCommand(CMD_PLAY); + } else { + this.element.play(); + this.statusCmdTimer = setInterval(this.statusCmdQuery.bind(this), statusRefreshTimeout); + } }; this.eventHandler = function(event) { @@ -681,7 +692,6 @@ function MonitorStream(monitorData) { this.getStatusCmdResponse=function(respObj, respText) { //watchdogOk('status'); if (respObj.result == 'Ok') { - const monitorStatus = respObj.monitor.Status; const captureFPSValue = $j('#captureFPSValue'+this.id); const analysisFPSValue = $j('#analysisFPSValue'+this.id); const viewingFPSValue = $j('#viewingFPSValue'+this.id); @@ -720,42 +730,45 @@ function MonitorStream(monitorData) { } if (canEdit.Monitors) { - if (monitorStatus.enabled) { - if ('enableAlarmButton' in this.buttons) { + if ('enableAlarmButton' in this.buttons) { + if (monitor.Analysing == 'None') { + // Not doing analysis, so enable/disable button should be grey + if (!this.buttons.enableAlarmButton.hasClass('disabled')) { this.buttons.enableAlarmButton.addClass('disabled'); this.buttons.enableAlarmButton.prop('title', disableAlarmsStr); } - } - if ('forceAlarmButton' in this.buttons) { - if (monitorStatus.forced) { - if (!this.buttons.forceAlarmButton.hasClass('disabled')) { - this.buttons.forceAlarmButton.addClass('disabled'); - this.buttons.forceAlarmButton.prop('title', cancelForcedAlarmStr); - } - } else { - if (this.buttons.forceAlarmButton.hasClass('disabled')) { - this.buttons.forceAlarmButton.removeClass('disabled'); - this.buttons.forceAlarmButton.prop('title', forceAlarmStr); - } - } - this.buttons.forceAlarmButton.prop('disabled', false); - } - } else { - if ('enableAlarmButton' in this.buttons) { + } else { this.buttons.enableAlarmButton.removeClass('disabled'); this.buttons.enableAlarmButton.prop('title', enableAlarmsStr); - } - if ('forceAlarmButton' in this.buttons) { - this.buttons.forceAlarmButton.prop('disabled', true); - } - } - if ('enableAlarmButton' in this.buttons) { + } // end if doing analysis this.buttons.enableAlarmButton.prop('disabled', false); + } // end if have enableAlarmButton + + if ('forceAlarmButton' in this.buttons) { + if (monitor.Status == STATE_ALARM || monitor.Status == STATE_ALERT) { + // Ic0n: My thought here is that the non-disabled state should be for killing an alarm + // and the disabled state should be to force an alarm + if (this.buttons.forceAlarmButton.hasClass('disabled')) { + this.buttons.forceAlarmButton.removeClass('disabled'); + this.buttons.forceAlarmButton.prop('title', cancelForcedAlarmStr); + } + } else { + if (!this.buttons.forceAlarmButton.hasClass('disabled')) { + // Looks disabled + this.buttons.forceAlarmButton.addClass('disabled'); + this.buttons.forceAlarmButton.prop('title', forceAlarmStr); + } + } + this.buttons.forceAlarmButton.prop('disabled', false); + } else { + console.log("No forceAlarmButton"); } + } else { + console.log("Can't edit"); } // end if canEdit.Monitors - this.setAlarmState(monitorStatus); + this.setAlarmState(monitor.Status); if (respObj.auth_hash) { if (auth_hash != respObj.auth_hash) { @@ -807,7 +820,7 @@ function MonitorStream(monitorData) { this.alarmCommand = function(command) { if (this.ajaxQueue) { - console.log('Aborting in progress ajax for alarm'); + console.log('Aborting in progress ajax for alarm', this.ajaxQueue); // Doing this for responsiveness, but we could be aborting something important. Need smarter logic this.ajaxQueue.abort(); } diff --git a/web/skins/classic/css/base/skin.css b/web/skins/classic/css/base/skin.css index 487e3858b..8574054e0 100644 --- a/web/skins/classic/css/base/skin.css +++ b/web/skins/classic/css/base/skin.css @@ -1123,6 +1123,20 @@ html::-webkit-scrollbar-thumb, div::-webkit-scrollbar-thumb, nav::-webkit-scroll } } +@media screen and (max-height:600px) { + .sticky #mfbpanel { + max-height: 40vh; + overflow-y: auto; + overflow-x: hidden; + } + + .sticky #toolbar { + max-height: 20vh; + overflow-y: auto; + overflow-x: hidden; + } +} + /* +++ Control button block in the Stream image*/ .block-button-center { position: absolute; diff --git a/web/skins/classic/js/skin.js.php b/web/skins/classic/js/skin.js.php index db16d462a..5bc1b4891 100644 --- a/web/skins/classic/js/skin.js.php +++ b/web/skins/classic/js/skin.js.php @@ -107,7 +107,6 @@ const STATE_IDLE = ; const STATE_PREALARM = ; const STATE_ALARM = ; const STATE_ALERT = ; -const STATE_TAPE = ; const CMD_ANALYZE_ON = ; const CMD_ANALYZE_OFF = ; diff --git a/web/skins/classic/views/js/event.js b/web/skins/classic/views/js/event.js index a9fdc252f..7fd14e0b2 100644 --- a/web/skins/classic/views/js/event.js +++ b/web/skins/classic/views/js/event.js @@ -199,6 +199,7 @@ function renderAlarmCues(containerEl) { // if we shouldn't just use the event length endtime-starttime var cueRatio = containerEl.width() / (event_length * 100); var minAlarm = Math.ceil(1/cueRatio); + var spanTime = 0; var spanTimeStart = 0; var spanTimeEnd = 0; var alarmed = 0; @@ -230,8 +231,8 @@ function renderAlarmCues(containerEl) { //console.log(left, frame.Delta, event_length, containerEl.width()); spanTimeStart = spanTimeEnd; } else if ( (frame.Type !== 'Alarm') && (alarmed == 1) ) { //from alarm to nothing. End alarm and start nothing. - futNone = 0; - indexPlus = i+1; + let futNone = 0; + let indexPlus = i+1; if (((frame.Delta * 100) - spanTimeStart) < minAlarm && indexPlus < num_cueFrames) { //alarm is too short and there is more event continue; @@ -1667,7 +1668,7 @@ function initPage() { mapDiv.style.height='450px'; } if ( window.L ) { - map = L.map('LocationMap', { + const map = L.map('LocationMap', { center: L.latLng(eventData.Latitude, eventData.Longitude), zoom: 8, onclick: function() { diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 99a4fb361..7ae98ed3e 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -148,135 +148,6 @@ function changeStreamQuality() { monitorsSetScale(monitorId); } -function getStreamCmdResponse(respObj, respText) { - watchdogOk('stream'); - streamCmdTimer = clearTimeout(streamCmdTimer); - if (respObj.result == 'Ok') { - // The get status command can get backed up, in which case we won't be able to get the semaphore and will exit. - if (respObj.status) { - const streamStatus = respObj.status; - if ($j('#viewingFPSValue').text() != streamStatus.fps) { - $j('#viewingFPSValue').text(streamStatus.fps); - } - if ($j('#captureFPSValue').text() != streamStatus.capturefps) { - $j('#captureFPSValue').text(streamStatus.capturefps); - } - if ($j('#analysisFPSValue').text() != streamStatus.analysisfps) { - $j('#analysisFPSValue').text(streamStatus.analysisfps); - } - - setAlarmState(streamStatus.state); - - $j('#levelValue').text(streamStatus.level); - var newClass = 'ok'; - if (streamStatus.level > 95) { - newClass = 'alarm'; - } else if (streamStatus.level > 80) { - newClass = 'alert'; - } - $j('#levelValue').removeClass(); - $j('#levelValue').addClass(newClass); - - var delayString = secsToTime(streamStatus.delay); - - if (streamStatus.paused == true) { - $j('#modeValue').text('Paused'); - $j('#rate').addClass('hidden'); - $j('#delayValue').text(delayString); - $j('#delay').removeClass('hidden'); - $j('#level').removeClass('hidden'); - streamCmdPause(false); - } else if (streamStatus.delayed == true) { - $j('#modeValue').text('Replay'); - $j('#rateValue').text(streamStatus.rate); - $j('#rate').removeClass('hidden'); - $j('#delayValue').text(delayString); - $j('#delay').removeClass('hidden'); - $j('#level').removeClass('hidden'); - if (streamStatus.rate == 1) { - streamCmdPlay(false); - } else if (streamStatus.rate > 0) { - if (streamStatus.rate < 1) { - streamCmdSlowFwd(false); - } else { - streamCmdFastFwd(false); - } - } else { - if (streamStatus.rate > -1) { - streamCmdSlowRev(false); - } else { - streamCmdFastRev(false); - } - } // rate - } else { - $j('#modeValue').text('Live'); - $j('#rate').addClass('hidden'); - $j('#delay').addClass('hidden'); - $j('#level').addClass('hidden'); - streamCmdPlay(false); - } // end if paused or delayed - - $j('#zoomValue').text(streamStatus.zoom); - if (streamStatus.zoom == '1.0') { - setButtonState('zoomOutBtn', 'unavail'); - } else { - setButtonState('zoomOutBtn', 'inactive'); - } - - if (canEdit.Monitors) { - if (streamStatus.enabled) { - enableAlmBtn.addClass('disabled'); - enableAlmBtn.prop('title', disableAlarmsStr); - if (streamStatus.forced) { - forceAlmBtn.addClass('disabled'); - forceAlmBtn.prop('title', cancelForcedAlarmStr); - } else { - forceAlmBtn.removeClass('disabled'); - forceAlmBtn.prop('title', forceAlarmStr); - } - forceAlmBtn.prop('disabled', false); - } else { - enableAlmBtn.removeClass('disabled'); - enableAlmBtn.prop('title', enableAlarmsStr); - forceAlmBtn.prop('disabled', true); - } - enableAlmBtn.prop('disabled', false); - } // end if canEdit.Monitors - - if (streamStatus.auth) { - auth_hash = streamStatus.auth; - // Try to reload the image stream. - var streamImg = $j('#liveStream'+monitorId); - if (streamImg) { - const oldSrc = streamImg.attr('src'); - if (oldSrc) { - const newSrc = oldSrc.replace(/auth=\w+/i, 'auth='+streamStatus.auth); - if (oldSrc != newSrc) { - streamImg.attr('src', ''); // Required or chrome doesn't stop the stream - streamImg.attr('src', newSrc); - table.bootstrapTable('refresh'); - } - } - } - } // end if have a new auth hash - } // end if respObj.status - } else { - console.log("Not ok"); - checkStreamForErrors('getStreamCmdResponse', respObj);//log them - setTimeout(fetchImage, 1000, $j('#imageFeed img')[0]); - } - - var streamCmdTimeout = statusRefreshTimeout; - if (alarmState == STATE_ALARM || alarmState == STATE_ALERT) { - streamCmdTimeout = streamCmdTimeout/5; - } - streamCmdTimer = setTimeout(streamCmdQuery, streamCmdTimeout); -} - -function streamCmdQuery() { - streamCmdReq({command: CMD_QUERY}); -} - function onPause() { setButtonState('pauseBtn', 'active'); setButtonState('playBtn', 'inactive'); @@ -292,7 +163,7 @@ function onPause() { function streamCmdPause(action) { onPause(); if (action) { - monitorStream.streamCommand(CMD_PAUSE); + monitorStream.pause(); } } @@ -327,7 +198,7 @@ function streamCmdPlay(action) { if (action) { if (monitorStream.started) { //Stream was on pause - monitorStream.streamCommand(CMD_PLAY); + monitorStream.play(); } else { //Stream has been stopped monitorStream.start(); @@ -383,7 +254,7 @@ function streamCmdSlowFwd(action) { setButtonState('fastRevBtn', 'inactive'); } if (action) { - monitorStream.command(CMD_SLOWFWD); + monitorStream.streamCommand(CMD_SLOWFWD); } setButtonState('pauseBtn', 'active'); if (monitorStreamReplayBuffer) { @@ -402,7 +273,7 @@ function streamCmdSlowRev(action) { setButtonState('fastRevBtn', 'inactive'); } if (action) { - monitorStream.command(CMD_SLOWREV); + monitorStream.streamCommand(CMD_SLOWREV); } setButtonState('pauseBtn', 'active'); if (monitorStreamReplayBuffer) { @@ -421,7 +292,7 @@ function streamCmdFastRev(action) { setButtonState('fastRevBtn', 'inactive'); } if (action) { - monitorStream.command(CMD_FASTREV); + monitorStream.streamCommand(CMD_FASTREV); } } @@ -502,9 +373,9 @@ function cmdCancelForcedAlarm() { function cmdForce() { if (forceAlmBtn.hasClass('disabled')) { - cmdCancelForcedAlarm(); - } else { cmdForceAlarm(); + } else { + cmdCancelForcedAlarm(); } } @@ -753,31 +624,6 @@ function zoomOutClick(event) { } } -var watchdogInactive = { - 'stream': false, - 'status': false -}; - -var watchdogFunctions = { - 'stream': streamCmdQuery, - 'status': statusCmdQuery, -}; - -//Make sure the various refreshes are still taking effect -function watchdogCheck(type) { - if (watchdogInactive[type]) { - console.log("Detected streamWatch of type: " + type + " stopped, restarting"); - watchdogFunctions[type](); - watchdogInactive[type] = false; - } else { - watchdogInactive[type] = true; - } -} - -function watchdogOk(type) { - watchdogInactive[type] = false; -} - function reloadWebSite() { document.getElementById('imageFeed').innerHTML = document.getElementById('imageFeed').innerHTML; } @@ -949,7 +795,7 @@ function streamPrepareStart(monitor=null) { // Update table links each time after new data is loaded table.on('post-body.bs.table', function(data) { - var thumb_ndx = $j('#eventList tr th').filter(function() { + const thumb_ndx = $j('#eventList tr th').filter(function() { return $j(this).text().trim() == 'Thumbnail'; }).index(); table.find("tr td:nth-child(" + (thumb_ndx+1) + ")").addClass('colThumbnail'); @@ -993,11 +839,7 @@ function handleMouseLeave(event) { } function streamStart(monitor = null) { - if (monitor) { - monitorStream = new MonitorStream(monitor); - } else { - monitorStream = new MonitorStream(monitorData[monIdx]); - } + monitorStream = new MonitorStream(monitor ? monitor : monitorData[monIdx]); monitorStream.setBottomElement(document.getElementById('dvrControls')); // Start the fps and status updates. give a random delay so that we don't assault the server //monitorStream.setScale($j('#scale').val(), $j('#width').val(), $j('#height').val()); @@ -1027,15 +869,17 @@ function streamStart(monitor = null) { } function streamReStart(oldId, newId) { - document.getElementById('monitor').classList.add('hidden-shift'); - const el = document.querySelector('.imageFeed'); - const newMonitorName = document.getElementById('nav-item-cycle'+newId).querySelector('a').textContent; + const monitor_div = document.getElementById('monitor'); + monitor_div.classList.add('hidden-shift'); + currentMonitor = monitorData.find((o) => { return parseInt(o["id"]) === newId; }); const url = new URL(document.location.href); monitorId = newId; filterQuery = '&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId; + + const newMonitorName = document.getElementById('nav-item-cycle'+newId).querySelector('a').textContent; document.querySelector('title').textContent = newMonitorName; url.searchParams.set('mid', monitorId); history.pushState(null, "", url); @@ -1044,11 +888,13 @@ function streamReStart(oldId, newId) { if (monitorStream) { monitorStream.kill(); } + + const el = document.querySelector('.imageFeed'); el.removeEventListener('mouseenter', handleMouseEnter); el.removeEventListener('mouseleave', handleMouseLeave); //Change main monitor block - document.getElementById('monitor').innerHTML = currentMonitor.streamHTML; + monitor_div.innerHTML = currentMonitor.streamHTML; //Change active element of the navigation menu document.getElementById('nav-item-cycle'+oldId).querySelector('a').classList.remove("active"); @@ -1154,7 +1000,7 @@ function initPage() { bindButton('#cyclePrevBtn', 'click', null, cyclePrev); bindButton('#cycleToggle', 'click', null, cycleToggle); bindButton('#cyclePeriod', 'change', null, cyclePeriodChange); - if (monitorData.length && cycle) { + if (monitorData.length > 1 && cycle) { cycleStart(); } else { cyclePause(); @@ -1170,6 +1016,8 @@ function initPage() { setInterval(function() { if (idle >= ZM_WEB_VIEWING_TIMEOUT) { streamCmdPause(true); + const cycle_was = cycle; + cyclePause(); let ayswModal = $j('#AYSWModal'); if (!ayswModal.length) { $j.getJSON('?request=modal&modal=areyoustillwatching') @@ -1177,6 +1025,7 @@ function initPage() { ayswModal = insertModalHtml('AYSWModal', data.html); $j('#AYSWYesBtn').on('click', function() { streamCmdPlay(true); + if (cycle_was) cycleStart(); idle = 0; }); ayswModal.modal('show'); @@ -1192,6 +1041,7 @@ function initPage() { setInterval(() => { //Updating Scale. When quickly scrolling the mouse wheel or quickly pressing Zoom In/Out, you should not set Scale very often. if (updateScale) { + console.log('set scale for ', monitorId); monitorsSetScale(monitorId); updateScale = false; } @@ -1210,13 +1060,11 @@ function initPage() { if (currentMonitor) { applyMonitorControllable(); } - streamPrepareStart(); + streamPrepareStart(currentMonitor); // Creating a ResizeObserver Instance observer = new ResizeObserver((objResizes) => { - objResizes.forEach((obj) => { - monitorsSetScale(monitorId); - }); + updateScale = true; }); // Registering an observer on an element @@ -1284,6 +1132,7 @@ function cycleStop(target) { cyclePause(); } +// FIXME this runs within the interval handler and can take >50ms which will cause chrome to complain. function cycleNext() { monIdx ++; if (monIdx >= monitorData.length) { @@ -1293,18 +1142,12 @@ function cycleNext() { console.log('No monitorData for ' + monIdx); } clearInterval(intervalId); - monitorStream.kill(); // +++ Start next monitor - let oldId; - if (monIdx == 0) { - oldId = monitorData[monitorData.length-1].id; - } else { - oldId = monitorData[monIdx-1].id; - } + const oldId = monitorData[(monIdx == 0) ? monitorData.length-1 : monIdx-1].id; const newId = monitorData[monIdx].id; streamReStart(oldId, newId); - cycleStart(); + if (cycle) cycleStart(); // --- Start next monitor //window.location.replace('?view=watch&cycle='+cycle+'&mid='+monitorData[monIdx].id+'&mode='+mode); } @@ -1318,19 +1161,12 @@ function cyclePrev() { console.log('No monitorData for ' + monIdx); } clearInterval(intervalId); - //monitorStream.stop(); - monitorStream.kill(); // +++ Start previous monitor - let oldId; - if (monIdx == monitorData.length - 1) { - oldId = monitorData[0].id; - } else { - oldId = monitorData[monIdx+1].id; - } + const oldId = monitorData[(monIdx == monitorData.length - 1)? 0 : monIdx+1].id; const newId = monitorData[monIdx].id; streamReStart(oldId, newId); - cycleStart(); + if (cycle) cycleStart(); // --- Start previous monitors //window.location.replace('?view=watch&cycle='+cycle+'&mid='+monitorData[monIdx].id+'&mode='+mode); } @@ -1512,21 +1348,23 @@ function monitorsSetScale(id=null) { overrideHW = true; } + const monitor_div = document.getElementById('monitor'+id); + if (!monitor_div) console.log("No monitor div for ", id); if (resize) { if (scale == '0') { - document.getElementById('monitor'+id).style.width = 'max-content'; //Required when switching from resize=false to resize=true + monitor_div.style.width = 'max-content'; //Required when switching from resize=false to resize=true } - document.getElementById('monitor'+id).style.maxWidth = maxWidth; + monitor_div.style.maxWidth = maxWidth; if (!landscape) { //PORTRAIT - document.getElementById('monitor'+id).style.width = 'max-content'; + monitor_div.style.width = 'max-content'; document.getElementById('liveStream'+id).style.height = height; } } else { document.getElementById('liveStream'+id).style.height = ''; - document.getElementById('monitor'+id).style.width = width; - document.getElementById('monitor'+id).style.maxWidth = ''; + monitor_div.style.width = width; + monitor_div.style.maxWidth = ''; if (scale == 'fit_to_width') { - document.getElementById('monitor'+id).style.width = ''; + monitor_div.style.width = ''; } else if (scale == '100') { document.getElementById('liveStream'+id).style.width = width; } @@ -1535,10 +1373,10 @@ function monitorsSetScale(id=null) { curentMonitor.setScale(defScale, width, height, {resizeImg: resize, scaleImg: panZoomScale, streamQuality: $j('#streamQuality').val()}); if (overrideHW) { if (!landscape) { //PORTRAIT - document.getElementById('monitor'+id).style.width = 'max-content'; + monitor_div.style.width = 'max-content'; } else { document.getElementById('liveStream'+id).style.height = 'auto'; - document.getElementById('monitor'+id).style.width = 'auto'; + monitor_div.style.width = 'auto'; } } } else { @@ -1574,20 +1412,20 @@ function monitorsSetScale(id=null) { } if (resize) { - document.getElementById('monitor'+id).style.width = 'max-content'; //Required when switching from resize=false to resize=true + monitor_div.style.width = 'max-content'; //Required when switching from resize=false to resize=true } //monitors[i].setScale(0, parseInt(el.clientWidth * panZoomScale) + 'px', parseInt(el.clientHeight * panZoomScale) + 'px', {resizeImg:true, scaleImg:panZoomScale}); monitors[i].setScale(0, width, height, {resizeImg: resize, scaleImg: panZoomScale}); if (!resize) { document.getElementById('liveStream'+id).style.height = ''; if (scale == 'fit_to_width') { - document.getElementById('monitor'+id).style.width = ''; + monitor_div.style.width = ''; } else if (scale == '100') { - document.getElementById('monitor'+id).style.width = 'max-content'; + monitor_div.style.width = 'max-content'; document.getElementById('liveStream'+id).style.width = width; } } - } + } // end foreach monitor } setButtonSizeOnStream(); } @@ -1606,7 +1444,7 @@ document.onvisibilitychange = () => { }, 15*1000); } else { //Start monitor when show page - if (monitorStream && !monitorStream.started) { + if (monitorStream && !monitorStream.started && (idle