mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-03-26 17:52:30 -04:00
Merge pull request #4682 from IgorA100/patch-723160
Fix: Remove unused listeners when stopping a stream.
This commit is contained in:
@@ -30,6 +30,7 @@ function MonitorStream(monitorData) {
|
||||
this.wsMSE = null;
|
||||
this.streamStartTime = 0; // Initial point of flow start time. Used for flow lag time analysis.
|
||||
this.waitingStart;
|
||||
this.handlerEventListener = {};
|
||||
this.mseListenerSourceopenBind = null;
|
||||
this.streamListenerBind = null;
|
||||
this.mseSourceBufferListenerUpdateendBind = null;
|
||||
@@ -441,7 +442,7 @@ function MonitorStream(monitorData) {
|
||||
clearInterval(this.statusCmdTimer); // Fix for issues in Chromium when quickly hiding/showing a page. Doesn't clear statusCmdTimer when minimizing a page https://stackoverflow.com/questions/9501813/clearinterval-not-working
|
||||
this.statusCmdTimer = setInterval(this.statusCmdQuery.bind(this), statusRefreshTimeout);
|
||||
this.started = true;
|
||||
this.streamListenerBind();
|
||||
this.handlerEventListener['killStream'] = this.streamListenerBind();
|
||||
|
||||
if (typeof observerMontage !== 'undefined') observerMontage.observe(stream);
|
||||
this.activePlayer = 'go2rtc';
|
||||
@@ -482,7 +483,7 @@ function MonitorStream(monitorData) {
|
||||
attachVideo(this);
|
||||
this.statusCmdTimer = setInterval(this.statusCmdQuery.bind(this), statusRefreshTimeout);
|
||||
this.started = true;
|
||||
this.streamListenerBind();
|
||||
this.handlerEventListener['killStream'] = this.streamListenerBind();
|
||||
this.activePlayer = 'janus';
|
||||
this.updateStreamInfo('Janus', 'loading');
|
||||
return;
|
||||
@@ -554,7 +555,7 @@ function MonitorStream(monitorData) {
|
||||
clearInterval(this.statusCmdTimer); // Fix for issues in Chromium when quickly hiding/showing a page. Doesn't clear statusCmdTimer when minimizing a page https://stackoverflow.com/questions/9501813/clearinterval-not-working
|
||||
this.statusCmdTimer = setInterval(this.statusCmdQuery.bind(this), statusRefreshTimeout);
|
||||
this.started = true;
|
||||
this.streamListenerBind();
|
||||
this.handlerEventListener['killStream'] = this.streamListenerBind();
|
||||
this.updateStreamInfo((typeof players !== "undefined" && players) ? players[this.activePlayer] : 'RTSP2Web ' + this.RTSP2WebType, 'loading');
|
||||
return;
|
||||
} else {
|
||||
@@ -618,12 +619,14 @@ function MonitorStream(monitorData) {
|
||||
}
|
||||
} // end if paused or not
|
||||
this.started = true;
|
||||
this.streamListenerBind();
|
||||
this.handlerEventListener['killStream'] = this.streamListenerBind();
|
||||
this.activePlayer = 'zms';
|
||||
this.updateStreamInfo('ZMS MJPEG');
|
||||
}; // this.start
|
||||
|
||||
this.stop = function() {
|
||||
manageEventListener.removeEventListener(this.handlerEventListener['killStream']);
|
||||
|
||||
/* Stop should stop the stream (killing zms) but NOT set src=''; This leaves the last jpeg up on screen instead of a broken image */
|
||||
const stream = this.getElement();
|
||||
if (!stream) {
|
||||
@@ -1976,10 +1979,10 @@ function startRTSP2WebPlay(videoEl, url, stream) {
|
||||
}
|
||||
|
||||
function streamListener(stream) {
|
||||
window.addEventListener('beforeunload', function(event) {
|
||||
return manageEventListener.addEventListener(window, 'beforeunload', function() {
|
||||
console.log('streamListener');
|
||||
stream.kill();
|
||||
});
|
||||
}, {capture: false});
|
||||
}
|
||||
|
||||
function mseListenerSourceopen(context, videoEl, url) {
|
||||
|
||||
@@ -2867,4 +2867,45 @@ const waitUntil = (condition, timeout = 0) => {
|
||||
});
|
||||
};
|
||||
|
||||
// https://stackoverflow.com/a/69273090
|
||||
class ManageEventListener {
|
||||
#listeners = {}; // # in a JS class signifies private
|
||||
#idx = 1;
|
||||
|
||||
// add event listener, returns integer ID of new listener
|
||||
addEventListener(element, type, listener, options = {}) {
|
||||
this.#privateAddEventListener(element, this.#idx, type, listener, options);
|
||||
return this.#idx++;
|
||||
}
|
||||
|
||||
// add event listener with custom ID (avoids need to retrieve return ID since you are providing it yourself)
|
||||
addEventListenerById(element, id, type, listener, options = {}) {
|
||||
this.#privateAddEventListener(element, id, type, listener, options);
|
||||
return id;
|
||||
}
|
||||
|
||||
#privateAddEventListener(element, id, type, listener, options) {
|
||||
if (this.#listeners[id]) throw Error(`A listener with id ${id} already exists`);
|
||||
element.addEventListener(type, listener, options);
|
||||
this.#listeners[id] = {element, type, listener, options};
|
||||
}
|
||||
|
||||
// remove event listener with given ID, returns ID of removed listener or null (if listener with given ID does not exist)
|
||||
removeEventListener(id) {
|
||||
const listen = this.#listeners[id];
|
||||
if (listen) {
|
||||
listen.element.removeEventListener(listen.type, listen.listener, listen.options);
|
||||
delete this.#listeners[id];
|
||||
}
|
||||
return !!listen ? id : null;
|
||||
}
|
||||
|
||||
// returns number of events listeners
|
||||
length() {
|
||||
return Object.keys(this.#listeners).length;
|
||||
}
|
||||
}
|
||||
const manageEventListener = new ManageEventListener();
|
||||
window.manageEventListener = manageEventListener;
|
||||
|
||||
$j( window ).on("load", initPageGeneral);
|
||||
|
||||
Reference in New Issue
Block a user