Merge branch 'master' of github.com:ZoneMinder/zoneminder

This commit is contained in:
Isaac Connor
2026-02-15 15:59:33 -05:00
8 changed files with 170 additions and 583 deletions

View File

@@ -248,6 +248,7 @@ int main(int argc, char *argv[]) {
while (!monitor->connect() and !zm_terminate) {
Warning("Couldn't connect to monitor %d", monitor->Id());
monitor->SetHeartbeatTime(std::chrono::system_clock::now());
sleep(1);
}
if (zm_terminate) break;
@@ -381,7 +382,9 @@ int main(int argc, char *argv[]) {
} // end while ! zm_terminate and connected
for (std::shared_ptr<Monitor> & monitor : monitors) {
monitor->SetHeartbeatTime(std::chrono::system_clock::now());
monitor->Close();
monitor->SetHeartbeatTime(std::chrono::system_clock::now());
monitor->disconnect();
}

View File

@@ -1044,6 +1044,9 @@ a.flip {
right: 0;
background: none;
}
.colThumbnail img {
border-radius: 4px;
}
.monitor {
position: relative;
}
@@ -1595,6 +1598,25 @@ video-stream {
overflow: hidden;
}
img[id^='liveStream'], video[id^='liveStream'], video-stream[id^='liveStream'] {
margin: 0 auto;
object-fit: fill;
}
video-stream[id^='liveStream'] video{
max-height: inherit;
max-width: inherit;
object-fit: fill;
}
.imageFeed,
.nav,
.fixed-table-body,
*[id^='videoFeedStream']
{
border-radius: 4px;
}
/* +++ This block should always be located at the end! */
.hidden {
display: none;

View File

@@ -105,431 +105,3 @@
.grid-stack-item-content.modeEditingMonitor {
cursor: crosshair;
}
.gs-24 > .grid-stack-item {
width: 4.167%;
}
.gs-24 > .grid-stack-item[gs-x="1"] {
left: 4.167%;
}
.gs-24 > .grid-stack-item[gs-w="2"] {
width: 8.333%;
}
.gs-24 > .grid-stack-item[gs-x="2"] {
left: 8.333%;
}
.gs-24 > .grid-stack-item[gs-w="3"] {
width: 12.5%;
}
.gs-24 > .grid-stack-item[gs-x="3"] {
left: 12.5%;
}
.gs-24 > .grid-stack-item[gs-w="4"] {
width: 16.667%;
}
.gs-24 > .grid-stack-item[gs-x="4"] {
left: 16.667%;
}
.gs-24 > .grid-stack-item[gs-w="5"] {
width: 20.833%;
}
.gs-24 > .grid-stack-item[gs-x="5"] {
left: 20.833%;
}
.gs-24 > .grid-stack-item[gs-w="6"] {
width: 25%;
}
.gs-24 > .grid-stack-item[gs-x="6"] {
left: 25%;
}
.gs-24 > .grid-stack-item[gs-w="7"] {
width: 29.167%;
}
.gs-24 > .grid-stack-item[gs-x="7"] {
left: 29.167%;
}
.gs-24 > .grid-stack-item[gs-w="8"] {
width: 33.333%;
}
.gs-24 > .grid-stack-item[gs-x="8"] {
left: 33.333%;
}
.gs-24 > .grid-stack-item[gs-w="9"] {
width: 37.5%;
}
.gs-24 > .grid-stack-item[gs-x="9"] {
left: 37.5%;
}
.gs-24 > .grid-stack-item[gs-w="10"] {
width: 41.667%;
}
.gs-24 > .grid-stack-item[gs-x="10"] {
left: 41.667%;
}
.gs-24 > .grid-stack-item[gs-w="11"] {
width: 45.833%;
}
.gs-24 > .grid-stack-item[gs-x="11"] {
left: 45.833%;
}
.gs-24 > .grid-stack-item[gs-w="12"] {
width: 50%;
}
.gs-24 > .grid-stack-item[gs-x="12"] {
left: 50%;
}
.gs-24 > .grid-stack-item[gs-w="13"] {
width: 54.167%;
}
.gs-24 > .grid-stack-item[gs-x="13"] {
left: 54.167%;
}
.gs-24 > .grid-stack-item[gs-w="14"] {
width: 58.333%;
}
.gs-24 > .grid-stack-item[gs-x="14"] {
left: 58.333%;
}
.gs-24 > .grid-stack-item[gs-w="15"] {
width: 62.5%;
}
.gs-24 > .grid-stack-item[gs-x="15"] {
left: 62.5%;
}
.gs-24 > .grid-stack-item[gs-w="16"] {
width: 66.667%;
}
.gs-24 > .grid-stack-item[gs-x="16"] {
left: 66.667%;
}
.gs-24 > .grid-stack-item[gs-w="17"] {
width: 70.833%;
}
.gs-24 > .grid-stack-item[gs-x="17"] {
left: 70.833%;
}
.gs-24 > .grid-stack-item[gs-w="18"] {
width: 75%;
}
.gs-24 > .grid-stack-item[gs-x="18"] {
left: 75%;
}
.gs-24 > .grid-stack-item[gs-w="19"] {
width: 79.167%;
}
.gs-24 > .grid-stack-item[gs-x="19"] {
left: 79.167%;
}
.gs-24 > .grid-stack-item[gs-w="20"] {
width: 83.333%;
}
.gs-24 > .grid-stack-item[gs-x="20"] {
left: 83.333%;
}
.gs-24 > .grid-stack-item[gs-w="21"] {
width: 87.5%;
}
.gs-24 > .grid-stack-item[gs-x="21"] {
left: 87.5%;
}
.gs-24 > .grid-stack-item[gs-w="22"] {
width: 91.667%;
}
.gs-24 > .grid-stack-item[gs-x="22"] {
left: 91.667%;
}
.gs-24 > .grid-stack-item[gs-w="23"] {
width: 95.833%;
}
.gs-24 > .grid-stack-item[gs-x="23"] {
left: 95.833%;
}
.gs-24 > .grid-stack-item[gs-w="24"] {
width: 100%;
}
.gs-48 > .grid-stack-item {
width: 2.083%;
}
.gs-48 > .grid-stack-item[gs-x="1"] {
left: 2.083%;
}
.gs-48 > .grid-stack-item[gs-w="2"] {
width: 4.167%;
}
.gs-48 > .grid-stack-item[gs-x="2"] {
left: 4.167%;
}
.gs-48 > .grid-stack-item[gs-w="3"] {
width: 6.25%;
}
.gs-48 > .grid-stack-item[gs-x="3"] {
left: 6.25%;
}
.gs-48 > .grid-stack-item[gs-w="4"] {
width: 8.333%;
}
.gs-48 > .grid-stack-item[gs-x="4"] {
left: 8.333%;
}
.gs-48 > .grid-stack-item[gs-w="5"] {
width: 10.417%;
}
.gs-48 > .grid-stack-item[gs-x="5"] {
left: 10.417%;
}
.gs-48 > .grid-stack-item[gs-w="6"] {
width: 12.5%;
}
.gs-48 > .grid-stack-item[gs-x="6"] {
left: 12.5%;
}
.gs-48 > .grid-stack-item[gs-w="7"] {
width: 14.583%;
}
.gs-48 > .grid-stack-item[gs-x="7"] {
left: 14.583%;
}
.gs-48 > .grid-stack-item[gs-w="8"] {
width: 16.667%;
}
.gs-48 > .grid-stack-item[gs-x="8"] {
left: 16.667%;
}
.gs-48 > .grid-stack-item[gs-w="9"] {
width: 18.75%;
}
.gs-48 > .grid-stack-item[gs-x="9"] {
left: 18.75%;
}
.gs-48 > .grid-stack-item[gs-w="10"] {
width: 20.833%;
}
.gs-48 > .grid-stack-item[gs-x="10"] {
left: 20.833%;
}
.gs-48 > .grid-stack-item[gs-w="11"] {
width: 22.917%;
}
.gs-48 > .grid-stack-item[gs-x="11"] {
left: 22.917%;
}
.gs-48 > .grid-stack-item[gs-w="12"] {
width: 25%;
}
.gs-48 > .grid-stack-item[gs-x="12"] {
left: 25%;
}
.gs-48 > .grid-stack-item[gs-w="13"] {
width: 27.083%;
}
.gs-48 > .grid-stack-item[gs-x="13"] {
left: 27.083%;
}
.gs-48 > .grid-stack-item[gs-w="14"] {
width: 29.167%;
}
.gs-48 > .grid-stack-item[gs-x="14"] {
left: 29.167%;
}
.gs-48 > .grid-stack-item[gs-w="15"] {
width: 31.25%;
}
.gs-48 > .grid-stack-item[gs-x="15"] {
left: 31.25%;
}
.gs-48 > .grid-stack-item[gs-w="16"] {
width: 33.333%;
}
.gs-48 > .grid-stack-item[gs-x="16"] {
left: 33.333%;
}
.gs-48 > .grid-stack-item[gs-w="17"] {
width: 35.417%;
}
.gs-48 > .grid-stack-item[gs-x="17"] {
left: 35.417%;
}
.gs-48 > .grid-stack-item[gs-w="18"] {
width: 37.5%;
}
.gs-48 > .grid-stack-item[gs-x="18"] {
left: 37.5%;
}
.gs-48 > .grid-stack-item[gs-w="19"] {
width: 39.583%;
}
.gs-48 > .grid-stack-item[gs-x="19"] {
left: 39.583%;
}
.gs-48 > .grid-stack-item[gs-w="20"] {
width: 41.667%;
}
.gs-48 > .grid-stack-item[gs-x="20"] {
left: 41.667%;
}
.gs-48 > .grid-stack-item[gs-w="21"] {
width: 43.75%;
}
.gs-48 > .grid-stack-item[gs-x="21"] {
left: 43.75%;
}
.gs-48 > .grid-stack-item[gs-w="22"] {
width: 45.833%;
}
.gs-48 > .grid-stack-item[gs-x="22"] {
left: 45.833%;
}
.gs-48 > .grid-stack-item[gs-w="23"] {
width: 47.917%;
}
.gs-48 > .grid-stack-item[gs-x="23"] {
left: 47.917%;
}
.gs-48 > .grid-stack-item[gs-w="24"] {
width: 50%;
}
.gs-48 > .grid-stack-item[gs-x="24"] {
left: 50%;
}
.gs-48 > .grid-stack-item[gs-w="25"] {
width: 52.083%;
}
.gs-48 > .grid-stack-item[gs-x="25"] {
left: 52.083%;
}
.gs-48 > .grid-stack-item[gs-w="26"] {
width: 54.167%;
}
.gs-48 > .grid-stack-item[gs-x="26"] {
left: 54.167%;
}
.gs-48 > .grid-stack-item[gs-w="27"] {
width: 56.25%;
}
.gs-48 > .grid-stack-item[gs-x="27"] {
left: 56.25%;
}
.gs-48 > .grid-stack-item[gs-w="28"] {
width: 58.333%;
}
.gs-48 > .grid-stack-item[gs-x="28"] {
left: 58.333%;
}
.gs-48 > .grid-stack-item[gs-w="29"] {
width: 60.417%;
}
.gs-48 > .grid-stack-item[gs-x="29"] {
left: 60.417%;
}
.gs-48 > .grid-stack-item[gs-w="30"] {
width: 62.5%;
}
.gs-48 > .grid-stack-item[gs-x="30"] {
left: 62.5%;
}
.gs-48 > .grid-stack-item[gs-w="31"] {
width: 64.583%;
}
.gs-48 > .grid-stack-item[gs-x="31"] {
left: 64.583%;
}
.gs-48 > .grid-stack-item[gs-w="32"] {
width: 66.667%;
}
.gs-48 > .grid-stack-item[gs-x="32"] {
left: 66.667%;
}
.gs-48 > .grid-stack-item[gs-w="33"] {
width: 68.75%;
}
.gs-48 > .grid-stack-item[gs-x="33"] {
left: 68.75%;
}
.gs-48 > .grid-stack-item[gs-w="34"] {
width: 70.833%;
}
.gs-48 > .grid-stack-item[gs-x="34"] {
left: 70.833%;
}
.gs-48 > .grid-stack-item[gs-w="35"] {
width: 72.917%;
}
.gs-48 > .grid-stack-item[gs-x="35"] {
left: 72.917%;
}
.gs-48 > .grid-stack-item[gs-w="36"] {
width: 75%;
}
.gs-48 > .grid-stack-item[gs-x="36"] {
left: 75%;
}
.gs-48 > .grid-stack-item[gs-w="37"] {
width: 77.083%;
}
.gs-48 > .grid-stack-item[gs-x="37"] {
left: 77.083%;
}
.gs-48 > .grid-stack-item[gs-w="38"] {
width: 79.167%;
}
.gs-48 > .grid-stack-item[gs-x="38"] {
left: 79.167%;
}
.gs-48 > .grid-stack-item[gs-w="39"] {
width: 81.25%;
}
.gs-48 > .grid-stack-item[gs-x="39"] {
left: 81.25%;
}
.gs-48 > .grid-stack-item[gs-w="40"] {
width: 83.333%;
}
.gs-48 > .grid-stack-item[gs-x="40"] {
left: 83.333%;
}
.gs-48 > .grid-stack-item[gs-w="41"] {
width: 85.417%;
}
.gs-48 > .grid-stack-item[gs-x="41"] {
left: 85.417%;
}
.gs-48 > .grid-stack-item[gs-w="42"] {
width: 87.5%;
}
.gs-48 > .grid-stack-item[gs-x="42"] {
left: 87.5%;
}
.gs-48 > .grid-stack-item[gs-w="43"] {
width: 89.583%;
}
.gs-48 > .grid-stack-item[gs-x="43"] {
left: 89.583%;
}
.gs-48 > .grid-stack-item[gs-w="44"] {
width: 91.667%;
}
.gs-48 > .grid-stack-item[gs-x="44"] {
left: 91.667%;
}
.gs-48 > .grid-stack-item[gs-w="45"] {
width: 93.75%;
}
.gs-48 > .grid-stack-item[gs-x="45"] {
left: 93.75%;
}
.gs-48 > .grid-stack-item[gs-w="46"] {
width: 95.833%;
}
.gs-48 > .grid-stack-item[gs-x="46"] {
left: 95.833%;
}
.gs-48 > .grid-stack-item[gs-w="47"] {
width: 97.917%;
}
.gs-48 > .grid-stack-item[gs-x="47"] {
left: 97.917%;
}
.gs-48 > .grid-stack-item[gs-w="48"] {
width: 100%;
}

View File

@@ -40,11 +40,15 @@
}
.monitor {
display: flex;
flex-direction: column;
margin: 0 auto;
}
.monitor .imageFeed {
border: 2px solid #999999;
padding: 0px;
margin: 0px;
}
.monitor .imageFeed img,
@@ -52,7 +56,8 @@
.monitor .imageFeed video-stream,
.monitor .imageFeed svg {
border: none;
display: inline-block;
/*display: inline-block;*/
display: block;
width: 100%;
}

View File

@@ -796,6 +796,8 @@ function scaleToFit(baseWidth, baseHeight, scaleEl, bottomEl, container, panZoom
const viewPort = $j(window);
// jquery does not provide a bottom offset, and offset does not include margins. outerHeight true minus false gives total vertical margins.
var bottomLoc = 0;
const content = $j("#content");
const scrollTop = (content.length > 0) ? content.scrollTop() : 0; // Watch page may have Scroll when Stream changes
if (bottomEl !== false) {
if (!bottomEl || !bottomEl.length) {
if (container[0] && container[0].lastElementChild) {
@@ -805,7 +807,7 @@ function scaleToFit(baseWidth, baseHeight, scaleEl, bottomEl, container, panZoom
}
}
if (bottomEl && bottomEl.length) {
bottomLoc = bottomEl.offset().top + (bottomEl.outerHeight(true) - bottomEl.outerHeight()) + bottomEl.outerHeight(true);
bottomLoc = bottomEl.offset().top + (bottomEl.outerHeight(true) - bottomEl.outerHeight()) + bottomEl.outerHeight(true) + scrollTop;
console.log("bottomLoc: " + bottomEl.offset().top + " + (" + bottomEl.outerHeight(true) + ' - ' + bottomEl.outerHeight() +') + '+bottomEl.outerHeight(true) + '='+bottomLoc);
}
}
@@ -2627,4 +2629,129 @@ function replaceDOMElement(fromEl, toTypeEl) {
return newEl;
};
function monitorsSetScale(id=null) {
id = stringToNumber(id);
if (!isNaN(id)) {
let currentMonitor;
if (typeof monitorStream !== 'undefined' && monitorStream !== false) {
//monitorStream used on Watch page.
currentMonitor = monitorStream;
} else if (typeof monitors !== 'undefined') {
//used on Montage, Watch & Event page.
currentMonitor = monitors.find((o) => {
return parseInt(o["id"]) === id;
});
} else {
console.log("Stream is missing.");
return;
}
_setScale(currentMonitor);
} else { // Not a specific stream, but all streams.
for ( let i = 0, length = monitors.length; i < length; i++ ) {
_setScale(monitors[i]);
} // end foreach monitor
}
function _setScale(currentMonitor) {
const id = currentMonitor.id;
const panZoomScale = (panZoomEnabled && typeof zmPanZoom !== 'undefined') ? zmPanZoom.panZoom[id].getScale() : 1;
let resize = false;
let width = 'auto';
let height = 'auto';
let overrideHW = false;
let defScale = 0;
const ratio = currentMonitor.width / currentMonitor.height;
const landscape = ratio > 1 ? true : false; //Image orientation.
const liveStream = currentMonitor.getElement();
const monitor_div = document.getElementById('monitor'+id);
if (!monitor_div) {
console.log("No monitor div for ", id);
return;
}
const scale = $j('#scale').val();
if (scale) {
if (scale == '0') {
//Auto, Width is calculated based on the occupied height so that the image and control buttons occupy the visible part of the screen.
} else if (scale == '100') {
//Actual, 100% of original size
width = currentMonitor.width + 'px';
height = currentMonitor.height + 'px';
overrideHW = true;
} else if (scale == 'fit_to_width') {
//Fit to screen width
width = parseInt(monitor_div.clientWidth * panZoomScale) + 'px';
defScale = parseInt(monitor_div.clientWidth / currentMonitor.width * panZoomScale * 100);
overrideHW = true;
} else if (scale.indexOf("px") > -1) {
// If the aspect ratio specified in the monitor settings does not correspond to the actual aspect ratio of the video, then:
// - For MJPEG player, the video will be displayed according to the specified aspect ratio.
// - For other players, taking into account the actual video aspect ratio.
if (landscape) {
width = scale;
//height = parseInt(scale) / ratio + 'px';
defScale = parseInt(Math.min(stringToNumber(scale), window.innerWidth) / currentMonitor.width * panZoomScale * 100);
} else {
width = parseInt(parseInt(scale) * ratio) + 'px';
//height = scale;
defScale = parseInt(Math.min(stringToNumber(scale), window.innerHeight) / currentMonitor.height * panZoomScale * 100);
}
overrideHW = true;
}
resize = true;
} else { // Montage page does not have "scale"
width = parseInt(liveStream.clientWidth * panZoomScale) + 'px';
height = parseInt(liveStream.clientHeight * panZoomScale) + 'px';
}
currentMonitor.setScale(defScale, width, height, {resizeImg: resize, scaleImg: panZoomScale, streamQuality: $j('#streamQuality').val()});
if (overrideHW) {
if (scale == 'fit_to_width') {
liveStream.style.width = width;
liveStream.style.height = '';
liveStream.style.maxWidth = '';
monitor_div.style.width = 'auto';
monitor_div.style.height = '';
monitor_div.style.maxWidth = '';
} else if (scale.indexOf("px") > -1) {
liveStream.style.width = '';
liveStream.style.height = height;
liveStream.style.maxWidth = '100%';
monitor_div.style.width = width;
monitor_div.style.height = '';
monitor_div.style.maxWidth = '100%';
} else if (scale == '100') {
liveStream.style.width = width;
liveStream.style.height = height;
liveStream.style.maxWidth = '';
monitor_div.style.width = 'fit-content';
monitor_div.style.height = '';
monitor_div.style.maxWidth = '';
} else {
liveStream.style.width = width;
liveStream.style.height = height;
liveStream.style.maxWidth = '';
monitor_div.style.width = '100%';
monitor_div.style.height = '';
monitor_div.style.maxWidth = '';
}
}
if (scale == '0') {
const fillVideo = true; //true = In AUTO mode it will stretch to the full width, but will spoil the proportions if they do not correspond to the actual proportions in the monitor settings!!!
const tagVideo = (liveStream.tagName == 'VIDEO') ? liveStream : liveStream.querySelector('video');
if (tagVideo) {
if (fillVideo) {
tagVideo.style.width = '';
tagVideo.objectFit = 'fill';
} else {
tagVideo.style.width = 'auto';
tagVideo.objectFit = '';
}
}
}
} // End function _setScale
setButtonSizeOnStream();
} // End function monitorsSetScale
$j( window ).on("load", initPageGeneral);

View File

@@ -860,33 +860,6 @@ function changeStreamQuality() {
monitorsSetScale();
}
function monitorsSetScale(id=null) {
// This function will probably need to be moved to the main JS file, because now used on Watch & Montage pages
id = parseInt(id);
if (id || typeof monitorStream !== 'undefined') {
//monitorStream used on Watch page.
if (typeof monitorStream !== 'undefined') {
var currentMonitor = monitorStream;
} else {
var currentMonitor = monitors.find((o) => {
return parseInt(o["id"]) === id;
});
}
const el = document.getElementById('liveStream'+id);
const panZoomScale = (panZoomEnabled && zmPanZoom.panZoom[id] ) ? zmPanZoom.panZoom[id].getScale() : 1;
console.log("monitorsSetsCale", id, 'clientWidth', el.clientWidth, 'clientHeight', el.clientHeight, 'panzoomscale', panZoomScale);
currentMonitor.setScale(0, el.clientWidth * panZoomScale + 'px', el.clientHeight * panZoomScale + 'px', {resizeImg: false, streamQuality: $j('#streamQuality').val()});
} else {
for ( let i = 0, length = monitors.length; i < length; i++ ) {
const id = monitors[i].id;
const el = document.getElementById('liveStream'+id);
const panZoomScale = panZoomEnabled ? zmPanZoom.panZoom[id].getScale() : 1;
monitors[i].setScale(0, parseInt(el.clientWidth * panZoomScale) + 'px', parseInt(el.clientHeight * panZoomScale) + 'px', {resizeImg: false, streamQuality: $j('#streamQuality').val()});
}
}
setButtonSizeOnStream();
}
function changeMonitorRate() {
const rate = $j('#changeRate').val();
monitorsSetRate(rate);

View File

@@ -834,7 +834,7 @@ function streamStart(monitor = null) {
monitorStream = new MonitorStream(monitor ? monitor : monitorData[monIdx]);
monitorStream.setPlayer($j('#player').val());
monitorStream.setBottomElement(document.getElementById('dvrControls'));
monitorStream.setBottomElement(document.getElementById('bottomBlock'));
monitorStream.controlMute(getCookie('zmWatchMute') || 'on'); // default to muted
monitorStream.manageAvailablePlayers();
setChannelStream();
@@ -917,6 +917,13 @@ function streamReStart(oldId, newId) {
zmPanZoom.init();
zmPanZoom.init({objString: '.imageFeed', disablePan: true, contain: 'inside', additional: true});
//document.getElementById('monitor').classList.remove('hidden-shift');
// Remove Event listener for double click
const elStream = document.querySelectorAll('[id = "wrapperMonitor"]');
Array.prototype.forEach.call(elStream, (el) => {
el.removeEventListener('touchstart', doubleTouch);
el.removeEventListener('dblclick', doubleClickOnStream);
});
}
function setChannelStream() {
@@ -1105,7 +1112,7 @@ function initPage() {
});
// Registering an observer on an element
$j('[id ^= "liveStream"]').each(function() {
$j('[id ^= "liveStream"], .monitorStatus').each(function() {
observer.observe(this);
});
@@ -1368,128 +1375,6 @@ function changePlayer() {
}, 300);*/
}
function monitorsSetScale(id=null) {
//This function will probably need to be moved to the main JS file, because now used on Watch & Montage pages
if (id || typeof monitorStream !== 'undefined') {
if (monitorStream !== false) {
//monitorStream used on Watch page.
var currentMonitor = monitorStream;
} else if (typeof monitors !== 'undefined') {
//used on Montage, Watch & Event page.
var currentMonitor = monitors.find((o) => {
return parseInt(o["id"]) === id;
});
} else {
//Stream is missing
return;
}
var panZoomScale = (panZoomEnabled && zmPanZoom.panZoom[id]) ? zmPanZoom.panZoom[id].getScale() : 1;
let resize = false;
let width = 'auto';
let maxWidth = '';
let height = 'auto';
let overrideHW = false;
let defScale = 0;
const landscape = currentMonitor.width / currentMonitor.height > 1 ? true : false; //Image orientation.
const scale = $j('#scale').val();
if (scale == '0') {
//Auto, Width is calculated based on the occupied height so that the image and control buttons occupy the visible part of the screen.
resize = true;
} else if (scale == '100') {
//Actual, 100% of original size
width = currentMonitor.width + 'px';
height = currentMonitor.height + 'px';
} else if (scale == 'fit_to_width') {
//Fit to screen width
width = parseInt(window.innerWidth * panZoomScale) + 'px';
} else if (scale.indexOf("px") > -1) {
if (landscape) {
maxWidth = scale;
defScale = parseInt(Math.min(stringToNumber(scale), window.innerWidth) / currentMonitor.width * panZoomScale * 100);
} else {
defScale = parseInt(Math.min(stringToNumber(scale), window.innerHeight) / currentMonitor.height * panZoomScale * 100);
height = scale;
}
resize = true;
overrideHW = true;
}
const liveStream = document.getElementById('liveStream'+id);
const monitor_div = document.getElementById('monitor'+id);
if (!monitor_div) console.log("No monitor div for ", id);
if (resize) {
if (scale == '0') {
monitor_div.style.width = 'max-content'; //Required when switching from resize=false to resize=true
}
monitor_div.style.maxWidth = maxWidth;
if (!landscape) { //PORTRAIT
monitor_div.style.width = 'max-content';
liveStream.style.height = height;
}
} else {
liveStream.style.height = '';
monitor_div.style.width = width;
monitor_div.style.maxWidth = '';
if (scale == 'fit_to_width') {
monitor_div.style.width = '';
} else if (scale == '100') {
liveStream.style.width = width;
}
}
//currentMonitor.setScale(0, maxWidth ? maxWidth : width, height, {resizeImg: resize, scaleImg: panZoomScale});
currentMonitor.setScale(defScale, width, height, {resizeImg: resize, scaleImg: panZoomScale, streamQuality: $j('#streamQuality').val()});
if (overrideHW) {
if (!landscape) { //PORTRAIT
monitor_div.style.width = 'max-content';
} else {
liveStream.style.height = 'auto';
monitor_div.style.width = 'auto';
}
}
} else { // Not a specific stream, but all streams.
for ( let i = 0, length = monitors.length; i < length; i++ ) {
const id = monitors[i].id;
var panZoomScale = panZoomEnabled ? panZoom[id].getScale() : 1;
let resize = false;
let width = 'auto';
let height = 'auto';
const scale = $j('#scale').val();
if (scale == '0') {
//Auto, Width is calculated based on the occupied height so that the image and control buttons occupy the visible part of the screen.
resize = true;
} else if (scale == '100') {
//Actual, 100% of original size
width = monitors[i].width + 'px';
height = monitors[i].height + 'px';
} else if (scale == 'fit_to_width') {
//Fit to screen width
width = parseInt(window.innerWidth * panZoomScale) + 'px';
}
if (resize) {
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) {
livestream = document.getElementById('liveStream'+id);
livestream.style.height = '';
if (scale == 'fit_to_width') {
monitor_div.style.width = '';
} else if (scale == '100') {
monitor_div.style.width = 'max-content';
liveStream.style.width = width;
}
}
} // end foreach monitor
}
setButtonSizeOnStream();
}
// Kick everything off
$j( window ).on("load", initPage);

View File

@@ -411,7 +411,7 @@ echo htmlSelect('cyclePeriod', $cyclePeriodOptions, $period, array('id'=>'cycleP
echo $monitor->getStreamHTML($options);
?>
</div><!-- id="Monitor" -->
<div class="buttons" id="dvrControls">
<div id="bottomBlock"><div class="buttons" id="dvrControls">
<!--
<button type="button" id="getImageBtn" title="<?php echo translate('Download Image') ?>"/>
-->
@@ -461,7 +461,7 @@ ZM\Debug("Muted $muted");
<div id="volumeSlider<?php echo $mid; ?>" data-volume="<?php echo $volume; ?>" data-muted="<?php echo $muted ? 'true' : 'false'; ?>" class="volumeSlider noUi-horizontal noUi-base noUi-round"></div>
<i id="controlMute<?php echo $mid; ?>" class="audio-control-mute material-icons md-22"></i>
</span>
</div>
</div><!-- id="extButton" --><div><!-- id="bottomBlock" -->
</div><!-- id="wrapperMonitor" -->
<!-- START Control -->