@stormstreaming/stormstreamer 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.0.5
4
+
5
+ Bugfix for destroying Network Controller,
6
+
7
+ ## 1.0.4
8
+
9
+ Bugfix for initialize() & start() methods race condition,
10
+
3
11
  ## 1.0.3
4
12
 
5
13
  A bug with undefined streamKey in stream status connection has been fixed,
package/dist/amd/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  * contact@stormstreaming.com
5
5
  * https://stormstreaming.com
6
6
  *
7
- * Version: 1.0.3
8
- * Version: 2/19/2026, 10:00:24 AM
7
+ * Version: 1.0.5
8
+ * Version: 2/20/2026, 10:02:22 AM
9
9
  *
10
10
  * LEGAL NOTICE:
11
11
  * This software is subject to the terms and conditions defined in
@@ -4437,6 +4437,7 @@
4437
4437
  */
4438
4438
  this._boundCameraPermissionHandler = null;
4439
4439
  this._boundMicrophonePermissionHandler = null;
4440
+ this._isInitializing = false;
4440
4441
  /**
4441
4442
  * Handles device state changes and initiates publishing if appropriate
4442
4443
  * @private
@@ -4596,10 +4597,10 @@
4596
4597
  if (this._publishState == exports.PublishState.CONNECTED && update.publishState == exports.PublishState.PUBLISHED) this.setPublishState(exports.PublishState.PUBLISHED);
4597
4598
  };
4598
4599
  this.onDescriptionSuccess = description => {
4599
- var _a, _b;
4600
+ var _a, _b, _c;
4600
4601
  if (this._isDestroyed) return;
4601
4602
  const streamInfo = {
4602
- applicationName: (_b = (_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.getConnection().getCurrentServer()) === null || _b === void 0 ? void 0 : _b.getApplication(),
4603
+ applicationName: (_c = (_b = (_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.getConnection()) === null || _b === void 0 ? void 0 : _b.getCurrentServer()) === null || _c === void 0 ? void 0 : _c.getApplication(),
4603
4604
  streamName: this._fullStreamName,
4604
4605
  sessionId: "[empty]"
4605
4606
  };
@@ -4684,6 +4685,8 @@
4684
4685
  initialize() {
4685
4686
  var _a, _b;
4686
4687
  return __awaiter(this, void 0, void 0, function* () {
4688
+ if (this._isInitializing) return;
4689
+ this._isInitializing = true;
4687
4690
  this._logger.info(this, "📹 [INIT] initialize() - starting initialization");
4688
4691
  try {
4689
4692
  if (this.isDestroyedCheck("initialize start")) return;
@@ -4712,6 +4715,8 @@
4712
4715
  }
4713
4716
  this._logger.error(this, "Initialization failed: " + JSON.stringify(error));
4714
4717
  this.setInputDeviceState(exports.InputDevicesState.INVALID);
4718
+ } finally {
4719
+ this._isInitializing = false;
4715
4720
  }
4716
4721
  this._main.dispatchEvent("microphoneStateChange", {
4717
4722
  ref: this._main,
@@ -5974,7 +5979,10 @@
5974
5979
  start() {
5975
5980
  var _a, _b, _c;
5976
5981
  return __awaiter(this, void 0, void 0, function* () {
5977
- if (this._isDestroyed) return;
5982
+ if (this._isDestroyed || this._isInitializing) {
5983
+ this._logger.warning(this, "📹 [START] start() - skipped (destroyed or already initializing)");
5984
+ return;
5985
+ }
5978
5986
  if (this._publishState !== exports.PublishState.STOPPED && this._publishState !== exports.PublishState.NOT_INITIALIZED) {
5979
5987
  this._logger.warning(this, "📹 [START] start() - already running, ignoring");
5980
5988
  return;
@@ -6316,6 +6324,11 @@
6316
6324
  * @param main reference to the main class
6317
6325
  */
6318
6326
  constructor(main) {
6327
+ /**
6328
+ * Object containing WebSocket Connection (only one is needed)
6329
+ * @private
6330
+ */
6331
+ this._connection = null;
6319
6332
  /**
6320
6333
  * Current streamKey
6321
6334
  * @private
@@ -6326,6 +6339,7 @@
6326
6339
  * @private
6327
6340
  */
6328
6341
  this._lastState = "";
6342
+ this._isDestroyed = false;
6329
6343
  //------------------------------------------------------------------------//
6330
6344
  // CONNECTION-RELATED METHODS
6331
6345
  //------------------------------------------------------------------------//
@@ -6348,6 +6362,7 @@
6348
6362
  // MAIN METHODS
6349
6363
  //------------------------------------------------------------------------//
6350
6364
  initialize() {
6365
+ if (this._isDestroyed) return;
6351
6366
  if (this._connection != null) {
6352
6367
  if (this._connection.getConnectionState() == ConnectionState.CONNECTING || this._connection.getConnectionState() == ConnectionState.CONNECTED) {
6353
6368
  this._logger.info(this, "Connection is alive, not doing anything!");
@@ -6361,10 +6376,12 @@
6361
6376
  this._connection = new WowzaConnection(this._main, this);
6362
6377
  }
6363
6378
  stop() {
6364
- this._connection.disconnect(true);
6379
+ var _a;
6380
+ (_a = this._connection) === null || _a === void 0 ? void 0 : _a.disconnect(true);
6365
6381
  this._lastState = "";
6366
6382
  }
6367
6383
  sendMessage(message) {
6384
+ if (this._isDestroyed || !this._connection) return;
6368
6385
  if (this._connection.isConnectionActive()) {
6369
6386
  this._connection.sendData(message);
6370
6387
  }
@@ -6384,6 +6401,16 @@
6384
6401
  getCurrentStreamKey() {
6385
6402
  return this._currentStreamKey;
6386
6403
  }
6404
+ destroy() {
6405
+ this._isDestroyed = true;
6406
+ // Odepnij listenery
6407
+ this._main.removeEventListener("serverConnect", this.onServerConnect);
6408
+ this._main.removeEventListener("serverDisconnect", this.onServerDisconnect);
6409
+ if (this._connection) {
6410
+ this._connection.destroy();
6411
+ this._connection = null;
6412
+ }
6413
+ }
6387
6414
  }
6388
6415
 
6389
6416
  class StatsController {
@@ -6727,8 +6754,8 @@
6727
6754
  constructor(streamConfig, autoInitialize = false) {
6728
6755
  super();
6729
6756
  this.DEV_MODE = true;
6730
- this.STREAMER_VERSION = "1.0.3";
6731
- this.COMPILE_DATE = "2/19/2026, 10:00:22 AM";
6757
+ this.STREAMER_VERSION = "1.0.5";
6758
+ this.COMPILE_DATE = "2/20/2026, 10:02:20 AM";
6732
6759
  this.STREAMER_BRANCH = "Experimental";
6733
6760
  this.STREAMER_PROTOCOL_VERSION = 1;
6734
6761
  this._initialized = false;
@@ -6788,8 +6815,8 @@
6788
6815
  }
6789
6816
  // PLAYBACK / STREAMING
6790
6817
  isConnected() {
6791
- var _a, _b;
6792
- return (_b = (_a = this._networkController) === null || _a === void 0 ? void 0 : _a.getConnection().isConnectionActive()) !== null && _b !== void 0 ? _b : false;
6818
+ var _a, _b, _c;
6819
+ return (_c = (_b = (_a = this._networkController) === null || _a === void 0 ? void 0 : _a.getConnection()) === null || _b === void 0 ? void 0 : _b.isConnectionActive()) !== null && _c !== void 0 ? _c : false;
6793
6820
  }
6794
6821
  mute() {
6795
6822
  var _a;
@@ -7075,7 +7102,7 @@
7075
7102
  * All pending async operations will detect the destroyed state and abort.
7076
7103
  */
7077
7104
  destroy() {
7078
- var _a, _b, _c, _d, _e, _f, _g;
7105
+ var _a, _b, _c, _d, _e, _f;
7079
7106
  // Prevent double destroy
7080
7107
  if (this._isDestroyed) {
7081
7108
  (_a = this._logger) === null || _a === void 0 ? void 0 : _a.warning(this, "🔴 [DESTROY] Already destroyed, skipping");
@@ -7093,23 +7120,20 @@
7093
7120
  // Stop all graphs
7094
7121
  this.stopAllGraphs();
7095
7122
  this._graphs = [];
7096
- // Destroy network controller
7097
7123
  if (this._networkController) {
7098
7124
  (_c = this._logger) === null || _c === void 0 ? void 0 : _c.info(this, "🔴 [DESTROY] Destroying NetworkController...");
7099
- try {
7100
- (_d = this._networkController.getConnection()) === null || _d === void 0 ? void 0 : _d.destroy();
7101
- } catch (e) {/* ignore */}
7125
+ this._networkController.destroy(); // zamiast ręcznego getConnection()?.destroy()
7102
7126
  this._networkController = null;
7103
7127
  }
7104
7128
  // Destroy streamer controller (this is also sync now)
7105
7129
  if (this._streamerController) {
7106
- (_e = this._logger) === null || _e === void 0 ? void 0 : _e.info(this, "🔴 [DESTROY] Destroying StreamerController...");
7130
+ (_d = this._logger) === null || _d === void 0 ? void 0 : _d.info(this, "🔴 [DESTROY] Destroying StreamerController...");
7107
7131
  this._streamerController.destroy();
7108
7132
  this._streamerController = null;
7109
7133
  }
7110
7134
  // Destroy stage controller
7111
7135
  if (this._stageController) {
7112
- (_f = this._logger) === null || _f === void 0 ? void 0 : _f.info(this, "🔴 [DESTROY] Destroying StageController...");
7136
+ (_e = this._logger) === null || _e === void 0 ? void 0 : _e.info(this, "🔴 [DESTROY] Destroying StageController...");
7113
7137
  try {
7114
7138
  this._stageController.destroy();
7115
7139
  } catch (e) {/* ignore */}
@@ -7120,7 +7144,7 @@
7120
7144
  this._statsController = null;
7121
7145
  // Remove all event listeners
7122
7146
  this.removeAllEventListeners();
7123
- (_g = this._logger) === null || _g === void 0 ? void 0 : _g.success(this, "🔴 [DESTROY] Streamer instance destroyed successfully (sync)");
7147
+ (_f = this._logger) === null || _f === void 0 ? void 0 : _f.success(this, "🔴 [DESTROY] Streamer instance destroyed successfully (sync)");
7124
7148
  }
7125
7149
  }
7126
7150
  StormStreamer.NEXT_STREAMER_ID = 0;
package/dist/cjs/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  * contact@stormstreaming.com
5
5
  * https://stormstreaming.com
6
6
  *
7
- * Version: 1.0.3
8
- * Version: 2/19/2026, 10:00:24 AM
7
+ * Version: 1.0.5
8
+ * Version: 2/20/2026, 10:02:22 AM
9
9
  *
10
10
  * LEGAL NOTICE:
11
11
  * This software is subject to the terms and conditions defined in
@@ -31,4 +31,4 @@ b=TIAS:${1e3*(1e3*l*.95-16e3)}\r
31
31
  `+`b=CT:${l}\r
32
32
  `)+`a=framerate:${i}\r
33
33
  `)+`a=max-fr:${i}\r
34
- `;continue}s+="\r\n"}return s}mungeSDPPlay(e){let s="";for(const o of e.split(/\r\n/))if(0!==o.length){if(o.includes("profile-level-id")){var n=o.substr(o.indexOf("profile-level-id")+17,6);let e=Number("0x"+n.substr(0,2)),t=Number("0x"+n.substr(2,2)),i=Number("0x"+n.substr(4,2));66<e&&(e=66,t=224,i=31),0===t&&(t=224);var r=("00"+e.toString(16)).slice(-2).toLowerCase()+("00"+t.toString(16)).slice(-2).toLowerCase()+("00"+i.toString(16)).slice(-2).toLowerCase();s+=o.replace(n,r)}else s+=o;s+="\r\n"}return s}}MungeSDP.SDPOutput={},function(e){e[e.VIDEO_INPUT=0]="VIDEO_INPUT",e[e.AUDIO_INPUT=1]="AUDIO_INPUT"}(InputType=InputType||{});class InputDevice{constructor(e,t){if(this._groupID="",this._isSelected=!1,null==e)throw new Error("no input device");if(void 0===e.deviceId||null===e.deviceId)throw new Error("no deviceID");if(this._id=e.deviceId,void 0===e.kind||null===e.kind)throw new Error("no device kind");switch(e.kind){case"videoinput":this._inputType=InputType.VIDEO_INPUT;break;case"audioinput":this._inputType=InputType.AUDIO_INPUT;break;default:throw new Error("incorrect kind")}null!==e.label&&""!==e.label?this._label=this.cleanLabel(e.label):this._label=this._inputType==InputType.VIDEO_INPUT?"Camera "+t:"Microphone "+t,void 0!==e.groupId&&null!==e.groupId&&(this._groupID=e.groupId)}cleanLabel(e){return e}get label(){return this._label}get id(){return this._id}get groupID(){return this._groupID}get isSelected(){return this._isSelected}set isSelected(e){this._isSelected=e}}class InputDeviceList{constructor(){this._internalList=new Array}push(t){let i=!1;if(0<this._internalList.length){for(let e=0;e<this._internalList.length;e++)""!==this._internalList[e].groupID&&this._internalList[e].groupID==t.groupID&&(i=!0,this._internalList[e]=t);return 0==i?this._internalList.push(t):this._internalList.length}return this._internalList.push(t)}get(e){return this._internalList[e]}getSize(){return this._internalList.length}getArray(){return this._internalList}}exports.PublishState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.INITIALIZED="INITIALIZED",e.CONNECTING="CONNECTING",e.CONNECTED="CONNECTED",e.PUBLISHED="PUBLISHED",e.UNPUBLISHED="UNPUBLISHED",e.STOPPED="STOPPED",e.UNKNOWN="UNKNOWN",e.ERROR="ERROR"}(exports.PublishState||(exports.PublishState={}));class SoundMeter{constructor(e){this._audioContext=null,this._analyser=null,this._microphone=null,this._lastEventTime=0,this.THROTTLE_INTERVAL=100,this._isMonitoring=!1,this._animationFrameId=null,this._instant=0,this._slow=0,this.PEAK_DECAY=.92,this._main=e}attach(e){if(e.getAudioTracks().length){this.detach();try{this._audioContext=new AudioContext,this._microphone=this._audioContext.createMediaStreamSource(e),this._analyser=this._audioContext.createAnalyser(),this._analyser.fftSize=2048,this._microphone.connect(this._analyser),this.startMonitoring()}catch(e){console.error("SoundMeter: Error during attach:",e),this.detach()}}else console.warn("SoundMeter: Attempted to attach stream without audio tracks")}detach(){if(this._audioContext||this._analyser||this._microphone){if(this._isMonitoring=!1,null!==this._animationFrameId&&(cancelAnimationFrame(this._animationFrameId),this._animationFrameId=null),this._microphone){try{this._microphone.disconnect()}catch(e){console.warn("SoundMeter: Error disconnecting microphone:",e)}this._microphone=null}if(this._analyser){try{this._analyser.disconnect()}catch(e){console.warn("SoundMeter: Error disconnecting analyser:",e)}this._analyser=null}if(this._audioContext)try{if("closed"!==this._audioContext.state){const e=this._audioContext;this._audioContext=null,e.suspend().then(()=>e.close()).catch(e=>{console.warn("SoundMeter: Error closing audio context:",e)})}else this._audioContext=null}catch(e){console.warn("SoundMeter: Error handling audio context:",e),this._audioContext=null}this.clear()}}clear(){this._instant=0,this._slow=0,this._lastEventTime=0}startMonitoring(){if(this._analyser&&!this._isMonitoring){this._isMonitoring=!0;const s=new Float32Array(this._analyser.frequencyBinCount),t=()=>{if(this._analyser&&this._isMonitoring&&this._audioContext){var e=Date.now();try{this._analyser.getFloatTimeDomainData(s);let t=0;for(let e=0;e<s.length;++e){var i=Math.abs(s[e]);i>t&&(t=i)}this._instant=Math.min(1,t),this._instant>this._slow?this._slow=this._instant:this._slow*=this.PEAK_DECAY,e-this._lastEventTime>=this.THROTTLE_INTERVAL&&(this._lastEventTime=e,this._main.dispatchEvent("soundMeter",{ref:this._main,high:this._instant,low:this._slow}))}catch(e){return console.error("SoundMeter: Error during analysis:",e),this._isMonitoring=!1,void(this._animationFrameId=null)}this._isMonitoring&&(this._animationFrameId=requestAnimationFrame(t))}else this._animationFrameId=null};this._animationFrameId=requestAnimationFrame(t)}}destroy(){this.detach()}}exports.InputDevicesState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.INITIALIZED="INITIALIZED",e.READY="READY",e.UPDATING="UPDATING",e.INVALID="INVALID",e.UNKNOWN="UNKNOWN",e.STOPPED="STOPPED"}(exports.InputDevicesState||(exports.InputDevicesState={})),exports.DeviceState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.ENABLED="ENABLED",e.ACCESS_DENIED="ACCESS_DENIED",e.NOT_FOUND="NOT_FOUND",e.STOPPED="STOPPED"}(exports.DeviceState||(exports.DeviceState={})),function(e){e[e.NOT_INITIALIZED=0]="NOT_INITIALIZED",e[e.STARTED=1]="STARTED",e[e.CONNECTING=2]="CONNECTING",e[e.CONNECTED=3]="CONNECTED",e[e.CLOSED=4]="CLOSED",e[e.FAILED=5]="FAILED"}(ConnectionState=ConnectionState||{});class AbstractSocket{constructor(){this.CONNECTION_TIMEOUT=5,this.isBinary=!0,this._connectionState=ConnectionState.NOT_INITIALIZED,this._messageCount=0,this._disconnectedByUser=!1,this._isConnected=!1,this._sequenceNumber=-1}startConnection(){this._disconnectedByUser=!1,this._messageCount=0,this._isConnected=!1,this._disconnectedByUser=!1,this._connectionState=ConnectionState.CONNECTING,this.socket=new WebSocket(this.socketURL),this.isBinary&&(this.socket.binaryType="arraybuffer"),this.socket.onopen=e=>{clearTimeout(this._connectionTimeout),this._sequenceNumber++,this._connectionState=ConnectionState.CONNECTED,this.onSocketOpen(e)},this.socket.onmessage=e=>{this._messageCount++,this.onSocketMessage(e)},this.socket.onclose=e=>{clearTimeout(this._connectionTimeout),this._connectionState==ConnectionState.CONNECTED?(this._connectionState=ConnectionState.CLOSED,this.onSocketClose(e)):this._connectionState=ConnectionState.FAILED},this.socket.onerror=e=>{if(clearTimeout(this._connectionTimeout),this._connectionState==ConnectionState.CONNECTING&&this.onSocketError(e),this._connectionState==ConnectionState.CONNECTED)try{this.socket.close()}catch(e){}},this._connectionTimeout=setTimeout(()=>{try{this.socket.close()}catch(e){}this._connectionState==ConnectionState.CONNECTING&&(this._connectionState=ConnectionState.FAILED,this.onSocketError(new ErrorEvent("connectionTimeout")))},1e3*this.CONNECTION_TIMEOUT)}onSocketOpen(e){}onSocketClose(e){}onSocketMessage(e){}onSocketError(e){}onError(e){}sendData(e){if(this._connectionState==ConnectionState.CONNECTED&&null!==this.socket){if(null!=e)return void this.socket.send(e);this.onError("no data to send")}this.onError("socket not connected")}getConnectionState(){return this._connectionState}disconnect(e=!0){this._isConnected=!1,this._connectionState=ConnectionState.CLOSED,e&&(this._logger.warning(this,"Disconnected by user"),this._disconnectedByUser=e),null!=this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onclose=null,this.socket.onerror=null,this.socket.close())}destroy(){void 0!==this.socket&&null!==this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onclose=null,this.socket.onerror=null,this.socket.close()),this._connectionState=ConnectionState.CLOSED}getSocketURL(){return this.socketURL}}class StreamStatusInfo{constructor(){this._publishState=exports.PublishState.NOT_INITIALIZED,this._videoPublishBitrate=0,this._audioPublishBitrate=0,this._currentBitrate=0,this._audioFrameCount=0,this._videoFrameCount=0,this._frameRate=0,this._videoWidth=0,this._videoHeight=0}get publishState(){return this._publishState}set publishState(e){this._publishState="published"===e?exports.PublishState.PUBLISHED:exports.PublishState.CONNECTED}get videoPublishBitrate(){return this._videoPublishBitrate}set videoPublishBitrate(e){this._videoPublishBitrate=e}get audioPublishBitrate(){return this._audioPublishBitrate}set audioPublishBitrate(e){this._audioPublishBitrate=e}set currentBitrate(e){this._currentBitrate=e}get currentBitrate(){return this._currentBitrate}get audioFrameCount(){return this._audioFrameCount}set audioFrameCount(e){this._audioFrameCount=e}get videoFrameCount(){return this._videoFrameCount}set videoFrameCount(e){this._videoFrameCount=e}get frameRate(){return this._frameRate}set frameRate(e){this._frameRate=e}set videoWidth(e){this._videoWidth=e}get videoWidth(){return this._videoWidth}set videoHeight(e){this._videoHeight=e}get videoHeight(){return this._videoHeight}}class WowzaStatusConnection extends AbstractSocket{constructor(e,t){super(),this._logger=e.getLogger(),this._main=e,this._currServer=t,this.initialize()}initialize(){this._logger.info(this,"Starting new status check connection with a storm server"),null!=this._currServer?(this.socketURL=this.createURL(this._currServer),this._logger.info(this,"Starting WebSocket connection with: "+this.socketURL),this.startConnection()):this._logger.error(this,"Connection with the server could not be initialized!")}onSocketOpen(e){this._logger.success(this,"Connection with the server has been established!"),this._main.dispatchEvent("statusServerConnect",{ref:this._main,serverURL:this.socketURL,sequenceNum:this._sequenceNumber}),this._isConnected=!0}onSocketError(e){this._isConnected=!1,this._disconnectedByUser||(this._logger.error(this,"Connection with the server failed"),this._main.dispatchEvent("serverConnectionError",{ref:this._main,serverURL:this.socketURL,restart:this._main.getConfigManager().getSettingsData().getIfRestartOnError(),sequenceNum:this._sequenceNumber}))}onSocketClose(e){this._isConnected=!1,this._disconnectedByUser?this._logger.warning(this,"Force disconnect from server!"):(this._logger.error(this,"Connection with the server has been closed"),this._main.dispatchEvent("statusServerDisconnect",{ref:this._main,serverURL:this.socketURL,restart:this._main.getConfigManager().getSettingsData().getIfRestartOnError(),sequenceNum:this._sequenceNumber}),this.initiateReconnect())}onSocketMessage(e){var t;"string"==typeof e.data&&"STREAM_STATUS_RESPONSE"===(e=JSON.parse(e.data)).packetID&&((t=new StreamStatusInfo).publishState=e.streamStatus,t.videoPublishBitrate=e.publishVideoBitrate,t.audioPublishBitrate=e.publishAudioBitrate,t.videoFrameCount=e.videoFrameCount,t.audioFrameCount=e.audioFrameCount,t.frameRate=e.frameRate,t.videoWidth=e.videoWidth,t.videoHeight=e.videoHeight,t.currentBitrate=e.realBitrate,this._main.dispatchEvent("streamStatusUpdate",{ref:this._main,streamStatus:t}))}initiateReconnect(){var e=this._main.getConfigManager().getSettingsData().getIfRestartOnError();const t=this._main.getConfigManager().getSettingsData().getReconnectTime();this._disconnectedByUser||e&&(null!=this._reconnectTimer&&clearTimeout(this._reconnectTimer),this._reconnectTimer=setTimeout(()=>{null!=this._currServer&&(this._logger.info(this,`Will reconnect to the server in ${t} seconds...`),this.socketURL=this.createURL(this._currServer),this._logger.info(this,"Starting WebSocket connection with: "+this.socketURL),this._main.dispatchEvent("serverConnectionInitiate",{ref:this._main,serverURL:this.socketURL}),this.startConnection())},1e3*t))}createURL(e){var t="";return(t+=e.getIfSSL()?"wss://":"ws://")+e.getHost()+(":"+e.getPort())+"/statuschecker"}isConnectionActive(){return this._isConnected}getCurrentServer(){return this._currServer}destroy(){super.destroy()}}class PublishMetadata{constructor(){this._streamWidth=0,this._streamHeight=0,this._aspectRatio="",this._hasVideoTrack=!1,this._hasAudioTrack=!1}get streamWidth(){return this._streamWidth}set streamWidth(e){this._streamWidth=e}get streamHeight(){return this._streamHeight}set streamHeight(e){this._streamHeight=e}get aspectRatio(){return this._aspectRatio}set aspectRatio(e){this._aspectRatio=e}get videoTrackPresent(){return this._hasVideoTrack}set videoTrackPresent(e){this._hasVideoTrack=e}get audioTrackPresent(){return this._hasAudioTrack}set audioTrackPresent(e){this._hasAudioTrack=e}}class StreamerController{constructor(e){this._isWindowActive=!0,this._peerConnectionConfig={iceServers:[]},this._isMicrophoneMuted=!1,this._pendingMicrophoneState=null,this._permissionChecked=!1,this._constraints={video:{width:{min:"640",ideal:"1024",max:"1024"},height:{min:"360",ideal:"576",max:"576"},frameRate:{min:24,ideal:30,max:30}},audio:!0},this._restartTimerCount=0,this._restartTimerMaxCount=5,this._publishState=exports.PublishState.NOT_INITIALIZED,this._publishTime=0,this._inputDeviceState=exports.InputDevicesState.NOT_INITIALIZED,this._cameraState=exports.DeviceState.NOT_INITIALIZED,this._microphoneState=exports.DeviceState.NOT_INITIALIZED,this._publishTimer=0,this._currentOrientation=(null==(t=window.screen.orientation)?void 0:t.type)||"",this._statusTimer=null,this._debug=!1,this._deviceChangeHandler=null,this._orientationChangeHandler=null,this._isDestroyed=!1,this._cameraAbortController=null,this._microphoneAbortController=null,this._startCameraAbortController=null,this._switchingCamera=!1,this._switchingMicrophone=!1,this._firstPublish=!0,this._activeStreamCount=0,this._cameraPermissionStatus=null,this._microphonePermissionStatus=null,this._boundCameraPermissionHandler=null,this._boundMicrophonePermissionHandler=null,this.onDeviceStateChange=e=>{var t;this._isDestroyed||(t=null==(t=this._main.getConfigManager())?void 0:t.getStreamData().streamKey,e.state==exports.InputDevicesState.READY&&null!=t&&this.internalPublish(t))},this.handleOrientationChange=()=>__awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed&&(yield new Promise(e=>setTimeout(e,500)),!this._isDestroyed)){var e=(null==(e=window.screen.orientation)?void 0:e.type)||"";if(this._currentOrientation!==e){this._logger.info(this,`Orientation changed from ${this._currentOrientation} to `+e),this._currentOrientation=e;e=null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey;if(this._publishState,exports.PublishState.PUBLISHED,this.closeWebRTCConnection(),this._stream&&(this._logger.info(this,"📹 [RELEASE] handleOrientationChange() - releasing stream for orientation change"),this._stream.getTracks().forEach(e=>{e.stop(),this._logger.info(this,"📹 [RELEASE] handleOrientationChange() - stopped track: "+e.kind)}),this._stream=null,this._activeStreamCount--),!this._isDestroyed)try{yield this.startCamera(),this._isDestroyed||e&&this.internalPublish(e)}catch(e){this._isDestroyed||(this._logger.error(this,"Error restarting stream after orientation change: "+JSON.stringify(e)),this.setInputDeviceState(exports.InputDevicesState.INVALID))}}}}),this.onServerDisconnect=()=>{},this.onStreamKeyTaken=()=>{this._isDestroyed||(null!=this._restartTimer&&(clearInterval(this._restartTimer),this._restartTimerCount=0),this._logger.info(this,"WebRTCStreamer :: Starting StreamKeyTaken Interval"),this.setPublishState(exports.PublishState.ERROR),this._restartTimer=setInterval(()=>{var e;this._isDestroyed?this._restartTimer&&clearInterval(this._restartTimer):null!=this._restartTimer&&(this._restartTimerCount<this._restartTimerMaxCount?(this._logger.info(this,"WebRTCStreamer :: StreamKeyTaken Interval: "+this._restartTimerCount+"/"+this._restartTimerMaxCount),this._restartTimerCount++):(clearInterval(this._restartTimer),this._restartTimer=null,this._restartTimerCount=0,null==(e=null==(e=null==(e=this._main.getConfigManager())?void 0:e.getStreamData())?void 0:e.streamKey)||this._isDestroyed||this.internalPublish(e)),this._isDestroyed||(e=null!=(e=this._main.getConfigManager().getStreamData().streamKey)?e:"unknown",this._main.dispatchEvent("streamKeyInUseInterval",{ref:this._main,streamKey:e,count:this._restartTimerCount,maxCount:this._restartTimerMaxCount})))},1e3))},this.onServerConnect=()=>{if(!this._isDestroyed){if(this._peerConnection&&this.closeWebRTCConnection(),this._peerConnection=new RTCPeerConnection(this._peerConnectionConfig),this._stream){var e,t=this._stream.getTracks();for(e in t)this._peerConnection.addTrack(t[e],this._stream)}this._peerConnection.onicecandidate=e=>{this.onIceCandidate(e)},this._peerConnection.onconnectionstatechange=e=>{this.onConnectionStateChange(e)},this._peerConnection.onnegotiationneeded=e=>__awaiter(this,void 0,void 0,function*(){if(this._peerConnection&&!this._isDestroyed)try{var e=yield this._peerConnection.createOffer();this._isDestroyed||(yield this.onDescriptionSuccess(e))}catch(e){this.onDescriptionError(e)}}),this.createStatusConnection()}},this.onStatusServerConnect=()=>{var e;this._isDestroyed||(e=this._main.getConfigManager().getStreamData().streamKey,null==this._statusTimer&&null!=this._statusConnection&&null!=e&&(this._statusTimer=setInterval(()=>{this._isDestroyed?this._statusTimer&&clearInterval(this._statusTimer):this.requestStatusData()},1e3)))},this.requestStatusData=()=>{var e;!this._isDestroyed&&this._fullStreamName&&null!=(e=this._statusConnection)&&e.sendData('{"packetID":"STREAM_STATUS", "streamKey": "'+this._fullStreamName+'"}')},this.onStatusServerDisconnect=()=>{null!=this._statusTimer&&clearInterval(this._statusTimer),this._statusTimer=null},this.onStreamStatsUpdate=e=>{this._isDestroyed||(e=e.streamStatus,this._publishState==exports.PublishState.PUBLISHED&&e.publishState!=exports.PublishState.PUBLISHED&&this.setPublishState(exports.PublishState.UNPUBLISHED),this._publishState==exports.PublishState.CONNECTED&&e.publishState==exports.PublishState.PUBLISHED&&this.setPublishState(exports.PublishState.PUBLISHED))},this.onDescriptionSuccess=t=>{var e;if(!this._isDestroyed){const i={applicationName:null==(e=null==(e=this._main.getNetworkController())?void 0:e.getConnection().getCurrentServer())?void 0:e.getApplication(),streamName:this._fullStreamName,sessionId:"[empty]"};t.sdp=this._mungeSDP.mungeSDPPublish(t.sdp,{audioBitrate:"64",videoBitrate:"2000",videoFrameRate:30,videoCodec:"42e01f",audioCodec:"opus"}),this._peerConnection&&!this._isDestroyed&&this._peerConnection.setLocalDescription(t).then(()=>{var e;this._isDestroyed||null!=(e=this._main.getNetworkController())&&e.sendMessage('{"direction":"publish", "command":"sendOffer", "streamInfo":'+JSON.stringify(i)+', "sdp":'+JSON.stringify(t)+"}")}).catch(e=>{console.log(e)})}},this.visibilityChange=()=>{"hidden"===document.visibilityState?this.onWindowBlur():"visible"===document.visibilityState&&this.onWindowFocus()},this.onWindowBlur=()=>{this._isWindowActive&&this._logger.warning(this,"Player window is no longer in focus!"),this._isWindowActive=!1},this.onWindowFocus=()=>{this._isWindowActive||this._logger.info(this,"Player window is focused again!"),this._isWindowActive=!0},this._main=e,this._logger=e.getLogger(),this._mungeSDP=new MungeSDP,this._soundMeter=new SoundMeter(this._main),this._debug=null!=(e=null==(t=this._main.getConfigManager())?void 0:t.getSettingsData().getDebugData().streamerControllerDebug)?e:this._debug;var t,e=null==(t=this._main.getStorageManager())?void 0:t.getField("microphoneMuted");null!==e&&(this._isMicrophoneMuted="true"===e,this._logger.info(this,"📹 [INIT] Restored microphone mute state: "+this._isMicrophoneMuted)),this.initialize()}isDestroyedCheck(e){var t;return!!this._isDestroyed&&(e&&null!=(t=this._logger)&&t.info(this,`📹 [ABORT] ${e} - instance destroyed, aborting`),!0)}initialize(){var e,t;return __awaiter(this,void 0,void 0,function*(){this._logger.info(this,"📹 [INIT] initialize() - starting initialization");try{if(this.isDestroyedCheck("initialize start"))return;if(yield this.initializeDevices(),this.isDestroyedCheck("after initializeDevices"))return;if(this.setupEventListeners(),this.isDestroyedCheck("after setupEventListeners"))return;if(this.initializeStream(),this.isDestroyedCheck("after initializeStream"))return;if(this.setupOrientationListener(),yield this.setupPermissionListeners(),this.isDestroyedCheck("after setupPermissionListeners"))return;if(this.setupDeviceChangeListener(),this.isDestroyedCheck("before network init"))return;null!=(e=this._main.getConfigManager())&&e.getSettingsData().autoConnect?(this._logger.info(this,"Initializing NetworkController (autoConnect is true)"),null!=(t=this._main.getNetworkController())&&t.initialize()):this._logger.warning(this,"Warning - autoConnect is set to false, switching to standby mode!"),this._logger.success(this,"📹 [INIT] initialize() - completed successfully")}catch(e){if(this._isDestroyed)return void this._logger.warning(this,"📹 [INIT] initialize() - aborted by destroy()");this._logger.error(this,"Initialization failed: "+JSON.stringify(e)),this.setInputDeviceState(exports.InputDevicesState.INVALID)}this._main.dispatchEvent("microphoneStateChange",{ref:this._main,isMuted:this._isMicrophoneMuted})})}setupEventListeners(){this._isDestroyed||(this._main.addEventListener("serverConnect",this.onServerConnect,!1),this._main.addEventListener("serverDisconnect",this.onServerDisconnect,!1),this._main.addEventListener("streamKeyInUse",this.onStreamKeyTaken,!1),this._main.addEventListener("statusServerConnect",this.onStatusServerConnect,!1),this._main.addEventListener("statusServerDisconnect",this.onStatusServerDisconnect,!1),this._main.addEventListener("streamStatusUpdate",this.onStreamStatsUpdate,!1),this._main.addEventListener("deviceStateChange",this.onDeviceStateChange,!1),document.addEventListener("visibilitychange",this.visibilityChange),window.addEventListener("blur",this.onWindowBlur),window.addEventListener("focus",this.onWindowFocus))}initializeDevices(){return __awaiter(this,void 0,void 0,function*(){try{var e;this._logger.info(this,"📹 [ACQUIRE] initializeDevices() - requesting test getUserMedia for permissions"),this.isDestroyedCheck("initializeDevices before getUserMedia")||(e=yield navigator.mediaDevices.getUserMedia({video:!0,audio:!0}),this._isDestroyed?(this._logger.warning(this,"📹 [RELEASE] initializeDevices() - destroyed during getUserMedia, releasing orphan stream"),e.getTracks().forEach(e=>{e.stop(),this._logger.info(this,`📹 [RELEASE] initializeDevices() - stopped orphan track: ${e.kind}, id: `+e.id)})):(this._logger.info(this,"📹 [RELEASE] initializeDevices() - stopping test stream immediately"),e.getTracks().forEach(e=>{e.stop(),this._logger.info(this,`📹 [RELEASE] initializeDevices() - stopped track: ${e.kind}, id: `+e.id)}),this.isDestroyedCheck("initializeDevices before grabDevices")||(yield this.grabDevices())))}catch(e){this._isDestroyed||(console.log(e),this._logger.error(this,"Error initializing devices: "+JSON.stringify(e)),this._isDestroyed)||(yield this.grabDevices())}})}initializeStream(){this._isDestroyed||(this._selectedCamera||this._selectedMicrophone)&&this.startCamera()}setupPermissionListeners(){return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed)try{var e={name:"camera"},t={name:"microphone"};this._cameraPermissionStatus=yield navigator.permissions.query(e),this._isDestroyed||(this._boundCameraPermissionHandler=()=>{this._isDestroyed||(this._permissionChecked=!1,this.handlePermissionChange("camera",this._cameraPermissionStatus.state))},this._cameraPermissionStatus.addEventListener("change",this._boundCameraPermissionHandler),this._microphonePermissionStatus=yield navigator.permissions.query(t),this._isDestroyed)||(this._boundMicrophonePermissionHandler=()=>{this._isDestroyed||(this._permissionChecked=!1,this.handlePermissionChange("microphone",this._microphonePermissionStatus.state))},this._microphonePermissionStatus.addEventListener("change",this._boundMicrophonePermissionHandler))}catch(e){this._logger.warning(this,"Could not set up permission listeners: "+e)}})}removePermissionListeners(){this._cameraPermissionStatus&&this._boundCameraPermissionHandler&&(this._cameraPermissionStatus.removeEventListener("change",this._boundCameraPermissionHandler),this._cameraPermissionStatus=null,this._boundCameraPermissionHandler=null),this._microphonePermissionStatus&&this._boundMicrophonePermissionHandler&&(this._microphonePermissionStatus.removeEventListener("change",this._boundMicrophonePermissionHandler),this._microphonePermissionStatus=null,this._boundMicrophonePermissionHandler=null)}setupDeviceChangeListener(){this._isDestroyed||(this._deviceChangeHandler=()=>__awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed)if(this._publishState===exports.PublishState.PUBLISHED)this._logger.info(this,"Device change detected, but already publish - no restarting streamer");else{this._logger.info(this,"Device change detected, restarting streamer");var e=null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey,t=this._publishState===exports.PublishState.CONNECTED;try{this.stop(),yield new Promise(e=>setTimeout(e,500)),this._isDestroyed||(yield this.start(),this._isDestroyed)||(t&&e&&(this._logger.info(this,"Resuming publishing after device change"),this.isStreamReady(!0,!0)?this.internalPublish(e):(this._logger.warning(this,"Cannot resume publishing - stream not ready after device change"),this._main.dispatchEvent("inputDeviceError",{ref:this._main}))),this._logger.success(this,"Successfully handled device change"))}catch(e){this._isDestroyed||(this._logger.error(this,"Error handling device change: "+JSON.stringify(e)),this.setInputDeviceState(exports.InputDevicesState.INVALID))}}}),navigator.mediaDevices.addEventListener("devicechange",this._deviceChangeHandler))}handlePermissionChange(e,t){return __awaiter(this,void 0,void 0,function*(){this._isDestroyed||(this._logger.info(this,`📹 [PERMISSION] handlePermissionChange() - device: ${e}, state: `+t),"denied"===t&&(this.setInputDeviceState(exports.InputDevicesState.INVALID),this._publishState!=exports.PublishState.CONNECTED&&!this._stream||(this._logger.info(this,"📹 [RELEASE] handlePermissionChange() - permission denied, stopping all streams"),this.stopCameraStream(),this.closeWebRTCConnection())),this._isDestroyed)||(yield this.grabDevices(),this._isDestroyed)||"granted"===t&&(yield this.startCamera())})}onCameraStreamSuccess(e){if(this._isDestroyed)this._logger.warning(this,"📹 [RELEASE] onCameraStreamSuccess() - destroyed, releasing stream immediately"),e.getTracks().forEach(e=>{e.stop()});else{this._activeStreamCount++,this._logger.success(this,`📹 [ACQUIRED] onCameraStreamSuccess() - stream acquired, id: ${e.id}, active streams: `+this._activeStreamCount);var s=e.getVideoTracks()[0],t=e.getAudioTracks()[0],n=new PublishMetadata;if(s){var r=s.getSettings();let e=r.width,t=r.height;/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)&&(e>t&&window.innerWidth<window.innerHeight||e<t&&window.innerWidth>window.innerHeight)&&([e,t]=[t,e]),n.streamWidth=e,n.streamHeight=t,n.videoTrackPresent=!0;const h=(e,t)=>t?h(t,e%t):e;var r=h(e,t),o=e/r,r=t/r,a=e/t;let i=o+":"+r;Math.abs(a-16/9)<.1?i=e>t?"16:9":"9:16":Math.abs(a-4/3)<.1&&(i=e>t?"4:3":"3:4"),n.aspectRatio=i,this._logger.info(this,`📹 [INFO] Video track - id: ${s.id}, enabled: ${s.enabled}, readyState: `+s.readyState)}else n.videoTrackPresent=!1;t&&this._logger.info(this,`📹 [INFO] Audio track - id: ${t.id}, enabled: ${t.enabled}, readyState: `+t.readyState),n.audioTrackPresent=!!t,this._logger.info(this,`Publish MetaData :: Resolution: ${n.streamWidth}x${n.streamHeight} | `+`Aspect ratio: ${n.aspectRatio}, `+`Video track: ${n.videoTrackPresent} | Audio track: `+n.audioTrackPresent),this._isDestroyed?(this._logger.warning(this,"📹 [RELEASE] onCameraStreamSuccess() - destroyed during setup, releasing"),e.getTracks().forEach(e=>e.stop()),this._activeStreamCount--):(this._main.dispatchEvent("publishMetadataUpdate",{ref:this._main,metadata:n}),this._stream=e,null!==this._pendingMicrophoneState?(this.applyMicrophoneState(this._pendingMicrophoneState),this._pendingMicrophoneState=null):this.applyMicrophoneState(!this._isMicrophoneMuted),0<this._stream.getAudioTracks().length&&this._soundMeter.attach(this._stream),null!=this._cameraList&&null!=this._microphoneList||this.grabDevices(),(a=null==(r=null==(o=this._main.getStageController())?void 0:o.getScreenElement())?void 0:r.getVideoElement())&&(a.srcObject=e,a.autoplay=!0,a.playsInline=!0,a.disableRemotePlayback=!0,a.controls=!1,a.muted=!0),this.setPublishState(exports.PublishState.INITIALIZED))}}initializeWebRTC(){var e;this._isDestroyed||(this._stream?this._peerConnection?(this._logger.info(this,"WebRTC connection already exists, updating stream"),this.updateWebRTCStream()):(this._logger.info(this,"Initializing new WebRTC connection"),null!=(e=this._main.getNetworkController())&&e.start()):this._logger.error(this,"Cannot initialize WebRTC - no camera stream available"))}publish(e){return!this._isDestroyed&&(this._debug&&this._logger.decoratedLog("Publishing: "+e,"dark-red"),this._logger.info(this,"Publish: "+e),this._main.getConfigManager().getStreamData().streamKey==e?(this._debug&&this._logger.decoratedLog("Canceling publishing, already published "+e,"dark-red"),this._logger.info(this,"Canceling publishing, already published "+e),!1):this.internalPublish(e))}internalPublish(e){return!(this._isDestroyed||(null!=this._statusTimer&&clearInterval(this._statusTimer),null==this._main.getConfigManager().getStreamData().streamKey||this._firstPublish||(this._debug&&this._logger.decoratedLog("Unpublishing active session: "+this._main.getConfigManager().getStreamData().streamKey,"dark-red"),this.unpublish()),this._main.getConfigManager().getStreamData().streamKey=e,this._fullStreamName=e+"_"+(new Date).getTime(),this.isStreamReady(!0,!0)?(this.closeWebRTCConnection(),this._main.dispatchEvent("publish",{ref:this._main,streamKey:e}),this.initializeWebRTC(),this._firstPublish=!1):(this._logger.warning(this,"Cannot publish - stream not ready (missing video or audio track)"),1)))}unpublish(){this._debug&&this._logger.decoratedLog("Unpublish","dark-red"),this._logger.info(this,"📹 [UNPUBLISH] unpublish() - stopping WebRTC but keeping camera preview"),null!=this._statusConnection&&(this._statusConnection.destroy(),this._statusConnection=null),null!=this._statusTimer&&(clearInterval(this._statusTimer),this._statusTimer=null),clearTimeout(this._publishTimer),this._main.getConfigManager().getStreamData().streamKey=null,this._main.dispatchEvent("unpublish",{ref:this._main}),this.closeWebRTCConnection(),this.setPublishState(exports.PublishState.UNPUBLISHED)}unpublishAndRelease(){this._logger.info(this,"📹 [UNPUBLISH+RELEASE] unpublishAndRelease() - stopping everything"),this._debug&&this._logger.decoratedLog("Unpublish + Release","dark-red"),this.unpublish(),this.stopCameraStream()}setupOrientationListener(){this._isDestroyed||(this._orientationChangeHandler=this.handleOrientationChange,window.screen&&window.screen.orientation?window.screen.orientation.addEventListener("change",this._orientationChangeHandler):window.addEventListener("orientationchange",this._orientationChangeHandler))}onUserMediaError(e){return __awaiter(this,void 0,void 0,function*(){this._isDestroyed||(this._logger.error(this,`📹 [ERROR] onUserMediaError() - ${e.name}: `+e.message),yield this.grabDevices(),"OverconstrainedError"===e.name&&this._logger.warning(this,"Device constraints not satisfied"))})}checkIndividualDeviceAccess(){return __awaiter(this,void 0,void 0,function*(){var t={camera:{allowed:!1,available:!1},microphone:{allowed:!1,available:!1}};if(!this._isDestroyed)try{var e=yield navigator.mediaDevices.enumerateDevices();if(this._isDestroyed)return t;if(t.camera.available=e.some(e=>"videoinput"===e.kind),t.microphone.available=e.some(e=>"audioinput"===e.kind),e.some(e=>""!==e.label))t.camera.allowed=e.some(e=>"videoinput"===e.kind&&""!==e.label),t.microphone.allowed=e.some(e=>"audioinput"===e.kind&&""!==e.label);else{if(this._logger.info(this,"📹 [ACQUIRE] checkIndividualDeviceAccess() - no labels, requesting permissions"),this._isDestroyed)return t;try{var i=yield navigator.mediaDevices.getUserMedia({video:t.camera.available,audio:t.microphone.available});if(this._isDestroyed)return this._logger.warning(this,"📹 [RELEASE] checkIndividualDeviceAccess() - destroyed, releasing orphan stream"),i.getTracks().forEach(e=>e.stop()),t;if(t.camera.allowed=0<i.getVideoTracks().length,t.microphone.allowed=0<i.getAudioTracks().length,this._logger.info(this,"📹 [RELEASE] checkIndividualDeviceAccess() - stopping test stream"),i.getTracks().forEach(e=>{e.stop(),this._logger.info(this,"📹 [RELEASE] checkIndividualDeviceAccess() - stopped track: "+e.kind)}),this._isDestroyed)return t;yield this.grabDevices()}catch(e){console.error("Error requesting permissions:",e),t.camera.allowed=!1,t.microphone.allowed=!1}}}catch(e){console.error("Error checking devices:",e)}return t})}onSocketMessage(e){if(!this._isDestroyed){var t=JSON.parse(e);switch(Number(t.status)){case 200:this._logger.info(this,"SDP Exchange Successful");var i=t.sdp,s=(void 0!==i&&this._peerConnection&&this._peerConnection.setRemoteDescription(new RTCSessionDescription(i),()=>{},()=>{}),t.iceCandidates);if(void 0!==s)for(var n in s)this._peerConnection&&this._peerConnection.addIceCandidate(new RTCIceCandidate(s[n]));break;case 503:this._logger.error(this,"StreamKey already use");i=null!=(i=this._main.getConfigManager().getStreamData().streamKey)?i:"unknown";this._main.dispatchEvent("streamKeyInUse",{ref:this._main,streamKey:i}),this.setPublishState(exports.PublishState.ERROR)}}}onConnectionStateChange(e){if(!this._isDestroyed&&(this._logger.info(this,"Connection State Change: "+JSON.stringify(e)),null!==e))switch(e.currentTarget.connectionState){case"connecting":this._logger.info(this,"WebRTCStreamer :: Event: onStreamerConnecting"),this.setPublishState(exports.PublishState.CONNECTING);break;case"connected":this._logger.info(this,"WebRTCStreamer :: Event: onStreamerConnected"),this.setPublishState(exports.PublishState.CONNECTED),this.muteMicrophone(this._isMicrophoneMuted);break;case"disconnected":this._logger.info(this,"WebRTCStreamer :: Event: onStreamerDisconnected"),this.setPublishState(exports.PublishState.UNPUBLISHED);break;case"failed":this._logger.info(this,"WebRTCStreamer :: Event: onPlayerFailed"),this.setPublishState(exports.PublishState.ERROR);break;default:this._logger.info(this,"WebRTCStreamer :: Unsupported onConnectionStateChange: "+e.currentTarget.connectionState)}}grabDevices(){return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed)try{var e=yield this.checkIndividualDeviceAccess();if(!this._isDestroyed&&(this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._permissionChecked||(e.camera.allowed?e.camera.available||(this._main.dispatchEvent("noCameraFound",{ref:this._main}),this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID)):(this._main.dispatchEvent("cameraAccessDenied",{ref:this._main}),this.setCameraState(exports.DeviceState.ACCESS_DENIED),this.setInputDeviceState(exports.InputDevicesState.INVALID)),e.microphone.allowed?e.microphone.available||(this._main.dispatchEvent("noMicrophoneFound",{ref:this._main}),this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID)):(this._main.dispatchEvent("microphoneAccessDenied",{ref:this._main}),this.setMicrophoneState(exports.DeviceState.ACCESS_DENIED),this.setInputDeviceState(exports.InputDevicesState.INVALID))),!this._isDestroyed)){var t,i,s=yield navigator.mediaDevices.enumerateDevices();if(!this._isDestroyed){for(const n of s)n.deviceId&&n.label&&("videoinput"===n.kind&&e.camera.allowed?(t=new InputDevice(n,this._cameraList.getSize()),this._cameraList.push(t)):"audioinput"===n.kind&&e.microphone.allowed&&(i=new InputDevice(n,this._microphoneList.getSize()),this._microphoneList.push(i)));if(!this._isDestroyed){try{e.camera.allowed&&(this._selectedCamera=this.pickCamera()),e.microphone.allowed&&(this._selectedMicrophone=this.pickMicrophone())}catch(e){console.log(e),this.setInputDeviceState(exports.InputDevicesState.INVALID),this._logger.error(this,"Error on grab devices: "+JSON.stringify(e))}this._isDestroyed||this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._permissionChecked=!0}}}}catch(e){this._isDestroyed||(console.error("Error in grabDevices:",e),this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._isDestroyed)||(this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._main.dispatchEvent("inputDeviceError",{ref:this._main}))}})}selectCamera(i){var n,r,o;return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed){this._cameraAbortController&&this._cameraAbortController.abort(),this._cameraAbortController=new AbortController;const s=this._cameraAbortController.signal;try{this._switchingCamera=!0,this._logger.info(this,"📹 [SWITCH] selectCamera() - switching to camera: "+i);for(let e=0;e<this._cameraList.getSize();e++)this._cameraList.get(e).isSelected=!1;this._selectedCamera=null,this.setInputDeviceState(exports.InputDevicesState.UPDATING),this.setCameraState(exports.DeviceState.NOT_INITIALIZED);var e=null==(n=this._main.getConfigManager())?void 0:n.getStreamData().streamKey,t=this._publishState===exports.PublishState.CONNECTED;for(let e=0;e<this._cameraList.getSize();e++)if(this._cameraList.get(e).id==i){this._selectedCamera=this._cameraList.get(e),this._selectedCamera.isSelected=!0,null!=(r=this._main.getStorageManager())&&r.saveField("cameraID",this._selectedCamera.id);break}this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),s.aborted||this._isDestroyed||(this.stopCameraStream(),null!=this._selectedCamera?(this._constraints.video.deviceId=this._selectedCamera.id,s.aborted||this._isDestroyed||(yield new Promise((e,t)=>{const i=setTimeout(e,500);s.addEventListener("abort",()=>{clearTimeout(i),t(new Error("Aborted"))})}),s.aborted)||this._isDestroyed||(yield this.startCamera(),this._isDestroyed)||(this.setCameraState(exports.DeviceState.ENABLED),this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED?this.setInputDeviceState(exports.InputDevicesState.READY):this.setInputDeviceState(exports.InputDevicesState.INVALID),t&&e&&!s.aborted&&!this._isDestroyed&&this.internalPublish(e))):this.setInputDeviceState(exports.InputDevicesState.INVALID))}catch(e){"Aborted"===e.message||this._isDestroyed||(this._logger.error(this,"📹 [ERROR] selectCamera() - Error switching camera: "+e),this.setInputDeviceState(exports.InputDevicesState.INVALID))}finally{this._switchingCamera=!1,(null==(o=this._cameraAbortController)?void 0:o.signal)===s&&(this._cameraAbortController=null)}}})}selectMicrophone(i){var n,r,o;return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed){this._microphoneAbortController&&this._microphoneAbortController.abort(),this._microphoneAbortController=new AbortController;const s=this._microphoneAbortController.signal;try{this._switchingMicrophone=!0,this._logger.info(this,"📹 [SWITCH] selectMicrophone() - switching to microphone: "+i);for(let e=0;e<this._microphoneList.getSize();e++)this._microphoneList.get(e).isSelected=!1;this._selectedMicrophone=null,this.setInputDeviceState(exports.InputDevicesState.UPDATING),this.setMicrophoneState(exports.DeviceState.NOT_INITIALIZED);var e=null==(n=this._main.getConfigManager())?void 0:n.getStreamData().streamKey,t=this._publishState===exports.PublishState.CONNECTED;for(let e=0;e<this._microphoneList.getSize();e++)if(this._microphoneList.get(e).id==i){this._selectedMicrophone=this._microphoneList.get(e),this._selectedMicrophone.isSelected=!0,null!=(r=this._main.getStorageManager())&&r.saveField("microphoneID",this._selectedMicrophone.id);break}this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),s.aborted||this._isDestroyed||(this._soundMeter.detach(),this.closeWebRTCConnection(),this._stream&&(this._logger.info(this,"📹 [RELEASE] selectMicrophone() - stopping current stream"),this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null,this._activeStreamCount--),s.aborted)||this._isDestroyed||(yield new Promise((e,t)=>{const i=setTimeout(e,500);s.addEventListener("abort",()=>{clearTimeout(i),t(new Error("Aborted"))})}),s.aborted)||this._isDestroyed||(yield this.startCamera(),this._isDestroyed)||(this.setMicrophoneState(exports.DeviceState.ENABLED),this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED?this.setInputDeviceState(exports.InputDevicesState.READY):this.setInputDeviceState(exports.InputDevicesState.INVALID),t&&e&&!s.aborted&&!this._isDestroyed&&this.internalPublish(e))}catch(e){"Aborted"===e.message||this._isDestroyed||(console.error("Error changing microphone:",e),this._main.dispatchEvent("inputDeviceError",{ref:this._main}),this.setInputDeviceState(exports.InputDevicesState.INVALID))}finally{this._switchingMicrophone=!1,(null==(o=this._microphoneAbortController)?void 0:o.signal)===s&&(this._microphoneAbortController=null)}}})}startCamera(){var s;return __awaiter(this,void 0,void 0,function*(){if(this._isDestroyed)this._logger.warning(this,"📹 [ACQUIRE] startCamera() - aborted, instance is destroyed");else{this._startCameraAbortController&&this._startCameraAbortController.abort(),this._startCameraAbortController=new AbortController;var t=this._startCameraAbortController.signal;this._stream&&(this._logger.info(this,"📹 [RELEASE] startCamera() - releasing existing stream before acquiring new one"),this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null,this._activeStreamCount--);try{var i={video:!!this._selectedCamera&&Object.assign(Object.assign({},this._constraints.video),{deviceId:{exact:this._selectedCamera.id}}),audio:!!this._selectedMicrophone&&{deviceId:{exact:this._selectedMicrophone.id}}};if(!t.aborted&&!this._isDestroyed){this._logger.info(this,"📹 [ACQUIRE] startCamera() - requesting getUserMedia");try{var e=yield navigator.mediaDevices.getUserMedia(i);if(t.aborted||this._isDestroyed)return this._logger.warning(this,"📹 [RELEASE] startCamera() - destroyed during getUserMedia, releasing orphan stream"),void e.getTracks().forEach(e=>{e.stop(),this._logger.info(this,`📹 [RELEASE] startCamera() - stopped orphan track: ${e.kind}, id: `+e.id)});this._stream=e,this.onCameraStreamSuccess(this._stream)}catch(e){if(t.aborted||this._isDestroyed)return;this._logger.error(this,`📹 [ERROR] startCamera() - getUserMedia failed: ${e.name}: `+e.message),i.video&&this.onUserMediaError({name:e.name||"Error",message:e.message||"Unknown error",deviceType:"video"}),i.audio&&this.onUserMediaError({name:e.name||"Error",message:e.message||"Unknown error",deviceType:"audio"})}this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED&&this.setInputDeviceState(exports.InputDevicesState.READY)}}catch(e){this._isDestroyed||(console.error("Error in startCamera:",e),yield this.grabDevices())}finally{(null==(s=this._startCameraAbortController)?void 0:s.signal)===t&&(this._startCameraAbortController=null)}}})}updateWebRTCStream(){this._isDestroyed||this._peerConnection&&this._stream&&(this._peerConnection.getSenders().forEach(e=>{this._peerConnection&&this._peerConnection.removeTrack(e)}),this._stream.getTracks().forEach(e=>{null!=this._stream&&this._peerConnection&&this._peerConnection.addTrack(e,this._stream)}))}pickCamera(){var e;if(this._isDestroyed)return null;for(let e=0;e<this._cameraList.getSize();e++)this._cameraList.get(e).isSelected=!1;var i=null!=(e=null==(e=this._main.getStorageManager())?void 0:e.getField("cameraID"))?e:null;if(0<this._cameraList.getSize()){if(i){let t=!1;for(let e=0;e<this._cameraList.getSize();e++)if(this._cameraList.get(e).id===i){this._selectedCamera=this._cameraList.get(e),this._selectedCamera.isSelected=!0,this.setCameraState(exports.DeviceState.ENABLED),t=!0,this._constraints.video.deviceId=this._selectedCamera.id;break}t||(this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID),this._main.dispatchEvent("savedCameraNotFound",{ref:this._main,savedDeviceID:i}),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null))}if(!this._selectedCamera){if(this._main.dispatchEvent("savedCameraNotFound",{ref:this._main,savedDeviceID:null}),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null),null==(e=this._main.getConfigManager())||!e.getSettingsData().getIfForceSelection())return this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID),null;this._selectedCamera=this._cameraList.get(0),this._selectedCamera.isSelected=!0,null!=(e=this._main.getStorageManager())&&e.saveField("cameraID",this._selectedCamera.id),this._constraints.video.deviceId=this._selectedCamera.id,this.setCameraState(exports.DeviceState.ENABLED)}}return this._isDestroyed||this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._selectedCamera}pickMicrophone(){var e;if(this._isDestroyed)return null;for(let e=0;e<this._microphoneList.getSize();e++)this._microphoneList.get(e).isSelected=!1;var i=null!=(e=null==(e=this._main.getStorageManager())?void 0:e.getField("microphoneID"))?e:null;if(0<this._microphoneList.getSize()){if(i){let t=!1;for(let e=0;e<this._microphoneList.getSize();e++)if(this._microphoneList.get(e).id===i){this._selectedMicrophone=this._microphoneList.get(e),t=!0,this.setMicrophoneState(exports.DeviceState.ENABLED);break}t||(this._main.dispatchEvent("savedMicrophoneNotFound",{ref:this._main,savedDeviceID:i}),this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null))}if(!this._selectedMicrophone){if(this._main.dispatchEvent("savedMicrophoneNotFound",{ref:this._main,savedDeviceID:null}),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null),null==(e=this._main.getConfigManager())||!e.getSettingsData().getIfForceSelection())return this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID),null;this._selectedMicrophone=this._microphoneList.get(0),this.setMicrophoneState(exports.DeviceState.ENABLED),null!=(e=this._main.getStorageManager())&&e.saveField("microphoneID",this._selectedMicrophone.id)}this._selectedMicrophone.isSelected=!0,this._constraints.audio={deviceId:this._selectedMicrophone.id}}return this._selectedMicrophone}clearSavedDevices(){var e;null!=(e=this._main.getStorageManager())&&e.removeField("cameraID"),null!=(e=this._main.getStorageManager())&&e.removeField("microphoneID")}messSavedDevices(){var e;null!=(e=this._main.getStorageManager())&&e.saveField("cameraID","a"),null!=(e=this._main.getStorageManager())&&e.saveField("microphoneID","b")}muteMicrophone(e){var t;this._isDestroyed||this._isMicrophoneMuted!==e&&(this._isMicrophoneMuted=e,null!=(t=this._main.getStorageManager())&&t.saveField("microphoneMuted",e?"true":"false"),this._stream?this.applyMicrophoneState(!e):this._pendingMicrophoneState=!e,this._main.dispatchEvent("microphoneStateChange",{ref:this._main,isMuted:this._isMicrophoneMuted}))}applyMicrophoneState(t){var e;this._stream&&(e=this._stream.getAudioTracks())&&0<e.length&&e.forEach(e=>e.enabled=t)}isStreamReady(e=!0,t=!0){var i,s;return!!this._stream&&(s=this._stream.getVideoTracks(),i=this._stream.getAudioTracks(),e=!e||0<s.length&&"live"===s[0].readyState,s=!t||0<i.length&&"live"===i[0].readyState,e)&&s}closeWebRTCConnection(){if(this._peerConnection){this._logger.info(this,"📡 [WEBRTC] closeWebRTCConnection() - closing peer connection"),this._peerConnection.onicecandidate=null,this._peerConnection.onconnectionstatechange=null,this._peerConnection.onnegotiationneeded=null;try{this._peerConnection.close()}catch(e){}this._peerConnection=null}}onDescriptionError(e){this._logger.info(this,"WebRTCStreamer :: onDescriptionError: "+JSON.stringify(e))}onIceCandidate(e){e.candidate}createStatusConnection(){var e;this._isDestroyed||(e=null==(e=null==(e=null==(e=this._main)?void 0:e.getNetworkController())?void 0:e.getConnection())?void 0:e.getCurrentServer())&&(this._statusConnection&&!this._statusConnection.isConnectionActive()&&this._statusConnection.destroy(),this._statusConnection=new WowzaStatusConnection(this._main,e))}isMicrophoneMuted(){return this._isMicrophoneMuted}getCurrentCamera(){return this._selectedCamera}getCurrentMicrophone(){return this._selectedMicrophone}setPublishState(e){this._publishState==e||this._isDestroyed||(this._debug&&this._logger.decoratedLog("Publish State: "+e,"dark-blue"),this._logger.info(this,"Publish State: "+e),e==exports.PublishState.PUBLISHED&&(this._publishTime=(new Date).getTime()),this._publishState=e,this._main.dispatchEvent("publishStateChange",{ref:this._main,state:this._publishState}))}getPublishTime(){return this._publishState==exports.PublishState.PUBLISHED?this._publishTime:0}setInputDeviceState(e){this._inputDeviceState==e||this._isDestroyed||(this._inputDeviceState=e,this._main.dispatchEvent("deviceStateChange",{ref:this._main,state:this._inputDeviceState,selectedCamera:this._selectedCamera,selectedMicrophone:this._selectedMicrophone}))}getInputDeviceState(){return this._inputDeviceState}setCameraState(e){this._cameraState==e||this._isDestroyed||(this._cameraState=e,this._main.dispatchEvent("cameraDeviceStateChange",{ref:this._main,state:e,selectedCamera:this._selectedCamera}))}getCameraState(){return this._cameraState}setMicrophoneState(e){this._microphoneState==e||this._isDestroyed||(this._microphoneState=e,this._main.dispatchEvent("microphoneDeviceStateChange",{ref:this._main,state:e,selectedMicrophone:this._selectedMicrophone}))}getMicrophoneState(){return this._microphoneState}getCameraList(){return null!=this._cameraList?this._cameraList.getArray():[]}getMicrophoneList(){return null!=this._microphoneList?this._microphoneList.getArray():[]}getPublishState(){return this._publishState}debugMediaState(){console.group("🎥 Media Debug State"),console.log("=== STREAM INFO ==="),console.log("this._stream:",this._stream),console.log("Active stream count:",this._activeStreamCount),console.log("Is destroyed:",this._isDestroyed),this._stream&&(console.log("Stream ID:",this._stream.id),console.log("Stream active:",this._stream.active),console.log("--- Video Tracks ---"),this._stream.getVideoTracks().forEach((e,t)=>{console.log(` Track ${t}:`,{id:e.id,enabled:e.enabled,readyState:e.readyState,muted:e.muted})}),console.log("--- Audio Tracks ---"),this._stream.getAudioTracks().forEach((e,t)=>{console.log(` Track ${t}:`,{id:e.id,enabled:e.enabled,readyState:e.readyState,muted:e.muted})})),console.log("=== VIDEO ELEMENT ===");var e=null==(e=null==(e=this._main.getStageController())?void 0:e.getScreenElement())?void 0:e.getVideoElement();(null==e?void 0:e.srcObject)instanceof MediaStream&&(e=e.srcObject,console.log("Video srcObject stream ID:",e.id),console.log("Video srcObject active:",e.active),console.log("Same as this._stream:",e===this._stream)),console.groupEnd()}stopCameraStream(){var e;this._stream&&(this._logger.info(this,"📹 [RELEASE] stopCameraStream() - stopping stream, id: "+this._stream.id),this._stream.getTracks().forEach(e=>{this._logger.info(this,`📹 [RELEASE] stopCameraStream() - stopping track: ${e.kind}, id: `+e.id),e.stop()}),(e=null==(e=null==(e=this._main.getStageController())?void 0:e.getScreenElement())?void 0:e.getVideoElement())&&(e.srcObject=null),this._soundMeter.detach(),this._stream=null,this._activeStreamCount--,this._logger.info(this,"📹 [RELEASE] stopCameraStream() - complete, active streams: "+this._activeStreamCount))}stop(){this._logger.info(this,"📹 [STOP] stop() - stopping all operations"),this._cameraAbortController&&(this._cameraAbortController.abort(),this._cameraAbortController=null),this._microphoneAbortController&&(this._microphoneAbortController.abort(),this._microphoneAbortController=null),this._startCameraAbortController&&(this._startCameraAbortController.abort(),this._startCameraAbortController=null),this._statusConnection&&(this._statusConnection.destroy(),this._statusConnection=null),this._statusTimer&&(clearInterval(this._statusTimer),this._statusTimer=null),this._main.getConfigManager().getStreamData().streamKey=null,this.closeWebRTCConnection(),this.stopCameraStream(),this.setPublishState(exports.PublishState.STOPPED),this.setInputDeviceState(exports.InputDevicesState.STOPPED),this.setCameraState(exports.DeviceState.STOPPED),this.setMicrophoneState(exports.DeviceState.STOPPED),this._restartTimer&&(clearInterval(this._restartTimer),this._restartTimer=null),this._restartTimerCount=0,clearTimeout(this._publishTimer)}start(){var e,t,i;return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed)if(this._publishState!==exports.PublishState.STOPPED&&this._publishState!==exports.PublishState.NOT_INITIALIZED)this._logger.warning(this,"📹 [START] start() - already running, ignoring");else if(this._inputDeviceState!==exports.InputDevicesState.STOPPED&&this._inputDeviceState!==exports.InputDevicesState.NOT_INITIALIZED)this._logger.warning(this,"📹 [START] start() - devices already initializing/ready, ignoring");else{this._logger.info(this,"📹 [START] start() - reinitializing streaming");try{this._publishState=exports.PublishState.NOT_INITIALIZED,this._inputDeviceState=exports.InputDevicesState.NOT_INITIALIZED,this._cameraState=exports.DeviceState.NOT_INITIALIZED,this._microphoneState=exports.DeviceState.NOT_INITIALIZED,yield this.initializeDevices(),this._isDestroyed||(yield this.startCamera(),this._isDestroyed)||(null!=(e=this._main.getConfigManager())&&e.getSettingsData().autoConnect&&null!=(t=this._main.getNetworkController())&&t.initialize(),null!=(i=this._main.getConfigManager())&&i.getStreamData().streamKey&&this.createStatusConnection())}catch(e){if(!this._isDestroyed)throw this._logger.error(this,"📹 [START] start() - failed: "+JSON.stringify(e)),this.setInputDeviceState(exports.InputDevicesState.INVALID),e}}})}destroy(){var e,t,i,s;if(this._isDestroyed)null!=(e=this._logger)&&e.warning(this,"🔴 [DESTROY] Already destroyed, skipping");else{this._logger.info(this,"🔴 [DESTROY] Starting StreamerController destroy (sync)..."),this._isDestroyed=!0,this._cameraAbortController&&(this._cameraAbortController.abort(),this._cameraAbortController=null),this._microphoneAbortController&&(this._microphoneAbortController.abort(),this._microphoneAbortController=null),this._startCameraAbortController&&(this._startCameraAbortController.abort(),this._startCameraAbortController=null),null!=this._statusTimer&&(clearInterval(this._statusTimer),this._statusTimer=null),null!=this._restartTimer&&(clearInterval(this._restartTimer),this._restartTimer=null),clearTimeout(this._publishTimer),this.removePermissionListeners(),this._deviceChangeHandler&&(navigator.mediaDevices.removeEventListener("devicechange",this._deviceChangeHandler),this._deviceChangeHandler=null),this._orientationChangeHandler&&(window.screen&&window.screen.orientation?window.screen.orientation.removeEventListener("change",this._orientationChangeHandler):window.removeEventListener("orientationchange",this._orientationChangeHandler),this._orientationChangeHandler=null);try{this._main.removeEventListener("serverConnect",this.onServerConnect),this._main.removeEventListener("serverDisconnect",this.onServerDisconnect),this._main.removeEventListener("streamKeyInUse",this.onStreamKeyTaken),this._main.removeEventListener("statusServerConnect",this.onStatusServerConnect),this._main.removeEventListener("statusServerDisconnect",this.onStatusServerDisconnect),this._main.removeEventListener("streamStatusUpdate",this.onStreamStatsUpdate),this._main.removeEventListener("deviceStateChange",this.onDeviceStateChange),document.removeEventListener("visibilitychange",this.visibilityChange),window.removeEventListener("blur",this.onWindowBlur),window.removeEventListener("focus",this.onWindowFocus)}catch(e){}this._statusConnection&&(this._statusConnection.destroy(),this._statusConnection=null),this.closeWebRTCConnection(),this._stream&&(this._logger.info(this,"📹 [FORCE_STOP] Stopping main stream"),this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null);try{var n=null==(i=null==(t=this._main.getStageController())?void 0:t.getScreenElement())?void 0:i.getVideoElement();n&&(n.srcObject instanceof MediaStream&&n.srcObject.getTracks().forEach(e=>e.stop()),n.srcObject=null)}catch(e){}try{null!=(s=this._soundMeter)&&s.destroy()}catch(e){}this._selectedCamera=null,this._selectedMicrophone=null,this._activeStreamCount=0,this._logger.success(this,"🔴 [DESTROY] StreamerController destroyed (sync)")}}}class WowzaConnection extends AbstractSocket{constructor(e,t){super(),this._logger=e.getLogger(),this._main=e,this._networkController=t,this.initialize()}initialize(){this._logger.info(this,"Starting new connection with a storm server"),this.pickServerFromList(this._main.getConfigManager().getStreamData().getServerList()),null!=this._currServer?(this.socketURL=this.createURL(this._currServer),this._logger.info(this,"Starting WebSocket connection with: "+this.socketURL),this._main.dispatchEvent("serverConnectionInitiate",{ref:this._main,serverURL:this.socketURL}),this._main.getConfigManager().getIfDemoMode()?(this._logger.warning(this,"Player is in demo mode, and will not connect with a server!"),this._main.dispatchEvent("authorizationComplete",{ref:this._main})):this.startConnection()):this._logger.error(this,"Connection with the server could not be initialized!")}onSocketOpen(e){this._logger.success(this,"Connection with the server has been established!"),this._main.dispatchEvent("serverConnect",{ref:this._main,serverURL:this.socketURL,sequenceNum:this._sequenceNumber}),this._isConnected=!0}onSocketError(e){this._isConnected=!1,this._disconnectedByUser||(this._logger.error(this,"Connection with the server failed"),this._main.dispatchEvent("serverConnectionError",{ref:this._main,serverURL:this.socketURL,restart:this._main.getConfigManager().getSettingsData().getIfRestartOnError(),sequenceNum:this._sequenceNumber}),0==this._isConnected&&(this._currServer.setAsFaild(!0),this.initiateReconnect()))}onSocketClose(e){this._isConnected=!1,this._disconnectedByUser?this._logger.warning(this,"Force disconnect from server!"):(this._logger.error(this,"Connection with the server has been closed"),this._main.dispatchEvent("serverDisconnect",{ref:this._main,serverURL:this.socketURL,restart:this._main.getConfigManager().getSettingsData().getIfRestartOnError(),sequenceNum:this._sequenceNumber}),this.initiateReconnect())}onSocketMessage(e){this._networkController.onMessage(e)}createURL(e){var t="";return(t+=e.getIfSSL()?"wss://":"ws://")+e.getHost()+(":"+e.getPort())+"/webrtc-session.json"}initiateReconnect(){var e=this._main.getConfigManager().getSettingsData().getIfRestartOnError();const t=this._main.getConfigManager().getSettingsData().getReconnectTime();this._disconnectedByUser||e&&(null!=this._reconnectTimer&&clearTimeout(this._reconnectTimer),this._reconnectTimer=setTimeout(()=>{this.pickServerFromList(this._main.getConfigManager().getStreamData().getServerList()),null!=this._currServer&&(this._logger.info(this,`Will reconnect to the server in ${t} seconds...`),this.socketURL=this.createURL(this._currServer),this._logger.info(this,"Starting WebSocket connection with: "+this.socketURL),this._main.dispatchEvent("serverConnectionInitiate",{ref:this._main,serverURL:this.socketURL}),this.startConnection())},1e3*t))}pickServerFromList(t){let i=null;for(let e=0;e<t.length;e++)if(!t[e].getIfFaild()){i=t[e];break}null==i?(this._logger.error(this,"All connections failed!"),this._main.dispatchEvent("allConnectionsFailed",{ref:this._main,mode:"none"}),this._currServer=null):this._currServer=i}isConnectionActive(){return this._isConnected}getCurrentServer(){return this._currServer}destroy(){super.destroy(),null!=this._reconnectTimer&&clearTimeout(this._reconnectTimer)}}class NetworkController{constructor(e){this._currentStreamKey="none",this._lastState="",this.onServerConnect=()=>{},this.onServerDisconnect=()=>{this._lastState="none"},this.onMessage=e=>{var t;null!=(t=this._main.getStreamerController())&&t.onSocketMessage(e.data)},this._main=e,this._logger=e.getLogger(),this._main.addEventListener("serverConnect",this.onServerConnect,!1),this._main.addEventListener("serverDisconnect",this.onServerDisconnect,!1)}initialize(){null!=this._connection&&(this._connection.getConnectionState()==ConnectionState.CONNECTING||this._connection.getConnectionState()==ConnectionState.CONNECTED?this._logger.info(this,"Connection is alive, not doing anything!"):(this._logger.info(this,"Connection is dead, restarting!"),this._connection.startConnection()))}start(){this._connection=new WowzaConnection(this._main,this)}stop(){this._connection.disconnect(!0),this._lastState=""}sendMessage(e){this._connection.isConnectionActive()&&this._connection.sendData(e)}getConnection(){return this._connection}getCurrentStreamKey(){return this._currentStreamKey}}class StatsController{constructor(e){this._publishVideoWidth=0,this._publishVideoHeight=0,this._publishVideoBitrate=0,this._publishAudioBitrate=0,this._currentBitrate=0,this._currentFPS=0,this._deliveredVideoFrames=0,this._deliveredAudioFrames=0,this.onStreamStatsUpdate=e=>{this._publishVideoWidth=e.streamStatus.videoWidth,this._publishVideoHeight=e.streamStatus.videoHeight,this._currentBitrate=e.streamStatus.currentBitrate,this._publishVideoBitrate=e.streamStatus.videoPublishBitrate,this._publishAudioBitrate=e.streamStatus.audioPublishBitrate,this._currentFPS=e.streamStatus.frameRate,this._deliveredVideoFrames=e.streamStatus.videoFrameCount,this._deliveredAudioFrames=e.streamStatus.audioFrameCount},this._main=e,this._logger=e.getLogger(),this._logger.info(this,"Creating new StatsController"),this.initialize()}initialize(){this._main.addEventListener("streamStatusUpdate",this.onStreamStatsUpdate,!1)}get deliveredVideoFrames(){return this._deliveredVideoFrames}get deliveredAudioFrames(){return this._deliveredAudioFrames}get currentFPS(){return this._currentFPS}get publishVideoWidth(){return this._publishVideoWidth}get publishVideoHeight(){return this._publishVideoHeight}get currentBitrate(){return this._currentBitrate}get publishVideoBitrate(){return this._publishVideoBitrate}get publishAudioBitrate(){return this._publishAudioBitrate}}class GraphDrawer{constructor(e,t,i,s=1){if(this._currentX=0,this._isFullyDrawn=!1,this._lastTimestamp=null,this._isTimemarkLine=!1,this._borderWidth=1,i.length!==t.length+1)throw new Error(`Colors array must have exactly ${t.length+1} elements (one more than valueRanges)`);for(let e=1;e<t.length;e++)if(t[e]<=t[e-1])throw new Error("ValueRanges must be in ascending order");const n=/^#[0-9A-Fa-f]{6}$/;if(!i.every(e=>n.test(e)))throw new Error("All colors must be in valid hex format (e.g., #FF0000)");let r;if("string"==typeof e){var o=document.getElementById(e);if(!o)throw new Error(`Container element with id ${e} not found`);r=o}else r=e;o=r.getBoundingClientRect(),this._width=Math.floor(o.width),this._height=Math.floor(o.height),this._effectiveWidth=this._width-2*this._borderWidth,this._effectiveHeight=this._height-2*this._borderWidth,this._canvas=document.createElement("canvas"),r.appendChild(this._canvas),e=this._canvas.getContext("2d",{willReadFrequently:!0});if(!e)throw new Error("Failed to get canvas context");this._ctx=e,this._valueRanges=[0,...t],this._colors=i,this._lineWidth=s,this._canvas.width=this._width,this._canvas.height=this._height,this._canvas.style.width=this._width+"px",this._canvas.style.height=this._height+"px",this.clear()}drawBorder(){this._ctx.strokeStyle="#000000",this._ctx.lineWidth=this._borderWidth,this._ctx.strokeRect(this._borderWidth/2,this._borderWidth/2,this._width-this._borderWidth,this._height-this._borderWidth)}clear(){this._ctx.clearRect(0,0,this._width,this._height),this._ctx.fillStyle=this._colors[0],this._ctx.fillRect(this._borderWidth,this._borderWidth,this._effectiveWidth,this._effectiveHeight),this.drawBorder(),this._isFullyDrawn=!1,this._currentX=this._borderWidth,this._lastTimestamp=null,this._isTimemarkLine=!1}getColorIndices(t){for(let e=0;e<this._valueRanges.length-1;e++)if(t>=this._valueRanges[e]&&t<=this._valueRanges[e+1])return{lowerIndex:e,upperIndex:e+1};return{lowerIndex:this._valueRanges.length-2,upperIndex:this._valueRanges.length-1}}calculateHeightRatio(e,t,i){return(e-t)/(i-t)}shiftCanvasLeft(e){e=this._ctx.getImageData(this._borderWidth+e,this._borderWidth,this._effectiveWidth-e,this._effectiveHeight);this._ctx.fillStyle=this._colors[0],this._ctx.fillRect(this._borderWidth,this._borderWidth,this._effectiveWidth,this._effectiveHeight),this._ctx.putImageData(e,this._borderWidth,this._borderWidth),this.drawBorder()}applyOverlayEffect(e,s=.5){var t=parseInt(e.slice(1,3),16),i=parseInt(e.slice(3,5),16),e=parseInt(e.slice(5,7),16),n=e=>{var t=e/255;let i;return i=t<=.5?2*t*1:1-2*(1-t)*0,Math.round(255*i*s+e*(1-s))},t=n(t),i=n(i),n=n(e),e=e=>{e=e.toString(16);return 1===e.length?"0"+e:e};return"#"+e(t)+e(i)+e(n)}addEntry(e){e=Math.round(100*e)/100;var t=Date.now(),t=(null===this._lastTimestamp?(this._lastTimestamp=t,this._isTimemarkLine=!1):1e3<=t-this._lastTimestamp?(this._isTimemarkLine=!0,this._lastTimestamp=t):this._isTimemarkLine=!1,this._isTimemarkLine?1:this._lineWidth);!this._isFullyDrawn&&this._currentX>=this._width-this._borderWidth&&(this._isFullyDrawn=!0),this._isFullyDrawn?(this.shiftCanvasLeft(t),this.drawLine(this._width-this._borderWidth-t,e,t)):(this.drawLine(this._currentX,e,t),this._currentX+=t)}drawLine(e,t,i){var{lowerIndex:s,upperIndex:n}=this.getColorIndices(t),t=this.calculateHeightRatio(t,this._valueRanges[s],this._valueRanges[n]);let r=this._colors[s],o=this._colors[n];this._isTimemarkLine&&(r=this.applyOverlayEffect(r,.3),o=this.applyOverlayEffect(o,.3));s=Math.round(this._effectiveHeight*t),n=this._effectiveHeight-s;this._ctx.fillStyle=r,this._ctx.fillRect(e,this._height-this._borderWidth-n,i,n),this._ctx.fillStyle=o,this._ctx.fillRect(e,this._borderWidth,i,s)}clearGraph(){this._currentX=this._borderWidth,this._isFullyDrawn=!1,this._lastTimestamp=null,this._isTimemarkLine=!1,this.clear()}destroy(){this._canvas.parentNode&&this._canvas.parentNode.removeChild(this._canvas)}}class BitrateGraph{constructor(e,t){this.onStreamStatsUpdate=e=>{var t;null!=(t=this._graph)&&t.addEntry(e.streamStatus.currentBitrate)},this._main=e,this._object=t,this._main.addGraph(this)}start(){null!=this._graph&&stop();return this._graph=new GraphDrawer(this._object,[1e6,2e6,3e6,5e6,6e6,7e6],["#000000","#0a3980","#2793dd","#3bc39c","#c3df3e","#f89539","#f83f3f"],5),this._main.addEventListener("streamStatusUpdate",this.onStreamStatsUpdate),this}stop(){return this._main.removeEventListener("streamStatusUpdate",this.onStreamStatsUpdate),null!=this._graph&&this._graph.destroy(),this._graph=null,this}}class FPSGraph{constructor(e,t){this.onStreamStatsUpdate=e=>{var t;null!=(t=this._graph)&&t.addEntry(e.streamStatus.frameRate)},this._main=e,this._object=t,this._main.addGraph(this)}start(){null!=this._graph&&stop();return this._graph=new GraphDrawer(this._object,[25,26,27,28,29,30],["#000000","#0a3980","#2793dd","#3bc39c","#c3df3e","#f89539","#f83f3f"],5),this._main.addEventListener("streamStatusUpdate",this.onStreamStatsUpdate),this}stop(){return this._main.removeEventListener("streamStatusUpdate",this.onStreamStatsUpdate),null!=this._graph&&this._graph.destroy(),this._graph=null,this}}class MicrophoneGraph{constructor(e,t){this.onStreamStatsUpdate=e=>{var t;null!=(t=this._graph)&&t.addEntry(500*e.high)},this._main=e,this._object=t,this._main.addGraph(this)}start(){null!=this._graph&&stop();return this._graph=new GraphDrawer(this._object,[0,20,40,60,80,100],["#000000","#0a3980","#2793dd","#3bc39c","#c3df3e","#f89539","#f83f3f"],2),this._main.addEventListener("soundMeter",this.onStreamStatsUpdate),this}stop(){return this._main.removeEventListener("soundMeter",this.onStreamStatsUpdate),null!=this._graph&&this._graph.destroy(),this._graph=null,this}}class StormStreamer extends EventDispatcher{constructor(e,t=!1){super(),this.DEV_MODE=!0,this.STREAMER_VERSION="1.0.3",this.COMPILE_DATE="2/19/2026, 10:00:22 AM",this.STREAMER_BRANCH="Experimental",this.STREAMER_PROTOCOL_VERSION=1,this._initialized=!1,this._isDestroyed=!1,"undefined"!=typeof window&&window.document&&window.document.createElement?(!this.DEV_MODE||"StormStreamerArray"in window||(window.StormStreamerArray=[]),window.StormStreamerArray.push(this),this._streamerID=StormStreamer.NEXT_STREAMER_ID++,null!=e&&(this.setStreamConfig(e),t)&&this.initialize()):console.error('StormStreamer Creation Error - No "window" element in the provided context!')}initialize(){if(!this._isRemoved&&!this._isDestroyed){if(null==this._configManager)throw Error("Stream Config was not provided for this streamer!");this._storageManager=new StorageManager(this),this._stageController=new StageController(this),this._networkController=new NetworkController(this),this._streamerController=new StreamerController(this),this._statsController=new StatsController(this),this._graphs=[],this._initialized=!0,this.dispatchEvent("streamerReady",{ref:this})}}setStreamConfig(e){this._isRemoved||this._isDestroyed||(e=JSON.parse(JSON.stringify(e)),null==this._configManager?(this._configManager=new ConfigManager(e),this._logger=new Logger(this._configManager.getSettingsData().getDebugData(),this),this._logger.info(this,"Storm Streamer :: Storm Streaming Suite"),this._logger.info(this,"StreamerID: "+this._streamerID),this._logger.info(this,"Version: "+this.STREAMER_VERSION+" | Compile Date: "+this.COMPILE_DATE+" | Branch: "+this.STREAMER_BRANCH),this._logger.info(this,"UserCapabilities :: Browser: "+UserCapabilities.getBrowserName()+" "+UserCapabilities.getBrowserVersion()),this._logger.info(this,"UserCapabilities :: Operating System: "+UserCapabilities.getOS()+" "+UserCapabilities.getOSVersion()),this._logger.info(this,"UserCapabilities :: isMobile: "+UserCapabilities.isMobile()),this._logger.info(this,"UserCapabilities :: hasMSESupport: "+UserCapabilities.hasMSESupport()),this._logger.info(this,"UserCapabilities :: hasWebSocketSupport: "+UserCapabilities.hasWebSocketsSupport()),this._logger.info(this,"UserCapabilities :: hasWebRTCSupport: "+UserCapabilities.hasWebRTCSupport()),this._configManager.print(this._logger)):(this._logger.info(this,"StreamConfig has been overwritten, dispatching streamConfigChanged!"),this._configManager=new ConfigManager(e),this._configManager.print(this._logger),this.dispatchEvent("streamConfigChange",{ref:this,newConfig:this._configManager})))}isConnected(){var e;return null!=(e=null==(e=this._networkController)?void 0:e.getConnection().isConnectionActive())&&e}mute(){var e;null!=(null==(e=this._stageController)?void 0:e.getScreenElement())?this._stageController.getScreenElement().setMuted(!0):this._configManager.getSettingsData().getAudioData().muted=!0}unmute(){var e;null!=(null==(e=this._stageController)?void 0:e.getScreenElement())?this._stageController.getScreenElement().setMuted(!1):this._configManager.getSettingsData().getAudioData().muted=!1}isMute(){var e;return null!=(e=null!=(e=null==(e=null==(e=this._stageController)?void 0:e.getScreenElement())?void 0:e.getIfMuted())?e:this._configManager.getSettingsData().getAudioData().muted)&&e}toggleMute(){var e=this.isMute();return e?this.unmute():this.mute(),!e}setVolume(e){var t;void 0===(null==(t=null==(t=this._stageController)?void 0:t.getScreenElement())?void 0:t.setVolume(e))&&(this._configManager.getSettingsData().getAudioData().startVolume=e)}getVolume(){var e;return null!=(e=null==(e=null==(e=this._stageController)?void 0:e.getScreenElement())?void 0:e.getVolume())?e:this._configManager.getSettingsData().getAudioData().startVolume}getCameraList(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getCameraList())?e:[]}getMicrophoneList(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getMicrophoneList())?e:[]}setCamera(e){var t;null!=(t=this._streamerController)&&t.selectCamera(e)}setMicrophone(e){var t;null!=(t=this._streamerController)&&t.selectMicrophone(e)}getCurrentCamera(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getCurrentCamera())?e:null}getCurrentMicrophone(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getCurrentMicrophone())?e:null}muteMicrophone(e){var t;null!=(t=this._streamerController)&&t.muteMicrophone(e)}isMicrophoneMuted(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.isMicrophoneMuted())&&e}getPublishState(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getPublishState())?e:exports.PublishState.NOT_INITIALIZED}getPublishTime(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getPublishTime())?e:0}publish(e){var t;return null!=(t=null==(t=this._streamerController)?void 0:t.publish(e))&&t}unpublish(){var e;null!=(e=this._streamerController)&&e.unpublish()}getInputDevicesState(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getInputDeviceState())?e:exports.InputDevicesState.NOT_INITIALIZED}getCameraState(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getCameraState())?e:exports.DeviceState.NOT_INITIALIZED}getMicrophoneState(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getMicrophoneState())?e:exports.DeviceState.NOT_INITIALIZED}clearSavedDevices(){var e;null!=(e=this._streamerController)&&e.clearSavedDevices()}messSavedDevices(){var e;null!=(e=this._streamerController)&&e.messSavedDevices()}isStreamReady(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.isStreamReady())&&e}attachToContainer(e){var t;return!!this._initialized&&null!=(t=null==(t=this._stageController)?void 0:t.attachToParent(e))&&t}detachFromContainer(){var e;return!!this._initialized&&null!=(e=null==(e=this._stageController)?void 0:e.detachFromParent())&&e}getContainer(){var e;return null!=(e=null==(e=this._stageController)?void 0:e.getParentElement())?e:null}setSize(e,t){this._initialized?this._stageController.setSize(e,t):(e=NumberUtilities.parseValue(e),t=NumberUtilities.parseValue(t),this._configManager.getSettingsData().getVideoData().videoWidthValue=e.value,this._configManager.getSettingsData().getVideoData().videoWidthInPixels=e.isPixels,this._configManager.getSettingsData().getVideoData().videoHeightValue=t.value,this._configManager.getSettingsData().getVideoData().videoHeightInPixels=t.isPixels)}setWidth(e){this._initialized?this._stageController.setWidth(e):(e=NumberUtilities.parseValue(e),this._configManager.getSettingsData().getVideoData().videoWidthValue=e.value,this._configManager.getSettingsData().getVideoData().videoWidthInPixels=e.isPixels)}setHeight(e){this._initialized?this._stageController.setHeight(e):(e=NumberUtilities.parseValue(e),this._configManager.getSettingsData().getVideoData().videoHeightValue=e.value,this._configManager.getSettingsData().getVideoData().videoHeightInPixels=e.isPixels)}getWidth(){return this._initialized?this._stageController.getContainerWidth():this._configManager.getSettingsData().getVideoData().videoWidthInPixels?this._configManager.getSettingsData().getVideoData().videoWidthValue:0}getHeight(){return this._initialized?this._stageController.getContainerHeight():this._configManager.getSettingsData().getVideoData().videoHeightInPixels?this._configManager.getSettingsData().getVideoData().videoHeightValue:0}setScalingMode(e){this._stageController?this._stageController.setScalingMode(e):this._configManager.getSettingsData().getVideoData().scalingMode=e}getScalingMode(){return this._stageController?this._stageController.getScalingMode():this._configManager.getSettingsData().getVideoData().scalingMode}updateToSize(){this._initialized&&this._stageController.handleResize()}makeScreenshot(){let i=document.createElement("canvas"),s=i.getContext("2d");return new Promise(t=>{var e;null!=this._stageController&&(i.width=this._stageController.getScreenElement().getVideoElement().videoWidth,i.height=this._stageController.getScreenElement().getVideoElement().videoHeight,e=this._stageController.getScreenElement().getVideoElement(),s)?(s.drawImage(e,0,0,i.width,i.height),i.toBlob(e=>t(e),"image/png")):t(null)})}createFPSGraph(e){return new FPSGraph(this,e)}createBitrateGraph(e){return new BitrateGraph(this,e)}createMicrophoneGraph(e){return new MicrophoneGraph(this,e)}addGraph(e){null!=this._graphs&&this._graphs.push(e)}stopAllGraphs(){if(null!=this._graphs&&0<this._graphs.length)for(let e=0;e<this._graphs.length;e++)this._graphs[e].stop()}enterFullScreen(){this._initialized&&this._stageController&&this._stageController.enterFullScreen()}exitFullScreen(){this._initialized&&this._stageController&&this._stageController.exitFullScreen()}isFullScreenMode(){return!(!this._initialized||!this._stageController)&&this._stageController.isFullScreenMode()}getStreamKey(){var e;return null!=(e=null==(e=null==(e=this.getConfigManager())?void 0:e.getStreamData())?void 0:e.streamKey)?e:null}getStatsController(){return this._statsController}getStreamerID(){return this._streamerID}getLogger(){return this._logger}getConfigManager(){return this._configManager}getNetworkController(){return this._networkController}getStreamerController(){return this._streamerController}getStageController(){return this._stageController}getStorageManager(){return this._storageManager}getVideoElement(){var e;return null!=(e=null==(e=null==(e=this._stageController)?void 0:e.getScreenElement())?void 0:e.getVideoElement())?e:null}isInitialized(){return this._initialized}isDestroyed(){return this._isDestroyed}getVersion(){return this.STREAMER_VERSION}getBranch(){return this.STREAMER_BRANCH}dispatchEvent(e,t){super.dispatchEvent(e,t)}start(){var e;return __awaiter(this,void 0,void 0,function*(){return!this._initialized||this._isDestroyed||null==(e=this._streamerController)?void 0:e.start()})}stop(){var e;null!=(e=this._streamerController)&&e.stop()}debugMediaState(){var e;null!=(e=this._streamerController)&&e.debugMediaState()}destroy(){var e,t;if(this._isDestroyed)null!=(t=this._logger)&&t.warning(this,"🔴 [DESTROY] Already destroyed, skipping");else{if(null!=(t=this._logger)&&t.warning(this,"🔴 [DESTROY] Starting streamer instance destruction (sync)..."),this._isDestroyed=!0,this._initialized=!1,this._isRemoved=!0,this.DEV_MODE&&"StormStreamerArray"in window&&(window.StormStreamerArray[this._streamerID]=null),this.stopAllGraphs(),this._graphs=[],this._networkController){null!=(t=this._logger)&&t.info(this,"🔴 [DESTROY] Destroying NetworkController...");try{null!=(e=this._networkController.getConnection())&&e.destroy()}catch(e){}this._networkController=null}if(this._streamerController&&(null!=(t=this._logger)&&t.info(this,"🔴 [DESTROY] Destroying StreamerController..."),this._streamerController.destroy(),this._streamerController=null),this._stageController){null!=(e=this._logger)&&e.info(this,"🔴 [DESTROY] Destroying StageController...");try{this._stageController.destroy()}catch(e){}this._stageController=null}this._storageManager=null,this._statsController=null,this.removeAllEventListeners(),null!=(t=this._logger)&&t.success(this,"🔴 [DESTROY] Streamer instance destroyed successfully (sync)")}}}function create(e){return new StormStreamer(e)}StormStreamer.NEXT_STREAMER_ID=0,exports.StormStreamer=StormStreamer,exports.create=create;
34
+ `;continue}s+="\r\n"}return s}mungeSDPPlay(e){let s="";for(const o of e.split(/\r\n/))if(0!==o.length){if(o.includes("profile-level-id")){var n=o.substr(o.indexOf("profile-level-id")+17,6);let e=Number("0x"+n.substr(0,2)),t=Number("0x"+n.substr(2,2)),i=Number("0x"+n.substr(4,2));66<e&&(e=66,t=224,i=31),0===t&&(t=224);var r=("00"+e.toString(16)).slice(-2).toLowerCase()+("00"+t.toString(16)).slice(-2).toLowerCase()+("00"+i.toString(16)).slice(-2).toLowerCase();s+=o.replace(n,r)}else s+=o;s+="\r\n"}return s}}MungeSDP.SDPOutput={},function(e){e[e.VIDEO_INPUT=0]="VIDEO_INPUT",e[e.AUDIO_INPUT=1]="AUDIO_INPUT"}(InputType=InputType||{});class InputDevice{constructor(e,t){if(this._groupID="",this._isSelected=!1,null==e)throw new Error("no input device");if(void 0===e.deviceId||null===e.deviceId)throw new Error("no deviceID");if(this._id=e.deviceId,void 0===e.kind||null===e.kind)throw new Error("no device kind");switch(e.kind){case"videoinput":this._inputType=InputType.VIDEO_INPUT;break;case"audioinput":this._inputType=InputType.AUDIO_INPUT;break;default:throw new Error("incorrect kind")}null!==e.label&&""!==e.label?this._label=this.cleanLabel(e.label):this._label=this._inputType==InputType.VIDEO_INPUT?"Camera "+t:"Microphone "+t,void 0!==e.groupId&&null!==e.groupId&&(this._groupID=e.groupId)}cleanLabel(e){return e}get label(){return this._label}get id(){return this._id}get groupID(){return this._groupID}get isSelected(){return this._isSelected}set isSelected(e){this._isSelected=e}}class InputDeviceList{constructor(){this._internalList=new Array}push(t){let i=!1;if(0<this._internalList.length){for(let e=0;e<this._internalList.length;e++)""!==this._internalList[e].groupID&&this._internalList[e].groupID==t.groupID&&(i=!0,this._internalList[e]=t);return 0==i?this._internalList.push(t):this._internalList.length}return this._internalList.push(t)}get(e){return this._internalList[e]}getSize(){return this._internalList.length}getArray(){return this._internalList}}exports.PublishState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.INITIALIZED="INITIALIZED",e.CONNECTING="CONNECTING",e.CONNECTED="CONNECTED",e.PUBLISHED="PUBLISHED",e.UNPUBLISHED="UNPUBLISHED",e.STOPPED="STOPPED",e.UNKNOWN="UNKNOWN",e.ERROR="ERROR"}(exports.PublishState||(exports.PublishState={}));class SoundMeter{constructor(e){this._audioContext=null,this._analyser=null,this._microphone=null,this._lastEventTime=0,this.THROTTLE_INTERVAL=100,this._isMonitoring=!1,this._animationFrameId=null,this._instant=0,this._slow=0,this.PEAK_DECAY=.92,this._main=e}attach(e){if(e.getAudioTracks().length){this.detach();try{this._audioContext=new AudioContext,this._microphone=this._audioContext.createMediaStreamSource(e),this._analyser=this._audioContext.createAnalyser(),this._analyser.fftSize=2048,this._microphone.connect(this._analyser),this.startMonitoring()}catch(e){console.error("SoundMeter: Error during attach:",e),this.detach()}}else console.warn("SoundMeter: Attempted to attach stream without audio tracks")}detach(){if(this._audioContext||this._analyser||this._microphone){if(this._isMonitoring=!1,null!==this._animationFrameId&&(cancelAnimationFrame(this._animationFrameId),this._animationFrameId=null),this._microphone){try{this._microphone.disconnect()}catch(e){console.warn("SoundMeter: Error disconnecting microphone:",e)}this._microphone=null}if(this._analyser){try{this._analyser.disconnect()}catch(e){console.warn("SoundMeter: Error disconnecting analyser:",e)}this._analyser=null}if(this._audioContext)try{if("closed"!==this._audioContext.state){const e=this._audioContext;this._audioContext=null,e.suspend().then(()=>e.close()).catch(e=>{console.warn("SoundMeter: Error closing audio context:",e)})}else this._audioContext=null}catch(e){console.warn("SoundMeter: Error handling audio context:",e),this._audioContext=null}this.clear()}}clear(){this._instant=0,this._slow=0,this._lastEventTime=0}startMonitoring(){if(this._analyser&&!this._isMonitoring){this._isMonitoring=!0;const s=new Float32Array(this._analyser.frequencyBinCount),t=()=>{if(this._analyser&&this._isMonitoring&&this._audioContext){var e=Date.now();try{this._analyser.getFloatTimeDomainData(s);let t=0;for(let e=0;e<s.length;++e){var i=Math.abs(s[e]);i>t&&(t=i)}this._instant=Math.min(1,t),this._instant>this._slow?this._slow=this._instant:this._slow*=this.PEAK_DECAY,e-this._lastEventTime>=this.THROTTLE_INTERVAL&&(this._lastEventTime=e,this._main.dispatchEvent("soundMeter",{ref:this._main,high:this._instant,low:this._slow}))}catch(e){return console.error("SoundMeter: Error during analysis:",e),this._isMonitoring=!1,void(this._animationFrameId=null)}this._isMonitoring&&(this._animationFrameId=requestAnimationFrame(t))}else this._animationFrameId=null};this._animationFrameId=requestAnimationFrame(t)}}destroy(){this.detach()}}exports.InputDevicesState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.INITIALIZED="INITIALIZED",e.READY="READY",e.UPDATING="UPDATING",e.INVALID="INVALID",e.UNKNOWN="UNKNOWN",e.STOPPED="STOPPED"}(exports.InputDevicesState||(exports.InputDevicesState={})),exports.DeviceState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.ENABLED="ENABLED",e.ACCESS_DENIED="ACCESS_DENIED",e.NOT_FOUND="NOT_FOUND",e.STOPPED="STOPPED"}(exports.DeviceState||(exports.DeviceState={})),function(e){e[e.NOT_INITIALIZED=0]="NOT_INITIALIZED",e[e.STARTED=1]="STARTED",e[e.CONNECTING=2]="CONNECTING",e[e.CONNECTED=3]="CONNECTED",e[e.CLOSED=4]="CLOSED",e[e.FAILED=5]="FAILED"}(ConnectionState=ConnectionState||{});class AbstractSocket{constructor(){this.CONNECTION_TIMEOUT=5,this.isBinary=!0,this._connectionState=ConnectionState.NOT_INITIALIZED,this._messageCount=0,this._disconnectedByUser=!1,this._isConnected=!1,this._sequenceNumber=-1}startConnection(){this._disconnectedByUser=!1,this._messageCount=0,this._isConnected=!1,this._disconnectedByUser=!1,this._connectionState=ConnectionState.CONNECTING,this.socket=new WebSocket(this.socketURL),this.isBinary&&(this.socket.binaryType="arraybuffer"),this.socket.onopen=e=>{clearTimeout(this._connectionTimeout),this._sequenceNumber++,this._connectionState=ConnectionState.CONNECTED,this.onSocketOpen(e)},this.socket.onmessage=e=>{this._messageCount++,this.onSocketMessage(e)},this.socket.onclose=e=>{clearTimeout(this._connectionTimeout),this._connectionState==ConnectionState.CONNECTED?(this._connectionState=ConnectionState.CLOSED,this.onSocketClose(e)):this._connectionState=ConnectionState.FAILED},this.socket.onerror=e=>{if(clearTimeout(this._connectionTimeout),this._connectionState==ConnectionState.CONNECTING&&this.onSocketError(e),this._connectionState==ConnectionState.CONNECTED)try{this.socket.close()}catch(e){}},this._connectionTimeout=setTimeout(()=>{try{this.socket.close()}catch(e){}this._connectionState==ConnectionState.CONNECTING&&(this._connectionState=ConnectionState.FAILED,this.onSocketError(new ErrorEvent("connectionTimeout")))},1e3*this.CONNECTION_TIMEOUT)}onSocketOpen(e){}onSocketClose(e){}onSocketMessage(e){}onSocketError(e){}onError(e){}sendData(e){if(this._connectionState==ConnectionState.CONNECTED&&null!==this.socket){if(null!=e)return void this.socket.send(e);this.onError("no data to send")}this.onError("socket not connected")}getConnectionState(){return this._connectionState}disconnect(e=!0){this._isConnected=!1,this._connectionState=ConnectionState.CLOSED,e&&(this._logger.warning(this,"Disconnected by user"),this._disconnectedByUser=e),null!=this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onclose=null,this.socket.onerror=null,this.socket.close())}destroy(){void 0!==this.socket&&null!==this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onclose=null,this.socket.onerror=null,this.socket.close()),this._connectionState=ConnectionState.CLOSED}getSocketURL(){return this.socketURL}}class StreamStatusInfo{constructor(){this._publishState=exports.PublishState.NOT_INITIALIZED,this._videoPublishBitrate=0,this._audioPublishBitrate=0,this._currentBitrate=0,this._audioFrameCount=0,this._videoFrameCount=0,this._frameRate=0,this._videoWidth=0,this._videoHeight=0}get publishState(){return this._publishState}set publishState(e){this._publishState="published"===e?exports.PublishState.PUBLISHED:exports.PublishState.CONNECTED}get videoPublishBitrate(){return this._videoPublishBitrate}set videoPublishBitrate(e){this._videoPublishBitrate=e}get audioPublishBitrate(){return this._audioPublishBitrate}set audioPublishBitrate(e){this._audioPublishBitrate=e}set currentBitrate(e){this._currentBitrate=e}get currentBitrate(){return this._currentBitrate}get audioFrameCount(){return this._audioFrameCount}set audioFrameCount(e){this._audioFrameCount=e}get videoFrameCount(){return this._videoFrameCount}set videoFrameCount(e){this._videoFrameCount=e}get frameRate(){return this._frameRate}set frameRate(e){this._frameRate=e}set videoWidth(e){this._videoWidth=e}get videoWidth(){return this._videoWidth}set videoHeight(e){this._videoHeight=e}get videoHeight(){return this._videoHeight}}class WowzaStatusConnection extends AbstractSocket{constructor(e,t){super(),this._logger=e.getLogger(),this._main=e,this._currServer=t,this.initialize()}initialize(){this._logger.info(this,"Starting new status check connection with a storm server"),null!=this._currServer?(this.socketURL=this.createURL(this._currServer),this._logger.info(this,"Starting WebSocket connection with: "+this.socketURL),this.startConnection()):this._logger.error(this,"Connection with the server could not be initialized!")}onSocketOpen(e){this._logger.success(this,"Connection with the server has been established!"),this._main.dispatchEvent("statusServerConnect",{ref:this._main,serverURL:this.socketURL,sequenceNum:this._sequenceNumber}),this._isConnected=!0}onSocketError(e){this._isConnected=!1,this._disconnectedByUser||(this._logger.error(this,"Connection with the server failed"),this._main.dispatchEvent("serverConnectionError",{ref:this._main,serverURL:this.socketURL,restart:this._main.getConfigManager().getSettingsData().getIfRestartOnError(),sequenceNum:this._sequenceNumber}))}onSocketClose(e){this._isConnected=!1,this._disconnectedByUser?this._logger.warning(this,"Force disconnect from server!"):(this._logger.error(this,"Connection with the server has been closed"),this._main.dispatchEvent("statusServerDisconnect",{ref:this._main,serverURL:this.socketURL,restart:this._main.getConfigManager().getSettingsData().getIfRestartOnError(),sequenceNum:this._sequenceNumber}),this.initiateReconnect())}onSocketMessage(e){var t;"string"==typeof e.data&&"STREAM_STATUS_RESPONSE"===(e=JSON.parse(e.data)).packetID&&((t=new StreamStatusInfo).publishState=e.streamStatus,t.videoPublishBitrate=e.publishVideoBitrate,t.audioPublishBitrate=e.publishAudioBitrate,t.videoFrameCount=e.videoFrameCount,t.audioFrameCount=e.audioFrameCount,t.frameRate=e.frameRate,t.videoWidth=e.videoWidth,t.videoHeight=e.videoHeight,t.currentBitrate=e.realBitrate,this._main.dispatchEvent("streamStatusUpdate",{ref:this._main,streamStatus:t}))}initiateReconnect(){var e=this._main.getConfigManager().getSettingsData().getIfRestartOnError();const t=this._main.getConfigManager().getSettingsData().getReconnectTime();this._disconnectedByUser||e&&(null!=this._reconnectTimer&&clearTimeout(this._reconnectTimer),this._reconnectTimer=setTimeout(()=>{null!=this._currServer&&(this._logger.info(this,`Will reconnect to the server in ${t} seconds...`),this.socketURL=this.createURL(this._currServer),this._logger.info(this,"Starting WebSocket connection with: "+this.socketURL),this._main.dispatchEvent("serverConnectionInitiate",{ref:this._main,serverURL:this.socketURL}),this.startConnection())},1e3*t))}createURL(e){var t="";return(t+=e.getIfSSL()?"wss://":"ws://")+e.getHost()+(":"+e.getPort())+"/statuschecker"}isConnectionActive(){return this._isConnected}getCurrentServer(){return this._currServer}destroy(){super.destroy()}}class PublishMetadata{constructor(){this._streamWidth=0,this._streamHeight=0,this._aspectRatio="",this._hasVideoTrack=!1,this._hasAudioTrack=!1}get streamWidth(){return this._streamWidth}set streamWidth(e){this._streamWidth=e}get streamHeight(){return this._streamHeight}set streamHeight(e){this._streamHeight=e}get aspectRatio(){return this._aspectRatio}set aspectRatio(e){this._aspectRatio=e}get videoTrackPresent(){return this._hasVideoTrack}set videoTrackPresent(e){this._hasVideoTrack=e}get audioTrackPresent(){return this._hasAudioTrack}set audioTrackPresent(e){this._hasAudioTrack=e}}class StreamerController{constructor(e){this._isWindowActive=!0,this._peerConnectionConfig={iceServers:[]},this._isMicrophoneMuted=!1,this._pendingMicrophoneState=null,this._permissionChecked=!1,this._constraints={video:{width:{min:"640",ideal:"1024",max:"1024"},height:{min:"360",ideal:"576",max:"576"},frameRate:{min:24,ideal:30,max:30}},audio:!0},this._restartTimerCount=0,this._restartTimerMaxCount=5,this._publishState=exports.PublishState.NOT_INITIALIZED,this._publishTime=0,this._inputDeviceState=exports.InputDevicesState.NOT_INITIALIZED,this._cameraState=exports.DeviceState.NOT_INITIALIZED,this._microphoneState=exports.DeviceState.NOT_INITIALIZED,this._publishTimer=0,this._currentOrientation=(null==(t=window.screen.orientation)?void 0:t.type)||"",this._statusTimer=null,this._debug=!1,this._deviceChangeHandler=null,this._orientationChangeHandler=null,this._isDestroyed=!1,this._cameraAbortController=null,this._microphoneAbortController=null,this._startCameraAbortController=null,this._switchingCamera=!1,this._switchingMicrophone=!1,this._firstPublish=!0,this._activeStreamCount=0,this._cameraPermissionStatus=null,this._microphonePermissionStatus=null,this._boundCameraPermissionHandler=null,this._boundMicrophonePermissionHandler=null,this._isInitializing=!1,this.onDeviceStateChange=e=>{var t;this._isDestroyed||(t=null==(t=this._main.getConfigManager())?void 0:t.getStreamData().streamKey,e.state==exports.InputDevicesState.READY&&null!=t&&this.internalPublish(t))},this.handleOrientationChange=()=>__awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed&&(yield new Promise(e=>setTimeout(e,500)),!this._isDestroyed)){var e=(null==(e=window.screen.orientation)?void 0:e.type)||"";if(this._currentOrientation!==e){this._logger.info(this,`Orientation changed from ${this._currentOrientation} to `+e),this._currentOrientation=e;e=null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey;if(this._publishState,exports.PublishState.PUBLISHED,this.closeWebRTCConnection(),this._stream&&(this._logger.info(this,"📹 [RELEASE] handleOrientationChange() - releasing stream for orientation change"),this._stream.getTracks().forEach(e=>{e.stop(),this._logger.info(this,"📹 [RELEASE] handleOrientationChange() - stopped track: "+e.kind)}),this._stream=null,this._activeStreamCount--),!this._isDestroyed)try{yield this.startCamera(),this._isDestroyed||e&&this.internalPublish(e)}catch(e){this._isDestroyed||(this._logger.error(this,"Error restarting stream after orientation change: "+JSON.stringify(e)),this.setInputDeviceState(exports.InputDevicesState.INVALID))}}}}),this.onServerDisconnect=()=>{},this.onStreamKeyTaken=()=>{this._isDestroyed||(null!=this._restartTimer&&(clearInterval(this._restartTimer),this._restartTimerCount=0),this._logger.info(this,"WebRTCStreamer :: Starting StreamKeyTaken Interval"),this.setPublishState(exports.PublishState.ERROR),this._restartTimer=setInterval(()=>{var e;this._isDestroyed?this._restartTimer&&clearInterval(this._restartTimer):null!=this._restartTimer&&(this._restartTimerCount<this._restartTimerMaxCount?(this._logger.info(this,"WebRTCStreamer :: StreamKeyTaken Interval: "+this._restartTimerCount+"/"+this._restartTimerMaxCount),this._restartTimerCount++):(clearInterval(this._restartTimer),this._restartTimer=null,this._restartTimerCount=0,null==(e=null==(e=null==(e=this._main.getConfigManager())?void 0:e.getStreamData())?void 0:e.streamKey)||this._isDestroyed||this.internalPublish(e)),this._isDestroyed||(e=null!=(e=this._main.getConfigManager().getStreamData().streamKey)?e:"unknown",this._main.dispatchEvent("streamKeyInUseInterval",{ref:this._main,streamKey:e,count:this._restartTimerCount,maxCount:this._restartTimerMaxCount})))},1e3))},this.onServerConnect=()=>{if(!this._isDestroyed){if(this._peerConnection&&this.closeWebRTCConnection(),this._peerConnection=new RTCPeerConnection(this._peerConnectionConfig),this._stream){var e,t=this._stream.getTracks();for(e in t)this._peerConnection.addTrack(t[e],this._stream)}this._peerConnection.onicecandidate=e=>{this.onIceCandidate(e)},this._peerConnection.onconnectionstatechange=e=>{this.onConnectionStateChange(e)},this._peerConnection.onnegotiationneeded=e=>__awaiter(this,void 0,void 0,function*(){if(this._peerConnection&&!this._isDestroyed)try{var e=yield this._peerConnection.createOffer();this._isDestroyed||(yield this.onDescriptionSuccess(e))}catch(e){this.onDescriptionError(e)}}),this.createStatusConnection()}},this.onStatusServerConnect=()=>{var e;this._isDestroyed||(e=this._main.getConfigManager().getStreamData().streamKey,null==this._statusTimer&&null!=this._statusConnection&&null!=e&&(this._statusTimer=setInterval(()=>{this._isDestroyed?this._statusTimer&&clearInterval(this._statusTimer):this.requestStatusData()},1e3)))},this.requestStatusData=()=>{var e;!this._isDestroyed&&this._fullStreamName&&null!=(e=this._statusConnection)&&e.sendData('{"packetID":"STREAM_STATUS", "streamKey": "'+this._fullStreamName+'"}')},this.onStatusServerDisconnect=()=>{null!=this._statusTimer&&clearInterval(this._statusTimer),this._statusTimer=null},this.onStreamStatsUpdate=e=>{this._isDestroyed||(e=e.streamStatus,this._publishState==exports.PublishState.PUBLISHED&&e.publishState!=exports.PublishState.PUBLISHED&&this.setPublishState(exports.PublishState.UNPUBLISHED),this._publishState==exports.PublishState.CONNECTED&&e.publishState==exports.PublishState.PUBLISHED&&this.setPublishState(exports.PublishState.PUBLISHED))},this.onDescriptionSuccess=t=>{var e;if(!this._isDestroyed){const i={applicationName:null==(e=null==(e=null==(e=this._main.getNetworkController())?void 0:e.getConnection())?void 0:e.getCurrentServer())?void 0:e.getApplication(),streamName:this._fullStreamName,sessionId:"[empty]"};t.sdp=this._mungeSDP.mungeSDPPublish(t.sdp,{audioBitrate:"64",videoBitrate:"2000",videoFrameRate:30,videoCodec:"42e01f",audioCodec:"opus"}),this._peerConnection&&!this._isDestroyed&&this._peerConnection.setLocalDescription(t).then(()=>{var e;this._isDestroyed||null!=(e=this._main.getNetworkController())&&e.sendMessage('{"direction":"publish", "command":"sendOffer", "streamInfo":'+JSON.stringify(i)+', "sdp":'+JSON.stringify(t)+"}")}).catch(e=>{console.log(e)})}},this.visibilityChange=()=>{"hidden"===document.visibilityState?this.onWindowBlur():"visible"===document.visibilityState&&this.onWindowFocus()},this.onWindowBlur=()=>{this._isWindowActive&&this._logger.warning(this,"Player window is no longer in focus!"),this._isWindowActive=!1},this.onWindowFocus=()=>{this._isWindowActive||this._logger.info(this,"Player window is focused again!"),this._isWindowActive=!0},this._main=e,this._logger=e.getLogger(),this._mungeSDP=new MungeSDP,this._soundMeter=new SoundMeter(this._main),this._debug=null!=(e=null==(t=this._main.getConfigManager())?void 0:t.getSettingsData().getDebugData().streamerControllerDebug)?e:this._debug;var t,e=null==(t=this._main.getStorageManager())?void 0:t.getField("microphoneMuted");null!==e&&(this._isMicrophoneMuted="true"===e,this._logger.info(this,"📹 [INIT] Restored microphone mute state: "+this._isMicrophoneMuted)),this.initialize()}isDestroyedCheck(e){var t;return!!this._isDestroyed&&(e&&null!=(t=this._logger)&&t.info(this,`📹 [ABORT] ${e} - instance destroyed, aborting`),!0)}initialize(){var e,t;return __awaiter(this,void 0,void 0,function*(){if(!this._isInitializing){this._isInitializing=!0,this._logger.info(this,"📹 [INIT] initialize() - starting initialization");try{if(this.isDestroyedCheck("initialize start"))return;if(yield this.initializeDevices(),this.isDestroyedCheck("after initializeDevices"))return;if(this.setupEventListeners(),this.isDestroyedCheck("after setupEventListeners"))return;if(this.initializeStream(),this.isDestroyedCheck("after initializeStream"))return;if(this.setupOrientationListener(),yield this.setupPermissionListeners(),this.isDestroyedCheck("after setupPermissionListeners"))return;if(this.setupDeviceChangeListener(),this.isDestroyedCheck("before network init"))return;null!=(e=this._main.getConfigManager())&&e.getSettingsData().autoConnect?(this._logger.info(this,"Initializing NetworkController (autoConnect is true)"),null!=(t=this._main.getNetworkController())&&t.initialize()):this._logger.warning(this,"Warning - autoConnect is set to false, switching to standby mode!"),this._logger.success(this,"📹 [INIT] initialize() - completed successfully")}catch(e){if(this._isDestroyed)return void this._logger.warning(this,"📹 [INIT] initialize() - aborted by destroy()");this._logger.error(this,"Initialization failed: "+JSON.stringify(e)),this.setInputDeviceState(exports.InputDevicesState.INVALID)}finally{this._isInitializing=!1}this._main.dispatchEvent("microphoneStateChange",{ref:this._main,isMuted:this._isMicrophoneMuted})}})}setupEventListeners(){this._isDestroyed||(this._main.addEventListener("serverConnect",this.onServerConnect,!1),this._main.addEventListener("serverDisconnect",this.onServerDisconnect,!1),this._main.addEventListener("streamKeyInUse",this.onStreamKeyTaken,!1),this._main.addEventListener("statusServerConnect",this.onStatusServerConnect,!1),this._main.addEventListener("statusServerDisconnect",this.onStatusServerDisconnect,!1),this._main.addEventListener("streamStatusUpdate",this.onStreamStatsUpdate,!1),this._main.addEventListener("deviceStateChange",this.onDeviceStateChange,!1),document.addEventListener("visibilitychange",this.visibilityChange),window.addEventListener("blur",this.onWindowBlur),window.addEventListener("focus",this.onWindowFocus))}initializeDevices(){return __awaiter(this,void 0,void 0,function*(){try{var e;this._logger.info(this,"📹 [ACQUIRE] initializeDevices() - requesting test getUserMedia for permissions"),this.isDestroyedCheck("initializeDevices before getUserMedia")||(e=yield navigator.mediaDevices.getUserMedia({video:!0,audio:!0}),this._isDestroyed?(this._logger.warning(this,"📹 [RELEASE] initializeDevices() - destroyed during getUserMedia, releasing orphan stream"),e.getTracks().forEach(e=>{e.stop(),this._logger.info(this,`📹 [RELEASE] initializeDevices() - stopped orphan track: ${e.kind}, id: `+e.id)})):(this._logger.info(this,"📹 [RELEASE] initializeDevices() - stopping test stream immediately"),e.getTracks().forEach(e=>{e.stop(),this._logger.info(this,`📹 [RELEASE] initializeDevices() - stopped track: ${e.kind}, id: `+e.id)}),this.isDestroyedCheck("initializeDevices before grabDevices")||(yield this.grabDevices())))}catch(e){this._isDestroyed||(console.log(e),this._logger.error(this,"Error initializing devices: "+JSON.stringify(e)),this._isDestroyed)||(yield this.grabDevices())}})}initializeStream(){this._isDestroyed||(this._selectedCamera||this._selectedMicrophone)&&this.startCamera()}setupPermissionListeners(){return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed)try{var e={name:"camera"},t={name:"microphone"};this._cameraPermissionStatus=yield navigator.permissions.query(e),this._isDestroyed||(this._boundCameraPermissionHandler=()=>{this._isDestroyed||(this._permissionChecked=!1,this.handlePermissionChange("camera",this._cameraPermissionStatus.state))},this._cameraPermissionStatus.addEventListener("change",this._boundCameraPermissionHandler),this._microphonePermissionStatus=yield navigator.permissions.query(t),this._isDestroyed)||(this._boundMicrophonePermissionHandler=()=>{this._isDestroyed||(this._permissionChecked=!1,this.handlePermissionChange("microphone",this._microphonePermissionStatus.state))},this._microphonePermissionStatus.addEventListener("change",this._boundMicrophonePermissionHandler))}catch(e){this._logger.warning(this,"Could not set up permission listeners: "+e)}})}removePermissionListeners(){this._cameraPermissionStatus&&this._boundCameraPermissionHandler&&(this._cameraPermissionStatus.removeEventListener("change",this._boundCameraPermissionHandler),this._cameraPermissionStatus=null,this._boundCameraPermissionHandler=null),this._microphonePermissionStatus&&this._boundMicrophonePermissionHandler&&(this._microphonePermissionStatus.removeEventListener("change",this._boundMicrophonePermissionHandler),this._microphonePermissionStatus=null,this._boundMicrophonePermissionHandler=null)}setupDeviceChangeListener(){this._isDestroyed||(this._deviceChangeHandler=()=>__awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed)if(this._publishState===exports.PublishState.PUBLISHED)this._logger.info(this,"Device change detected, but already publish - no restarting streamer");else{this._logger.info(this,"Device change detected, restarting streamer");var e=null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey,t=this._publishState===exports.PublishState.CONNECTED;try{this.stop(),yield new Promise(e=>setTimeout(e,500)),this._isDestroyed||(yield this.start(),this._isDestroyed)||(t&&e&&(this._logger.info(this,"Resuming publishing after device change"),this.isStreamReady(!0,!0)?this.internalPublish(e):(this._logger.warning(this,"Cannot resume publishing - stream not ready after device change"),this._main.dispatchEvent("inputDeviceError",{ref:this._main}))),this._logger.success(this,"Successfully handled device change"))}catch(e){this._isDestroyed||(this._logger.error(this,"Error handling device change: "+JSON.stringify(e)),this.setInputDeviceState(exports.InputDevicesState.INVALID))}}}),navigator.mediaDevices.addEventListener("devicechange",this._deviceChangeHandler))}handlePermissionChange(e,t){return __awaiter(this,void 0,void 0,function*(){this._isDestroyed||(this._logger.info(this,`📹 [PERMISSION] handlePermissionChange() - device: ${e}, state: `+t),"denied"===t&&(this.setInputDeviceState(exports.InputDevicesState.INVALID),this._publishState!=exports.PublishState.CONNECTED&&!this._stream||(this._logger.info(this,"📹 [RELEASE] handlePermissionChange() - permission denied, stopping all streams"),this.stopCameraStream(),this.closeWebRTCConnection())),this._isDestroyed)||(yield this.grabDevices(),this._isDestroyed)||"granted"===t&&(yield this.startCamera())})}onCameraStreamSuccess(e){if(this._isDestroyed)this._logger.warning(this,"📹 [RELEASE] onCameraStreamSuccess() - destroyed, releasing stream immediately"),e.getTracks().forEach(e=>{e.stop()});else{this._activeStreamCount++,this._logger.success(this,`📹 [ACQUIRED] onCameraStreamSuccess() - stream acquired, id: ${e.id}, active streams: `+this._activeStreamCount);var s=e.getVideoTracks()[0],t=e.getAudioTracks()[0],n=new PublishMetadata;if(s){var r=s.getSettings();let e=r.width,t=r.height;/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)&&(e>t&&window.innerWidth<window.innerHeight||e<t&&window.innerWidth>window.innerHeight)&&([e,t]=[t,e]),n.streamWidth=e,n.streamHeight=t,n.videoTrackPresent=!0;const h=(e,t)=>t?h(t,e%t):e;var r=h(e,t),o=e/r,r=t/r,a=e/t;let i=o+":"+r;Math.abs(a-16/9)<.1?i=e>t?"16:9":"9:16":Math.abs(a-4/3)<.1&&(i=e>t?"4:3":"3:4"),n.aspectRatio=i,this._logger.info(this,`📹 [INFO] Video track - id: ${s.id}, enabled: ${s.enabled}, readyState: `+s.readyState)}else n.videoTrackPresent=!1;t&&this._logger.info(this,`📹 [INFO] Audio track - id: ${t.id}, enabled: ${t.enabled}, readyState: `+t.readyState),n.audioTrackPresent=!!t,this._logger.info(this,`Publish MetaData :: Resolution: ${n.streamWidth}x${n.streamHeight} | `+`Aspect ratio: ${n.aspectRatio}, `+`Video track: ${n.videoTrackPresent} | Audio track: `+n.audioTrackPresent),this._isDestroyed?(this._logger.warning(this,"📹 [RELEASE] onCameraStreamSuccess() - destroyed during setup, releasing"),e.getTracks().forEach(e=>e.stop()),this._activeStreamCount--):(this._main.dispatchEvent("publishMetadataUpdate",{ref:this._main,metadata:n}),this._stream=e,null!==this._pendingMicrophoneState?(this.applyMicrophoneState(this._pendingMicrophoneState),this._pendingMicrophoneState=null):this.applyMicrophoneState(!this._isMicrophoneMuted),0<this._stream.getAudioTracks().length&&this._soundMeter.attach(this._stream),null!=this._cameraList&&null!=this._microphoneList||this.grabDevices(),(a=null==(r=null==(o=this._main.getStageController())?void 0:o.getScreenElement())?void 0:r.getVideoElement())&&(a.srcObject=e,a.autoplay=!0,a.playsInline=!0,a.disableRemotePlayback=!0,a.controls=!1,a.muted=!0),this.setPublishState(exports.PublishState.INITIALIZED))}}initializeWebRTC(){var e;this._isDestroyed||(this._stream?this._peerConnection?(this._logger.info(this,"WebRTC connection already exists, updating stream"),this.updateWebRTCStream()):(this._logger.info(this,"Initializing new WebRTC connection"),null!=(e=this._main.getNetworkController())&&e.start()):this._logger.error(this,"Cannot initialize WebRTC - no camera stream available"))}publish(e){return!this._isDestroyed&&(this._debug&&this._logger.decoratedLog("Publishing: "+e,"dark-red"),this._logger.info(this,"Publish: "+e),this._main.getConfigManager().getStreamData().streamKey==e?(this._debug&&this._logger.decoratedLog("Canceling publishing, already published "+e,"dark-red"),this._logger.info(this,"Canceling publishing, already published "+e),!1):this.internalPublish(e))}internalPublish(e){return!(this._isDestroyed||(null!=this._statusTimer&&clearInterval(this._statusTimer),null==this._main.getConfigManager().getStreamData().streamKey||this._firstPublish||(this._debug&&this._logger.decoratedLog("Unpublishing active session: "+this._main.getConfigManager().getStreamData().streamKey,"dark-red"),this.unpublish()),this._main.getConfigManager().getStreamData().streamKey=e,this._fullStreamName=e+"_"+(new Date).getTime(),this.isStreamReady(!0,!0)?(this.closeWebRTCConnection(),this._main.dispatchEvent("publish",{ref:this._main,streamKey:e}),this.initializeWebRTC(),this._firstPublish=!1):(this._logger.warning(this,"Cannot publish - stream not ready (missing video or audio track)"),1)))}unpublish(){this._debug&&this._logger.decoratedLog("Unpublish","dark-red"),this._logger.info(this,"📹 [UNPUBLISH] unpublish() - stopping WebRTC but keeping camera preview"),null!=this._statusConnection&&(this._statusConnection.destroy(),this._statusConnection=null),null!=this._statusTimer&&(clearInterval(this._statusTimer),this._statusTimer=null),clearTimeout(this._publishTimer),this._main.getConfigManager().getStreamData().streamKey=null,this._main.dispatchEvent("unpublish",{ref:this._main}),this.closeWebRTCConnection(),this.setPublishState(exports.PublishState.UNPUBLISHED)}unpublishAndRelease(){this._logger.info(this,"📹 [UNPUBLISH+RELEASE] unpublishAndRelease() - stopping everything"),this._debug&&this._logger.decoratedLog("Unpublish + Release","dark-red"),this.unpublish(),this.stopCameraStream()}setupOrientationListener(){this._isDestroyed||(this._orientationChangeHandler=this.handleOrientationChange,window.screen&&window.screen.orientation?window.screen.orientation.addEventListener("change",this._orientationChangeHandler):window.addEventListener("orientationchange",this._orientationChangeHandler))}onUserMediaError(e){return __awaiter(this,void 0,void 0,function*(){this._isDestroyed||(this._logger.error(this,`📹 [ERROR] onUserMediaError() - ${e.name}: `+e.message),yield this.grabDevices(),"OverconstrainedError"===e.name&&this._logger.warning(this,"Device constraints not satisfied"))})}checkIndividualDeviceAccess(){return __awaiter(this,void 0,void 0,function*(){var t={camera:{allowed:!1,available:!1},microphone:{allowed:!1,available:!1}};if(!this._isDestroyed)try{var e=yield navigator.mediaDevices.enumerateDevices();if(this._isDestroyed)return t;if(t.camera.available=e.some(e=>"videoinput"===e.kind),t.microphone.available=e.some(e=>"audioinput"===e.kind),e.some(e=>""!==e.label))t.camera.allowed=e.some(e=>"videoinput"===e.kind&&""!==e.label),t.microphone.allowed=e.some(e=>"audioinput"===e.kind&&""!==e.label);else{if(this._logger.info(this,"📹 [ACQUIRE] checkIndividualDeviceAccess() - no labels, requesting permissions"),this._isDestroyed)return t;try{var i=yield navigator.mediaDevices.getUserMedia({video:t.camera.available,audio:t.microphone.available});if(this._isDestroyed)return this._logger.warning(this,"📹 [RELEASE] checkIndividualDeviceAccess() - destroyed, releasing orphan stream"),i.getTracks().forEach(e=>e.stop()),t;if(t.camera.allowed=0<i.getVideoTracks().length,t.microphone.allowed=0<i.getAudioTracks().length,this._logger.info(this,"📹 [RELEASE] checkIndividualDeviceAccess() - stopping test stream"),i.getTracks().forEach(e=>{e.stop(),this._logger.info(this,"📹 [RELEASE] checkIndividualDeviceAccess() - stopped track: "+e.kind)}),this._isDestroyed)return t;yield this.grabDevices()}catch(e){console.error("Error requesting permissions:",e),t.camera.allowed=!1,t.microphone.allowed=!1}}}catch(e){console.error("Error checking devices:",e)}return t})}onSocketMessage(e){if(!this._isDestroyed){var t=JSON.parse(e);switch(Number(t.status)){case 200:this._logger.info(this,"SDP Exchange Successful");var i=t.sdp,s=(void 0!==i&&this._peerConnection&&this._peerConnection.setRemoteDescription(new RTCSessionDescription(i),()=>{},()=>{}),t.iceCandidates);if(void 0!==s)for(var n in s)this._peerConnection&&this._peerConnection.addIceCandidate(new RTCIceCandidate(s[n]));break;case 503:this._logger.error(this,"StreamKey already use");i=null!=(i=this._main.getConfigManager().getStreamData().streamKey)?i:"unknown";this._main.dispatchEvent("streamKeyInUse",{ref:this._main,streamKey:i}),this.setPublishState(exports.PublishState.ERROR)}}}onConnectionStateChange(e){if(!this._isDestroyed&&(this._logger.info(this,"Connection State Change: "+JSON.stringify(e)),null!==e))switch(e.currentTarget.connectionState){case"connecting":this._logger.info(this,"WebRTCStreamer :: Event: onStreamerConnecting"),this.setPublishState(exports.PublishState.CONNECTING);break;case"connected":this._logger.info(this,"WebRTCStreamer :: Event: onStreamerConnected"),this.setPublishState(exports.PublishState.CONNECTED),this.muteMicrophone(this._isMicrophoneMuted);break;case"disconnected":this._logger.info(this,"WebRTCStreamer :: Event: onStreamerDisconnected"),this.setPublishState(exports.PublishState.UNPUBLISHED);break;case"failed":this._logger.info(this,"WebRTCStreamer :: Event: onPlayerFailed"),this.setPublishState(exports.PublishState.ERROR);break;default:this._logger.info(this,"WebRTCStreamer :: Unsupported onConnectionStateChange: "+e.currentTarget.connectionState)}}grabDevices(){return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed)try{var e=yield this.checkIndividualDeviceAccess();if(!this._isDestroyed&&(this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._permissionChecked||(e.camera.allowed?e.camera.available||(this._main.dispatchEvent("noCameraFound",{ref:this._main}),this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID)):(this._main.dispatchEvent("cameraAccessDenied",{ref:this._main}),this.setCameraState(exports.DeviceState.ACCESS_DENIED),this.setInputDeviceState(exports.InputDevicesState.INVALID)),e.microphone.allowed?e.microphone.available||(this._main.dispatchEvent("noMicrophoneFound",{ref:this._main}),this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID)):(this._main.dispatchEvent("microphoneAccessDenied",{ref:this._main}),this.setMicrophoneState(exports.DeviceState.ACCESS_DENIED),this.setInputDeviceState(exports.InputDevicesState.INVALID))),!this._isDestroyed)){var t,i,s=yield navigator.mediaDevices.enumerateDevices();if(!this._isDestroyed){for(const n of s)n.deviceId&&n.label&&("videoinput"===n.kind&&e.camera.allowed?(t=new InputDevice(n,this._cameraList.getSize()),this._cameraList.push(t)):"audioinput"===n.kind&&e.microphone.allowed&&(i=new InputDevice(n,this._microphoneList.getSize()),this._microphoneList.push(i)));if(!this._isDestroyed){try{e.camera.allowed&&(this._selectedCamera=this.pickCamera()),e.microphone.allowed&&(this._selectedMicrophone=this.pickMicrophone())}catch(e){console.log(e),this.setInputDeviceState(exports.InputDevicesState.INVALID),this._logger.error(this,"Error on grab devices: "+JSON.stringify(e))}this._isDestroyed||this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._permissionChecked=!0}}}}catch(e){this._isDestroyed||(console.error("Error in grabDevices:",e),this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._isDestroyed)||(this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._main.dispatchEvent("inputDeviceError",{ref:this._main}))}})}selectCamera(i){var n,r,o;return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed){this._cameraAbortController&&this._cameraAbortController.abort(),this._cameraAbortController=new AbortController;const s=this._cameraAbortController.signal;try{this._switchingCamera=!0,this._logger.info(this,"📹 [SWITCH] selectCamera() - switching to camera: "+i);for(let e=0;e<this._cameraList.getSize();e++)this._cameraList.get(e).isSelected=!1;this._selectedCamera=null,this.setInputDeviceState(exports.InputDevicesState.UPDATING),this.setCameraState(exports.DeviceState.NOT_INITIALIZED);var e=null==(n=this._main.getConfigManager())?void 0:n.getStreamData().streamKey,t=this._publishState===exports.PublishState.CONNECTED;for(let e=0;e<this._cameraList.getSize();e++)if(this._cameraList.get(e).id==i){this._selectedCamera=this._cameraList.get(e),this._selectedCamera.isSelected=!0,null!=(r=this._main.getStorageManager())&&r.saveField("cameraID",this._selectedCamera.id);break}this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),s.aborted||this._isDestroyed||(this.stopCameraStream(),null!=this._selectedCamera?(this._constraints.video.deviceId=this._selectedCamera.id,s.aborted||this._isDestroyed||(yield new Promise((e,t)=>{const i=setTimeout(e,500);s.addEventListener("abort",()=>{clearTimeout(i),t(new Error("Aborted"))})}),s.aborted)||this._isDestroyed||(yield this.startCamera(),this._isDestroyed)||(this.setCameraState(exports.DeviceState.ENABLED),this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED?this.setInputDeviceState(exports.InputDevicesState.READY):this.setInputDeviceState(exports.InputDevicesState.INVALID),t&&e&&!s.aborted&&!this._isDestroyed&&this.internalPublish(e))):this.setInputDeviceState(exports.InputDevicesState.INVALID))}catch(e){"Aborted"===e.message||this._isDestroyed||(this._logger.error(this,"📹 [ERROR] selectCamera() - Error switching camera: "+e),this.setInputDeviceState(exports.InputDevicesState.INVALID))}finally{this._switchingCamera=!1,(null==(o=this._cameraAbortController)?void 0:o.signal)===s&&(this._cameraAbortController=null)}}})}selectMicrophone(i){var n,r,o;return __awaiter(this,void 0,void 0,function*(){if(!this._isDestroyed){this._microphoneAbortController&&this._microphoneAbortController.abort(),this._microphoneAbortController=new AbortController;const s=this._microphoneAbortController.signal;try{this._switchingMicrophone=!0,this._logger.info(this,"📹 [SWITCH] selectMicrophone() - switching to microphone: "+i);for(let e=0;e<this._microphoneList.getSize();e++)this._microphoneList.get(e).isSelected=!1;this._selectedMicrophone=null,this.setInputDeviceState(exports.InputDevicesState.UPDATING),this.setMicrophoneState(exports.DeviceState.NOT_INITIALIZED);var e=null==(n=this._main.getConfigManager())?void 0:n.getStreamData().streamKey,t=this._publishState===exports.PublishState.CONNECTED;for(let e=0;e<this._microphoneList.getSize();e++)if(this._microphoneList.get(e).id==i){this._selectedMicrophone=this._microphoneList.get(e),this._selectedMicrophone.isSelected=!0,null!=(r=this._main.getStorageManager())&&r.saveField("microphoneID",this._selectedMicrophone.id);break}this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),s.aborted||this._isDestroyed||(this._soundMeter.detach(),this.closeWebRTCConnection(),this._stream&&(this._logger.info(this,"📹 [RELEASE] selectMicrophone() - stopping current stream"),this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null,this._activeStreamCount--),s.aborted)||this._isDestroyed||(yield new Promise((e,t)=>{const i=setTimeout(e,500);s.addEventListener("abort",()=>{clearTimeout(i),t(new Error("Aborted"))})}),s.aborted)||this._isDestroyed||(yield this.startCamera(),this._isDestroyed)||(this.setMicrophoneState(exports.DeviceState.ENABLED),this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED?this.setInputDeviceState(exports.InputDevicesState.READY):this.setInputDeviceState(exports.InputDevicesState.INVALID),t&&e&&!s.aborted&&!this._isDestroyed&&this.internalPublish(e))}catch(e){"Aborted"===e.message||this._isDestroyed||(console.error("Error changing microphone:",e),this._main.dispatchEvent("inputDeviceError",{ref:this._main}),this.setInputDeviceState(exports.InputDevicesState.INVALID))}finally{this._switchingMicrophone=!1,(null==(o=this._microphoneAbortController)?void 0:o.signal)===s&&(this._microphoneAbortController=null)}}})}startCamera(){var s;return __awaiter(this,void 0,void 0,function*(){if(this._isDestroyed)this._logger.warning(this,"📹 [ACQUIRE] startCamera() - aborted, instance is destroyed");else{this._startCameraAbortController&&this._startCameraAbortController.abort(),this._startCameraAbortController=new AbortController;var t=this._startCameraAbortController.signal;this._stream&&(this._logger.info(this,"📹 [RELEASE] startCamera() - releasing existing stream before acquiring new one"),this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null,this._activeStreamCount--);try{var i={video:!!this._selectedCamera&&Object.assign(Object.assign({},this._constraints.video),{deviceId:{exact:this._selectedCamera.id}}),audio:!!this._selectedMicrophone&&{deviceId:{exact:this._selectedMicrophone.id}}};if(!t.aborted&&!this._isDestroyed){this._logger.info(this,"📹 [ACQUIRE] startCamera() - requesting getUserMedia");try{var e=yield navigator.mediaDevices.getUserMedia(i);if(t.aborted||this._isDestroyed)return this._logger.warning(this,"📹 [RELEASE] startCamera() - destroyed during getUserMedia, releasing orphan stream"),void e.getTracks().forEach(e=>{e.stop(),this._logger.info(this,`📹 [RELEASE] startCamera() - stopped orphan track: ${e.kind}, id: `+e.id)});this._stream=e,this.onCameraStreamSuccess(this._stream)}catch(e){if(t.aborted||this._isDestroyed)return;this._logger.error(this,`📹 [ERROR] startCamera() - getUserMedia failed: ${e.name}: `+e.message),i.video&&this.onUserMediaError({name:e.name||"Error",message:e.message||"Unknown error",deviceType:"video"}),i.audio&&this.onUserMediaError({name:e.name||"Error",message:e.message||"Unknown error",deviceType:"audio"})}this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED&&this.setInputDeviceState(exports.InputDevicesState.READY)}}catch(e){this._isDestroyed||(console.error("Error in startCamera:",e),yield this.grabDevices())}finally{(null==(s=this._startCameraAbortController)?void 0:s.signal)===t&&(this._startCameraAbortController=null)}}})}updateWebRTCStream(){this._isDestroyed||this._peerConnection&&this._stream&&(this._peerConnection.getSenders().forEach(e=>{this._peerConnection&&this._peerConnection.removeTrack(e)}),this._stream.getTracks().forEach(e=>{null!=this._stream&&this._peerConnection&&this._peerConnection.addTrack(e,this._stream)}))}pickCamera(){var e;if(this._isDestroyed)return null;for(let e=0;e<this._cameraList.getSize();e++)this._cameraList.get(e).isSelected=!1;var i=null!=(e=null==(e=this._main.getStorageManager())?void 0:e.getField("cameraID"))?e:null;if(0<this._cameraList.getSize()){if(i){let t=!1;for(let e=0;e<this._cameraList.getSize();e++)if(this._cameraList.get(e).id===i){this._selectedCamera=this._cameraList.get(e),this._selectedCamera.isSelected=!0,this.setCameraState(exports.DeviceState.ENABLED),t=!0,this._constraints.video.deviceId=this._selectedCamera.id;break}t||(this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID),this._main.dispatchEvent("savedCameraNotFound",{ref:this._main,savedDeviceID:i}),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null))}if(!this._selectedCamera){if(this._main.dispatchEvent("savedCameraNotFound",{ref:this._main,savedDeviceID:null}),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null),null==(e=this._main.getConfigManager())||!e.getSettingsData().getIfForceSelection())return this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID),null;this._selectedCamera=this._cameraList.get(0),this._selectedCamera.isSelected=!0,null!=(e=this._main.getStorageManager())&&e.saveField("cameraID",this._selectedCamera.id),this._constraints.video.deviceId=this._selectedCamera.id,this.setCameraState(exports.DeviceState.ENABLED)}}return this._isDestroyed||this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._selectedCamera}pickMicrophone(){var e;if(this._isDestroyed)return null;for(let e=0;e<this._microphoneList.getSize();e++)this._microphoneList.get(e).isSelected=!1;var i=null!=(e=null==(e=this._main.getStorageManager())?void 0:e.getField("microphoneID"))?e:null;if(0<this._microphoneList.getSize()){if(i){let t=!1;for(let e=0;e<this._microphoneList.getSize();e++)if(this._microphoneList.get(e).id===i){this._selectedMicrophone=this._microphoneList.get(e),t=!0,this.setMicrophoneState(exports.DeviceState.ENABLED);break}t||(this._main.dispatchEvent("savedMicrophoneNotFound",{ref:this._main,savedDeviceID:i}),this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null))}if(!this._selectedMicrophone){if(this._main.dispatchEvent("savedMicrophoneNotFound",{ref:this._main,savedDeviceID:null}),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null),null==(e=this._main.getConfigManager())||!e.getSettingsData().getIfForceSelection())return this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.InputDevicesState.INVALID),null;this._selectedMicrophone=this._microphoneList.get(0),this.setMicrophoneState(exports.DeviceState.ENABLED),null!=(e=this._main.getStorageManager())&&e.saveField("microphoneID",this._selectedMicrophone.id)}this._selectedMicrophone.isSelected=!0,this._constraints.audio={deviceId:this._selectedMicrophone.id}}return this._selectedMicrophone}clearSavedDevices(){var e;null!=(e=this._main.getStorageManager())&&e.removeField("cameraID"),null!=(e=this._main.getStorageManager())&&e.removeField("microphoneID")}messSavedDevices(){var e;null!=(e=this._main.getStorageManager())&&e.saveField("cameraID","a"),null!=(e=this._main.getStorageManager())&&e.saveField("microphoneID","b")}muteMicrophone(e){var t;this._isDestroyed||this._isMicrophoneMuted!==e&&(this._isMicrophoneMuted=e,null!=(t=this._main.getStorageManager())&&t.saveField("microphoneMuted",e?"true":"false"),this._stream?this.applyMicrophoneState(!e):this._pendingMicrophoneState=!e,this._main.dispatchEvent("microphoneStateChange",{ref:this._main,isMuted:this._isMicrophoneMuted}))}applyMicrophoneState(t){var e;this._stream&&(e=this._stream.getAudioTracks())&&0<e.length&&e.forEach(e=>e.enabled=t)}isStreamReady(e=!0,t=!0){var i,s;return!!this._stream&&(s=this._stream.getVideoTracks(),i=this._stream.getAudioTracks(),e=!e||0<s.length&&"live"===s[0].readyState,s=!t||0<i.length&&"live"===i[0].readyState,e)&&s}closeWebRTCConnection(){if(this._peerConnection){this._logger.info(this,"📡 [WEBRTC] closeWebRTCConnection() - closing peer connection"),this._peerConnection.onicecandidate=null,this._peerConnection.onconnectionstatechange=null,this._peerConnection.onnegotiationneeded=null;try{this._peerConnection.close()}catch(e){}this._peerConnection=null}}onDescriptionError(e){this._logger.info(this,"WebRTCStreamer :: onDescriptionError: "+JSON.stringify(e))}onIceCandidate(e){e.candidate}createStatusConnection(){var e;this._isDestroyed||(e=null==(e=null==(e=null==(e=this._main)?void 0:e.getNetworkController())?void 0:e.getConnection())?void 0:e.getCurrentServer())&&(this._statusConnection&&!this._statusConnection.isConnectionActive()&&this._statusConnection.destroy(),this._statusConnection=new WowzaStatusConnection(this._main,e))}isMicrophoneMuted(){return this._isMicrophoneMuted}getCurrentCamera(){return this._selectedCamera}getCurrentMicrophone(){return this._selectedMicrophone}setPublishState(e){this._publishState==e||this._isDestroyed||(this._debug&&this._logger.decoratedLog("Publish State: "+e,"dark-blue"),this._logger.info(this,"Publish State: "+e),e==exports.PublishState.PUBLISHED&&(this._publishTime=(new Date).getTime()),this._publishState=e,this._main.dispatchEvent("publishStateChange",{ref:this._main,state:this._publishState}))}getPublishTime(){return this._publishState==exports.PublishState.PUBLISHED?this._publishTime:0}setInputDeviceState(e){this._inputDeviceState==e||this._isDestroyed||(this._inputDeviceState=e,this._main.dispatchEvent("deviceStateChange",{ref:this._main,state:this._inputDeviceState,selectedCamera:this._selectedCamera,selectedMicrophone:this._selectedMicrophone}))}getInputDeviceState(){return this._inputDeviceState}setCameraState(e){this._cameraState==e||this._isDestroyed||(this._cameraState=e,this._main.dispatchEvent("cameraDeviceStateChange",{ref:this._main,state:e,selectedCamera:this._selectedCamera}))}getCameraState(){return this._cameraState}setMicrophoneState(e){this._microphoneState==e||this._isDestroyed||(this._microphoneState=e,this._main.dispatchEvent("microphoneDeviceStateChange",{ref:this._main,state:e,selectedMicrophone:this._selectedMicrophone}))}getMicrophoneState(){return this._microphoneState}getCameraList(){return null!=this._cameraList?this._cameraList.getArray():[]}getMicrophoneList(){return null!=this._microphoneList?this._microphoneList.getArray():[]}getPublishState(){return this._publishState}debugMediaState(){console.group("🎥 Media Debug State"),console.log("=== STREAM INFO ==="),console.log("this._stream:",this._stream),console.log("Active stream count:",this._activeStreamCount),console.log("Is destroyed:",this._isDestroyed),this._stream&&(console.log("Stream ID:",this._stream.id),console.log("Stream active:",this._stream.active),console.log("--- Video Tracks ---"),this._stream.getVideoTracks().forEach((e,t)=>{console.log(` Track ${t}:`,{id:e.id,enabled:e.enabled,readyState:e.readyState,muted:e.muted})}),console.log("--- Audio Tracks ---"),this._stream.getAudioTracks().forEach((e,t)=>{console.log(` Track ${t}:`,{id:e.id,enabled:e.enabled,readyState:e.readyState,muted:e.muted})})),console.log("=== VIDEO ELEMENT ===");var e=null==(e=null==(e=this._main.getStageController())?void 0:e.getScreenElement())?void 0:e.getVideoElement();(null==e?void 0:e.srcObject)instanceof MediaStream&&(e=e.srcObject,console.log("Video srcObject stream ID:",e.id),console.log("Video srcObject active:",e.active),console.log("Same as this._stream:",e===this._stream)),console.groupEnd()}stopCameraStream(){var e;this._stream&&(this._logger.info(this,"📹 [RELEASE] stopCameraStream() - stopping stream, id: "+this._stream.id),this._stream.getTracks().forEach(e=>{this._logger.info(this,`📹 [RELEASE] stopCameraStream() - stopping track: ${e.kind}, id: `+e.id),e.stop()}),(e=null==(e=null==(e=this._main.getStageController())?void 0:e.getScreenElement())?void 0:e.getVideoElement())&&(e.srcObject=null),this._soundMeter.detach(),this._stream=null,this._activeStreamCount--,this._logger.info(this,"📹 [RELEASE] stopCameraStream() - complete, active streams: "+this._activeStreamCount))}stop(){this._logger.info(this,"📹 [STOP] stop() - stopping all operations"),this._cameraAbortController&&(this._cameraAbortController.abort(),this._cameraAbortController=null),this._microphoneAbortController&&(this._microphoneAbortController.abort(),this._microphoneAbortController=null),this._startCameraAbortController&&(this._startCameraAbortController.abort(),this._startCameraAbortController=null),this._statusConnection&&(this._statusConnection.destroy(),this._statusConnection=null),this._statusTimer&&(clearInterval(this._statusTimer),this._statusTimer=null),this._main.getConfigManager().getStreamData().streamKey=null,this.closeWebRTCConnection(),this.stopCameraStream(),this.setPublishState(exports.PublishState.STOPPED),this.setInputDeviceState(exports.InputDevicesState.STOPPED),this.setCameraState(exports.DeviceState.STOPPED),this.setMicrophoneState(exports.DeviceState.STOPPED),this._restartTimer&&(clearInterval(this._restartTimer),this._restartTimer=null),this._restartTimerCount=0,clearTimeout(this._publishTimer)}start(){var e,t,i;return __awaiter(this,void 0,void 0,function*(){if(this._isDestroyed||this._isInitializing)this._logger.warning(this,"📹 [START] start() - skipped (destroyed or already initializing)");else if(this._publishState!==exports.PublishState.STOPPED&&this._publishState!==exports.PublishState.NOT_INITIALIZED)this._logger.warning(this,"📹 [START] start() - already running, ignoring");else if(this._inputDeviceState!==exports.InputDevicesState.STOPPED&&this._inputDeviceState!==exports.InputDevicesState.NOT_INITIALIZED)this._logger.warning(this,"📹 [START] start() - devices already initializing/ready, ignoring");else{this._logger.info(this,"📹 [START] start() - reinitializing streaming");try{this._publishState=exports.PublishState.NOT_INITIALIZED,this._inputDeviceState=exports.InputDevicesState.NOT_INITIALIZED,this._cameraState=exports.DeviceState.NOT_INITIALIZED,this._microphoneState=exports.DeviceState.NOT_INITIALIZED,yield this.initializeDevices(),this._isDestroyed||(yield this.startCamera(),this._isDestroyed)||(null!=(e=this._main.getConfigManager())&&e.getSettingsData().autoConnect&&null!=(t=this._main.getNetworkController())&&t.initialize(),null!=(i=this._main.getConfigManager())&&i.getStreamData().streamKey&&this.createStatusConnection())}catch(e){if(!this._isDestroyed)throw this._logger.error(this,"📹 [START] start() - failed: "+JSON.stringify(e)),this.setInputDeviceState(exports.InputDevicesState.INVALID),e}}})}destroy(){var e,t,i,s;if(this._isDestroyed)null!=(e=this._logger)&&e.warning(this,"🔴 [DESTROY] Already destroyed, skipping");else{this._logger.info(this,"🔴 [DESTROY] Starting StreamerController destroy (sync)..."),this._isDestroyed=!0,this._cameraAbortController&&(this._cameraAbortController.abort(),this._cameraAbortController=null),this._microphoneAbortController&&(this._microphoneAbortController.abort(),this._microphoneAbortController=null),this._startCameraAbortController&&(this._startCameraAbortController.abort(),this._startCameraAbortController=null),null!=this._statusTimer&&(clearInterval(this._statusTimer),this._statusTimer=null),null!=this._restartTimer&&(clearInterval(this._restartTimer),this._restartTimer=null),clearTimeout(this._publishTimer),this.removePermissionListeners(),this._deviceChangeHandler&&(navigator.mediaDevices.removeEventListener("devicechange",this._deviceChangeHandler),this._deviceChangeHandler=null),this._orientationChangeHandler&&(window.screen&&window.screen.orientation?window.screen.orientation.removeEventListener("change",this._orientationChangeHandler):window.removeEventListener("orientationchange",this._orientationChangeHandler),this._orientationChangeHandler=null);try{this._main.removeEventListener("serverConnect",this.onServerConnect),this._main.removeEventListener("serverDisconnect",this.onServerDisconnect),this._main.removeEventListener("streamKeyInUse",this.onStreamKeyTaken),this._main.removeEventListener("statusServerConnect",this.onStatusServerConnect),this._main.removeEventListener("statusServerDisconnect",this.onStatusServerDisconnect),this._main.removeEventListener("streamStatusUpdate",this.onStreamStatsUpdate),this._main.removeEventListener("deviceStateChange",this.onDeviceStateChange),document.removeEventListener("visibilitychange",this.visibilityChange),window.removeEventListener("blur",this.onWindowBlur),window.removeEventListener("focus",this.onWindowFocus)}catch(e){}this._statusConnection&&(this._statusConnection.destroy(),this._statusConnection=null),this.closeWebRTCConnection(),this._stream&&(this._logger.info(this,"📹 [FORCE_STOP] Stopping main stream"),this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null);try{var n=null==(i=null==(t=this._main.getStageController())?void 0:t.getScreenElement())?void 0:i.getVideoElement();n&&(n.srcObject instanceof MediaStream&&n.srcObject.getTracks().forEach(e=>e.stop()),n.srcObject=null)}catch(e){}try{null!=(s=this._soundMeter)&&s.destroy()}catch(e){}this._selectedCamera=null,this._selectedMicrophone=null,this._activeStreamCount=0,this._logger.success(this,"🔴 [DESTROY] StreamerController destroyed (sync)")}}}class WowzaConnection extends AbstractSocket{constructor(e,t){super(),this._logger=e.getLogger(),this._main=e,this._networkController=t,this.initialize()}initialize(){this._logger.info(this,"Starting new connection with a storm server"),this.pickServerFromList(this._main.getConfigManager().getStreamData().getServerList()),null!=this._currServer?(this.socketURL=this.createURL(this._currServer),this._logger.info(this,"Starting WebSocket connection with: "+this.socketURL),this._main.dispatchEvent("serverConnectionInitiate",{ref:this._main,serverURL:this.socketURL}),this._main.getConfigManager().getIfDemoMode()?(this._logger.warning(this,"Player is in demo mode, and will not connect with a server!"),this._main.dispatchEvent("authorizationComplete",{ref:this._main})):this.startConnection()):this._logger.error(this,"Connection with the server could not be initialized!")}onSocketOpen(e){this._logger.success(this,"Connection with the server has been established!"),this._main.dispatchEvent("serverConnect",{ref:this._main,serverURL:this.socketURL,sequenceNum:this._sequenceNumber}),this._isConnected=!0}onSocketError(e){this._isConnected=!1,this._disconnectedByUser||(this._logger.error(this,"Connection with the server failed"),this._main.dispatchEvent("serverConnectionError",{ref:this._main,serverURL:this.socketURL,restart:this._main.getConfigManager().getSettingsData().getIfRestartOnError(),sequenceNum:this._sequenceNumber}),0==this._isConnected&&(this._currServer.setAsFaild(!0),this.initiateReconnect()))}onSocketClose(e){this._isConnected=!1,this._disconnectedByUser?this._logger.warning(this,"Force disconnect from server!"):(this._logger.error(this,"Connection with the server has been closed"),this._main.dispatchEvent("serverDisconnect",{ref:this._main,serverURL:this.socketURL,restart:this._main.getConfigManager().getSettingsData().getIfRestartOnError(),sequenceNum:this._sequenceNumber}),this.initiateReconnect())}onSocketMessage(e){this._networkController.onMessage(e)}createURL(e){var t="";return(t+=e.getIfSSL()?"wss://":"ws://")+e.getHost()+(":"+e.getPort())+"/webrtc-session.json"}initiateReconnect(){var e=this._main.getConfigManager().getSettingsData().getIfRestartOnError();const t=this._main.getConfigManager().getSettingsData().getReconnectTime();this._disconnectedByUser||e&&(null!=this._reconnectTimer&&clearTimeout(this._reconnectTimer),this._reconnectTimer=setTimeout(()=>{this.pickServerFromList(this._main.getConfigManager().getStreamData().getServerList()),null!=this._currServer&&(this._logger.info(this,`Will reconnect to the server in ${t} seconds...`),this.socketURL=this.createURL(this._currServer),this._logger.info(this,"Starting WebSocket connection with: "+this.socketURL),this._main.dispatchEvent("serverConnectionInitiate",{ref:this._main,serverURL:this.socketURL}),this.startConnection())},1e3*t))}pickServerFromList(t){let i=null;for(let e=0;e<t.length;e++)if(!t[e].getIfFaild()){i=t[e];break}null==i?(this._logger.error(this,"All connections failed!"),this._main.dispatchEvent("allConnectionsFailed",{ref:this._main,mode:"none"}),this._currServer=null):this._currServer=i}isConnectionActive(){return this._isConnected}getCurrentServer(){return this._currServer}destroy(){super.destroy(),null!=this._reconnectTimer&&clearTimeout(this._reconnectTimer)}}class NetworkController{constructor(e){this._connection=null,this._currentStreamKey="none",this._lastState="",this._isDestroyed=!1,this.onServerConnect=()=>{},this.onServerDisconnect=()=>{this._lastState="none"},this.onMessage=e=>{var t;null!=(t=this._main.getStreamerController())&&t.onSocketMessage(e.data)},this._main=e,this._logger=e.getLogger(),this._main.addEventListener("serverConnect",this.onServerConnect,!1),this._main.addEventListener("serverDisconnect",this.onServerDisconnect,!1)}initialize(){this._isDestroyed||null!=this._connection&&(this._connection.getConnectionState()==ConnectionState.CONNECTING||this._connection.getConnectionState()==ConnectionState.CONNECTED?this._logger.info(this,"Connection is alive, not doing anything!"):(this._logger.info(this,"Connection is dead, restarting!"),this._connection.startConnection()))}start(){this._connection=new WowzaConnection(this._main,this)}stop(){var e;null!=(e=this._connection)&&e.disconnect(!0),this._lastState=""}sendMessage(e){!this._isDestroyed&&this._connection&&this._connection.isConnectionActive()&&this._connection.sendData(e)}getConnection(){return this._connection}getCurrentStreamKey(){return this._currentStreamKey}destroy(){this._isDestroyed=!0,this._main.removeEventListener("serverConnect",this.onServerConnect),this._main.removeEventListener("serverDisconnect",this.onServerDisconnect),this._connection&&(this._connection.destroy(),this._connection=null)}}class StatsController{constructor(e){this._publishVideoWidth=0,this._publishVideoHeight=0,this._publishVideoBitrate=0,this._publishAudioBitrate=0,this._currentBitrate=0,this._currentFPS=0,this._deliveredVideoFrames=0,this._deliveredAudioFrames=0,this.onStreamStatsUpdate=e=>{this._publishVideoWidth=e.streamStatus.videoWidth,this._publishVideoHeight=e.streamStatus.videoHeight,this._currentBitrate=e.streamStatus.currentBitrate,this._publishVideoBitrate=e.streamStatus.videoPublishBitrate,this._publishAudioBitrate=e.streamStatus.audioPublishBitrate,this._currentFPS=e.streamStatus.frameRate,this._deliveredVideoFrames=e.streamStatus.videoFrameCount,this._deliveredAudioFrames=e.streamStatus.audioFrameCount},this._main=e,this._logger=e.getLogger(),this._logger.info(this,"Creating new StatsController"),this.initialize()}initialize(){this._main.addEventListener("streamStatusUpdate",this.onStreamStatsUpdate,!1)}get deliveredVideoFrames(){return this._deliveredVideoFrames}get deliveredAudioFrames(){return this._deliveredAudioFrames}get currentFPS(){return this._currentFPS}get publishVideoWidth(){return this._publishVideoWidth}get publishVideoHeight(){return this._publishVideoHeight}get currentBitrate(){return this._currentBitrate}get publishVideoBitrate(){return this._publishVideoBitrate}get publishAudioBitrate(){return this._publishAudioBitrate}}class GraphDrawer{constructor(e,t,i,s=1){if(this._currentX=0,this._isFullyDrawn=!1,this._lastTimestamp=null,this._isTimemarkLine=!1,this._borderWidth=1,i.length!==t.length+1)throw new Error(`Colors array must have exactly ${t.length+1} elements (one more than valueRanges)`);for(let e=1;e<t.length;e++)if(t[e]<=t[e-1])throw new Error("ValueRanges must be in ascending order");const n=/^#[0-9A-Fa-f]{6}$/;if(!i.every(e=>n.test(e)))throw new Error("All colors must be in valid hex format (e.g., #FF0000)");let r;if("string"==typeof e){var o=document.getElementById(e);if(!o)throw new Error(`Container element with id ${e} not found`);r=o}else r=e;o=r.getBoundingClientRect(),this._width=Math.floor(o.width),this._height=Math.floor(o.height),this._effectiveWidth=this._width-2*this._borderWidth,this._effectiveHeight=this._height-2*this._borderWidth,this._canvas=document.createElement("canvas"),r.appendChild(this._canvas),e=this._canvas.getContext("2d",{willReadFrequently:!0});if(!e)throw new Error("Failed to get canvas context");this._ctx=e,this._valueRanges=[0,...t],this._colors=i,this._lineWidth=s,this._canvas.width=this._width,this._canvas.height=this._height,this._canvas.style.width=this._width+"px",this._canvas.style.height=this._height+"px",this.clear()}drawBorder(){this._ctx.strokeStyle="#000000",this._ctx.lineWidth=this._borderWidth,this._ctx.strokeRect(this._borderWidth/2,this._borderWidth/2,this._width-this._borderWidth,this._height-this._borderWidth)}clear(){this._ctx.clearRect(0,0,this._width,this._height),this._ctx.fillStyle=this._colors[0],this._ctx.fillRect(this._borderWidth,this._borderWidth,this._effectiveWidth,this._effectiveHeight),this.drawBorder(),this._isFullyDrawn=!1,this._currentX=this._borderWidth,this._lastTimestamp=null,this._isTimemarkLine=!1}getColorIndices(t){for(let e=0;e<this._valueRanges.length-1;e++)if(t>=this._valueRanges[e]&&t<=this._valueRanges[e+1])return{lowerIndex:e,upperIndex:e+1};return{lowerIndex:this._valueRanges.length-2,upperIndex:this._valueRanges.length-1}}calculateHeightRatio(e,t,i){return(e-t)/(i-t)}shiftCanvasLeft(e){e=this._ctx.getImageData(this._borderWidth+e,this._borderWidth,this._effectiveWidth-e,this._effectiveHeight);this._ctx.fillStyle=this._colors[0],this._ctx.fillRect(this._borderWidth,this._borderWidth,this._effectiveWidth,this._effectiveHeight),this._ctx.putImageData(e,this._borderWidth,this._borderWidth),this.drawBorder()}applyOverlayEffect(e,s=.5){var t=parseInt(e.slice(1,3),16),i=parseInt(e.slice(3,5),16),e=parseInt(e.slice(5,7),16),n=e=>{var t=e/255;let i;return i=t<=.5?2*t*1:1-2*(1-t)*0,Math.round(255*i*s+e*(1-s))},t=n(t),i=n(i),n=n(e),e=e=>{e=e.toString(16);return 1===e.length?"0"+e:e};return"#"+e(t)+e(i)+e(n)}addEntry(e){e=Math.round(100*e)/100;var t=Date.now(),t=(null===this._lastTimestamp?(this._lastTimestamp=t,this._isTimemarkLine=!1):1e3<=t-this._lastTimestamp?(this._isTimemarkLine=!0,this._lastTimestamp=t):this._isTimemarkLine=!1,this._isTimemarkLine?1:this._lineWidth);!this._isFullyDrawn&&this._currentX>=this._width-this._borderWidth&&(this._isFullyDrawn=!0),this._isFullyDrawn?(this.shiftCanvasLeft(t),this.drawLine(this._width-this._borderWidth-t,e,t)):(this.drawLine(this._currentX,e,t),this._currentX+=t)}drawLine(e,t,i){var{lowerIndex:s,upperIndex:n}=this.getColorIndices(t),t=this.calculateHeightRatio(t,this._valueRanges[s],this._valueRanges[n]);let r=this._colors[s],o=this._colors[n];this._isTimemarkLine&&(r=this.applyOverlayEffect(r,.3),o=this.applyOverlayEffect(o,.3));s=Math.round(this._effectiveHeight*t),n=this._effectiveHeight-s;this._ctx.fillStyle=r,this._ctx.fillRect(e,this._height-this._borderWidth-n,i,n),this._ctx.fillStyle=o,this._ctx.fillRect(e,this._borderWidth,i,s)}clearGraph(){this._currentX=this._borderWidth,this._isFullyDrawn=!1,this._lastTimestamp=null,this._isTimemarkLine=!1,this.clear()}destroy(){this._canvas.parentNode&&this._canvas.parentNode.removeChild(this._canvas)}}class BitrateGraph{constructor(e,t){this.onStreamStatsUpdate=e=>{var t;null!=(t=this._graph)&&t.addEntry(e.streamStatus.currentBitrate)},this._main=e,this._object=t,this._main.addGraph(this)}start(){null!=this._graph&&stop();return this._graph=new GraphDrawer(this._object,[1e6,2e6,3e6,5e6,6e6,7e6],["#000000","#0a3980","#2793dd","#3bc39c","#c3df3e","#f89539","#f83f3f"],5),this._main.addEventListener("streamStatusUpdate",this.onStreamStatsUpdate),this}stop(){return this._main.removeEventListener("streamStatusUpdate",this.onStreamStatsUpdate),null!=this._graph&&this._graph.destroy(),this._graph=null,this}}class FPSGraph{constructor(e,t){this.onStreamStatsUpdate=e=>{var t;null!=(t=this._graph)&&t.addEntry(e.streamStatus.frameRate)},this._main=e,this._object=t,this._main.addGraph(this)}start(){null!=this._graph&&stop();return this._graph=new GraphDrawer(this._object,[25,26,27,28,29,30],["#000000","#0a3980","#2793dd","#3bc39c","#c3df3e","#f89539","#f83f3f"],5),this._main.addEventListener("streamStatusUpdate",this.onStreamStatsUpdate),this}stop(){return this._main.removeEventListener("streamStatusUpdate",this.onStreamStatsUpdate),null!=this._graph&&this._graph.destroy(),this._graph=null,this}}class MicrophoneGraph{constructor(e,t){this.onStreamStatsUpdate=e=>{var t;null!=(t=this._graph)&&t.addEntry(500*e.high)},this._main=e,this._object=t,this._main.addGraph(this)}start(){null!=this._graph&&stop();return this._graph=new GraphDrawer(this._object,[0,20,40,60,80,100],["#000000","#0a3980","#2793dd","#3bc39c","#c3df3e","#f89539","#f83f3f"],2),this._main.addEventListener("soundMeter",this.onStreamStatsUpdate),this}stop(){return this._main.removeEventListener("soundMeter",this.onStreamStatsUpdate),null!=this._graph&&this._graph.destroy(),this._graph=null,this}}class StormStreamer extends EventDispatcher{constructor(e,t=!1){super(),this.DEV_MODE=!0,this.STREAMER_VERSION="1.0.5",this.COMPILE_DATE="2/20/2026, 10:02:20 AM",this.STREAMER_BRANCH="Experimental",this.STREAMER_PROTOCOL_VERSION=1,this._initialized=!1,this._isDestroyed=!1,"undefined"!=typeof window&&window.document&&window.document.createElement?(!this.DEV_MODE||"StormStreamerArray"in window||(window.StormStreamerArray=[]),window.StormStreamerArray.push(this),this._streamerID=StormStreamer.NEXT_STREAMER_ID++,null!=e&&(this.setStreamConfig(e),t)&&this.initialize()):console.error('StormStreamer Creation Error - No "window" element in the provided context!')}initialize(){if(!this._isRemoved&&!this._isDestroyed){if(null==this._configManager)throw Error("Stream Config was not provided for this streamer!");this._storageManager=new StorageManager(this),this._stageController=new StageController(this),this._networkController=new NetworkController(this),this._streamerController=new StreamerController(this),this._statsController=new StatsController(this),this._graphs=[],this._initialized=!0,this.dispatchEvent("streamerReady",{ref:this})}}setStreamConfig(e){this._isRemoved||this._isDestroyed||(e=JSON.parse(JSON.stringify(e)),null==this._configManager?(this._configManager=new ConfigManager(e),this._logger=new Logger(this._configManager.getSettingsData().getDebugData(),this),this._logger.info(this,"Storm Streamer :: Storm Streaming Suite"),this._logger.info(this,"StreamerID: "+this._streamerID),this._logger.info(this,"Version: "+this.STREAMER_VERSION+" | Compile Date: "+this.COMPILE_DATE+" | Branch: "+this.STREAMER_BRANCH),this._logger.info(this,"UserCapabilities :: Browser: "+UserCapabilities.getBrowserName()+" "+UserCapabilities.getBrowserVersion()),this._logger.info(this,"UserCapabilities :: Operating System: "+UserCapabilities.getOS()+" "+UserCapabilities.getOSVersion()),this._logger.info(this,"UserCapabilities :: isMobile: "+UserCapabilities.isMobile()),this._logger.info(this,"UserCapabilities :: hasMSESupport: "+UserCapabilities.hasMSESupport()),this._logger.info(this,"UserCapabilities :: hasWebSocketSupport: "+UserCapabilities.hasWebSocketsSupport()),this._logger.info(this,"UserCapabilities :: hasWebRTCSupport: "+UserCapabilities.hasWebRTCSupport()),this._configManager.print(this._logger)):(this._logger.info(this,"StreamConfig has been overwritten, dispatching streamConfigChanged!"),this._configManager=new ConfigManager(e),this._configManager.print(this._logger),this.dispatchEvent("streamConfigChange",{ref:this,newConfig:this._configManager})))}isConnected(){var e;return null!=(e=null==(e=null==(e=this._networkController)?void 0:e.getConnection())?void 0:e.isConnectionActive())&&e}mute(){var e;null!=(null==(e=this._stageController)?void 0:e.getScreenElement())?this._stageController.getScreenElement().setMuted(!0):this._configManager.getSettingsData().getAudioData().muted=!0}unmute(){var e;null!=(null==(e=this._stageController)?void 0:e.getScreenElement())?this._stageController.getScreenElement().setMuted(!1):this._configManager.getSettingsData().getAudioData().muted=!1}isMute(){var e;return null!=(e=null!=(e=null==(e=null==(e=this._stageController)?void 0:e.getScreenElement())?void 0:e.getIfMuted())?e:this._configManager.getSettingsData().getAudioData().muted)&&e}toggleMute(){var e=this.isMute();return e?this.unmute():this.mute(),!e}setVolume(e){var t;void 0===(null==(t=null==(t=this._stageController)?void 0:t.getScreenElement())?void 0:t.setVolume(e))&&(this._configManager.getSettingsData().getAudioData().startVolume=e)}getVolume(){var e;return null!=(e=null==(e=null==(e=this._stageController)?void 0:e.getScreenElement())?void 0:e.getVolume())?e:this._configManager.getSettingsData().getAudioData().startVolume}getCameraList(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getCameraList())?e:[]}getMicrophoneList(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getMicrophoneList())?e:[]}setCamera(e){var t;null!=(t=this._streamerController)&&t.selectCamera(e)}setMicrophone(e){var t;null!=(t=this._streamerController)&&t.selectMicrophone(e)}getCurrentCamera(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getCurrentCamera())?e:null}getCurrentMicrophone(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getCurrentMicrophone())?e:null}muteMicrophone(e){var t;null!=(t=this._streamerController)&&t.muteMicrophone(e)}isMicrophoneMuted(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.isMicrophoneMuted())&&e}getPublishState(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getPublishState())?e:exports.PublishState.NOT_INITIALIZED}getPublishTime(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getPublishTime())?e:0}publish(e){var t;return null!=(t=null==(t=this._streamerController)?void 0:t.publish(e))&&t}unpublish(){var e;null!=(e=this._streamerController)&&e.unpublish()}getInputDevicesState(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getInputDeviceState())?e:exports.InputDevicesState.NOT_INITIALIZED}getCameraState(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getCameraState())?e:exports.DeviceState.NOT_INITIALIZED}getMicrophoneState(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.getMicrophoneState())?e:exports.DeviceState.NOT_INITIALIZED}clearSavedDevices(){var e;null!=(e=this._streamerController)&&e.clearSavedDevices()}messSavedDevices(){var e;null!=(e=this._streamerController)&&e.messSavedDevices()}isStreamReady(){var e;return null!=(e=null==(e=this._streamerController)?void 0:e.isStreamReady())&&e}attachToContainer(e){var t;return!!this._initialized&&null!=(t=null==(t=this._stageController)?void 0:t.attachToParent(e))&&t}detachFromContainer(){var e;return!!this._initialized&&null!=(e=null==(e=this._stageController)?void 0:e.detachFromParent())&&e}getContainer(){var e;return null!=(e=null==(e=this._stageController)?void 0:e.getParentElement())?e:null}setSize(e,t){this._initialized?this._stageController.setSize(e,t):(e=NumberUtilities.parseValue(e),t=NumberUtilities.parseValue(t),this._configManager.getSettingsData().getVideoData().videoWidthValue=e.value,this._configManager.getSettingsData().getVideoData().videoWidthInPixels=e.isPixels,this._configManager.getSettingsData().getVideoData().videoHeightValue=t.value,this._configManager.getSettingsData().getVideoData().videoHeightInPixels=t.isPixels)}setWidth(e){this._initialized?this._stageController.setWidth(e):(e=NumberUtilities.parseValue(e),this._configManager.getSettingsData().getVideoData().videoWidthValue=e.value,this._configManager.getSettingsData().getVideoData().videoWidthInPixels=e.isPixels)}setHeight(e){this._initialized?this._stageController.setHeight(e):(e=NumberUtilities.parseValue(e),this._configManager.getSettingsData().getVideoData().videoHeightValue=e.value,this._configManager.getSettingsData().getVideoData().videoHeightInPixels=e.isPixels)}getWidth(){return this._initialized?this._stageController.getContainerWidth():this._configManager.getSettingsData().getVideoData().videoWidthInPixels?this._configManager.getSettingsData().getVideoData().videoWidthValue:0}getHeight(){return this._initialized?this._stageController.getContainerHeight():this._configManager.getSettingsData().getVideoData().videoHeightInPixels?this._configManager.getSettingsData().getVideoData().videoHeightValue:0}setScalingMode(e){this._stageController?this._stageController.setScalingMode(e):this._configManager.getSettingsData().getVideoData().scalingMode=e}getScalingMode(){return this._stageController?this._stageController.getScalingMode():this._configManager.getSettingsData().getVideoData().scalingMode}updateToSize(){this._initialized&&this._stageController.handleResize()}makeScreenshot(){let i=document.createElement("canvas"),s=i.getContext("2d");return new Promise(t=>{var e;null!=this._stageController&&(i.width=this._stageController.getScreenElement().getVideoElement().videoWidth,i.height=this._stageController.getScreenElement().getVideoElement().videoHeight,e=this._stageController.getScreenElement().getVideoElement(),s)?(s.drawImage(e,0,0,i.width,i.height),i.toBlob(e=>t(e),"image/png")):t(null)})}createFPSGraph(e){return new FPSGraph(this,e)}createBitrateGraph(e){return new BitrateGraph(this,e)}createMicrophoneGraph(e){return new MicrophoneGraph(this,e)}addGraph(e){null!=this._graphs&&this._graphs.push(e)}stopAllGraphs(){if(null!=this._graphs&&0<this._graphs.length)for(let e=0;e<this._graphs.length;e++)this._graphs[e].stop()}enterFullScreen(){this._initialized&&this._stageController&&this._stageController.enterFullScreen()}exitFullScreen(){this._initialized&&this._stageController&&this._stageController.exitFullScreen()}isFullScreenMode(){return!(!this._initialized||!this._stageController)&&this._stageController.isFullScreenMode()}getStreamKey(){var e;return null!=(e=null==(e=null==(e=this.getConfigManager())?void 0:e.getStreamData())?void 0:e.streamKey)?e:null}getStatsController(){return this._statsController}getStreamerID(){return this._streamerID}getLogger(){return this._logger}getConfigManager(){return this._configManager}getNetworkController(){return this._networkController}getStreamerController(){return this._streamerController}getStageController(){return this._stageController}getStorageManager(){return this._storageManager}getVideoElement(){var e;return null!=(e=null==(e=null==(e=this._stageController)?void 0:e.getScreenElement())?void 0:e.getVideoElement())?e:null}isInitialized(){return this._initialized}isDestroyed(){return this._isDestroyed}getVersion(){return this.STREAMER_VERSION}getBranch(){return this.STREAMER_BRANCH}dispatchEvent(e,t){super.dispatchEvent(e,t)}start(){var e;return __awaiter(this,void 0,void 0,function*(){return!this._initialized||this._isDestroyed||null==(e=this._streamerController)?void 0:e.start()})}stop(){var e;null!=(e=this._streamerController)&&e.stop()}debugMediaState(){var e;null!=(e=this._streamerController)&&e.debugMediaState()}destroy(){var e;if(this._isDestroyed)null!=(e=this._logger)&&e.warning(this,"🔴 [DESTROY] Already destroyed, skipping");else{if(null!=(e=this._logger)&&e.warning(this,"🔴 [DESTROY] Starting streamer instance destruction (sync)..."),this._isDestroyed=!0,this._initialized=!1,this._isRemoved=!0,this.DEV_MODE&&"StormStreamerArray"in window&&(window.StormStreamerArray[this._streamerID]=null),this.stopAllGraphs(),this._graphs=[],this._networkController&&(null!=(e=this._logger)&&e.info(this,"🔴 [DESTROY] Destroying NetworkController..."),this._networkController.destroy(),this._networkController=null),this._streamerController&&(null!=(e=this._logger)&&e.info(this,"🔴 [DESTROY] Destroying StreamerController..."),this._streamerController.destroy(),this._streamerController=null),this._stageController){null!=(e=this._logger)&&e.info(this,"🔴 [DESTROY] Destroying StageController...");try{this._stageController.destroy()}catch(e){}this._stageController=null}this._storageManager=null,this._statsController=null,this.removeAllEventListeners(),null!=(e=this._logger)&&e.success(this,"🔴 [DESTROY] Streamer instance destroyed successfully (sync)")}}}function create(e){return new StormStreamer(e)}StormStreamer.NEXT_STREAMER_ID=0,exports.StormStreamer=StormStreamer,exports.create=create;