From 7727c3e6980be9667f9cd091696610644341d24f Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Thu, 9 Jul 2026 22:22:51 +0300 Subject: [PATCH 1/2] Start loop countdown only if the stream has started playing on the Watch page. - Some players may take a long time to start playing a stream (several seconds) and if a short cycle is selected (5 or 10 seconds), then half of the time or more the stream is in standby mode and viewing may occur within 1-5 seconds instead of the planned 5 or 10 seconds. Now the player will play the stream for the time specified in the cycle parameters - If a specific player is selected on the page, then in case of repeated errors it will switch to the next monitor. In the "Auto" mode, theoretically we should always get to the ZMS player. - This change will only work if approved by PR #4960 --- web/skins/classic/views/js/watch.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 8004769afe..1b673e802d 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -1210,8 +1210,9 @@ var cycleIntervalId; var secondsToCycle = 0; function nextCycleView() { - secondsToCycle --; - if (secondsToCycle<=0) { + const stream = (monitorStream) ? monitorStream.getAVStream() : null; + if (stream && stream.readyState >= 2 || -1 !== monitorStream.activePlayer.indexOf('zms')) secondsToCycle --; + if (secondsToCycle<=0 || (monitorStream.fatalError && monitorStream.selectedPlayer)) { cycleNext(); } $j('#secondsToCycle').text(secondsToCycle); From bfb415a6a7135561ffdaea89481195a10df93891 Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Thu, 9 Jul 2026 22:28:37 +0300 Subject: [PATCH 2/2] Added "fatalError" property for MonitorStream --- web/js/MonitorStream.js | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index e77567c826..1fd1caac89 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -59,6 +59,7 @@ function MonitorStream(monitorData) { request: 'stream', connkey: this.connKey }; + this.fatalError = false; this.playerPriority = { 1: { // This setting should always be priority #1. name: 'default', @@ -576,6 +577,7 @@ function MonitorStream(monitorData) { }; this.start = function(streamChannel = 'default') { + this.fatalError = false; this.writeTextInfoBlock("Loading..."); if (streamChannel === null || streamChannel === '' || currentView == 'montage') streamChannel = 'default'; // Normalize channel name for internal tracking @@ -850,10 +852,29 @@ function MonitorStream(monitorData) { this.restart = function(channelStream = "default", delay = 200) { this.stop(); - const this_ = this; - setTimeout(function() {// During the downtime, the monitor may have already started to work. - if (!this_.started) this_.start(channelStream); - }, delay); + const countErrors = this.getCountStreamErrors(this.player); + if (countErrors < this.limitCountErrors) { + setTimeout(function(self) {// During the downtime, the monitor may have already started to work. + if (!self.started) self.start(channelStream); + }, delay, this); + } else { + if (typeof streamCmdStop === 'function') { + // Let's set the correct state for the player control buttons (for example, on the Watch page) + streamCmdStop(); + } + + if (-1 !== this.player.indexOf('zms')) { + this.writeTextInfoBlock("Error", {showImg: false}); + } else { + this.writeTextInfoBlock("Error"); + } + this.updateStreamInfo('', 'Error'); + this.fatalError = true; + this.resetCountStreamErrors(this.player); + const msg = `Out of ${this.limitCountErrors} consecutive attempts to start a stream for monitor ID=${this.id} using player "${this.player}", none were successful. The stream has been stopped.`; + console.warn(msg); + this.showText(msg); + } }; this.pause = function() {