Skip to content

Improved RTSP2Web processing in HLS mode. - #4968

Merged
connortechnology merged 2 commits into
ZoneMinder:masterfrom
IgorA100:patch-601764
Jul 8, 2026
Merged

Improved RTSP2Web processing in HLS mode.#4968
connortechnology merged 2 commits into
ZoneMinder:masterfrom
IgorA100:patch-601764

Conversation

@IgorA100

@IgorA100 IgorA100 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor
  • Assign video._hls when Hls() is executed, not just when an error occurs. This will allow HLS to be destroyed more correctly even if no error occurred.
  • Destroy Hls using the hlsDestroy() function, in which we remove all listeners. This will prevent memory leaks and unintended and unpredictable HLS code execution in the future.
  • When hovering over an image thumbnail and starting RTSP2Web_Hls, let's clear video._fallbackTimer when Media ATTACHED. The problem is that RTSP2Web can take a long time to load, even more than 5 seconds. But it's highly likely to load eventually. If an error occurs later (for example, a manifest error or something else), our "Hls.Events.ERROR" listener will be triggered and we'll switch to the fallbackToMjpeg() method.
    It's probably better to wait a bit and play using HLS rather than immediately switch to ZMS.
  • When attempting to play an AAC: mp4a.40.2 audio track using RTSP2Web in HLS mode, stop playback and restart. Yes, for now, it will restart in an infinite loop if a specific player is selected in the browser. However, this will be changed in the next PR More accurate next player selection and preventing endless restarts when a specific player is selected #4960.
  • Execute this.updateStreamInfo('', '') only after playback starts, not after MEDIA_ATTACHED, since that will cause a delay. There may be more errors later (for example, an unsupported audio codec, an m3u8 manifest error, or other errors.)
  • Execute this.updateStreamInfo('', 'Error') and log errors only if the error is fatal.
  • Moved this.streamErrorRegistration() lower in the code.
  • When an error is detected in a loop, players are cycled through. Once we've found the required player and detected the error, we stop cycling through the loop. While this won't impact performance, it will be more accurate.

IgorA100 and others added 2 commits July 6, 2026 16:08
- Assign video._hls when Hls() is executed, not just when an error occurs. This will allow Hls to be destroyed more correctly even if no error occurs.
- Destroy Hls using the hlsDestroy() function, in which we remove all listeners. This will prevent memory leaks and unintended and unpredictable Hls code execution in the future.
- When hovering over an image thumbnail and starting RTSP2Web_Hls, let's clear video._fallbackTimer when Media ATTACHED. RTSP2Web can take a long time to load, even more than 5 seconds. But it will most likely load eventually. If an error occurs later (for example, a manifest error or something else), the "Hls.Events.ERROR" listener will be triggered, and we will switch to the fallbackToMjpeg() method. It's probably better to wait a bit and play using HLS rather than immediately switch to ZMS.
…b in HLS mode, stop playback and restart. Yes, for now, it will restart in an infinite loop if a specific player is selected in the browser. However, this will be changed in the next PR ZoneMinder#4960.

- Execute this.updateStreamInfo('', '') only after playback starts, not after MEDIA_ATTACHED, since that will cause a delay. There may be more errors later (for example, an unsupported audio codec, an m3u8 manifest error, or other errors.)
- Execute this.updateStreamInfo('', 'Error') and log errors only if the error is fatal.
- Moved this.streamErrorRegistration() lower in the code.
@IgorA100
IgorA100 marked this pull request as ready for review July 6, 2026 14:59
@connortechnology
connortechnology requested a review from Copilot July 8, 2026 05:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines RTSP2Web HLS playback handling in the ZoneMinder web UI by improving teardown behavior, error/fallback timing, and when stream status is updated, with the goal of reducing leaks and making player switching more accurate.

Changes:

  • Assigns and clears HLS state more consistently (e.g., video._hls) and attempts to centralize HLS teardown via a helper.
  • Adjusts RTSP2Web HLS event handling (e.g., fatal-only error handling, update stream info on playback start).
  • Tweaks error counting behavior to stop cycling once the current player is identified.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
web/skins/classic/js/skin.js Adds HLS instance tracking, changes fallback/error teardown to use a new hlsDestroy() helper, and tweaks fallback timing behavior.
web/js/MonitorStream.js Switches HLS teardown to hlsDestroy(), adds additional HLS event handlers, and adjusts when stream info/error counters are updated.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1644 to +1655
const hlsDestroy = function(hls) {
if (hls && Hls) {
Object.keys(Hls.Events).forEach(function(eventName) {
hls.off(Hls.Events[eventName], function(event, data) {
});
});
hls.destroy();
hls = null;
} else {
console.warn("Hls cannot be destroyed because it is not loaded.");
}
};
Comment on lines 1631 to 1634
video._fallbackTimer = setTimeout(function() {
if (video.readyState < 2) {
if (video._hls) video._hls.destroy();
if (video._hls) hlsDestroy(video._hls);
video.remove();
video._hls.destroy();
video._hls = null;
}
if (video._hls) hlsDestroy(video._hls);
Comment thread web/js/MonitorStream.js
Comment thread web/js/MonitorStream.js
Comment on lines +1813 to +1817
this.updateStreamInfo('', `Error. AAC codec "${data.audio.codec}" is not supported.`); //HLS
this.streamErrorRegistration();
hlsDestroy(this.hls);
this.restart(this.currentChannelStream);
}
Comment thread web/js/MonitorStream.js
Comment on lines +1824 to 1828
if (!data || !data.fatal) return;
this.updateStreamInfo('', 'Error'); //HLS
this.streamErrorRegistration();
if (!data || !data.fatal) return;
this.hls.destroy();
hlsDestroy(this.hls);
this.restart(this.currentChannelStream);
@connortechnology
connortechnology merged commit 889b5da into ZoneMinder:master Jul 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants