@stormstreaming/stormstreamer 1.0.4 → 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,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.0.5
4
+
5
+ Bugfix for destroying Network Controller,
6
+
3
7
  ## 1.0.4
4
8
 
5
9
  Bugfix for initialize() & start() methods race condition,
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.4
8
- * Version: 2/19/2026, 11:12:13 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
@@ -4597,10 +4597,10 @@
4597
4597
  if (this._publishState == exports.PublishState.CONNECTED && update.publishState == exports.PublishState.PUBLISHED) this.setPublishState(exports.PublishState.PUBLISHED);
4598
4598
  };
4599
4599
  this.onDescriptionSuccess = description => {
4600
- var _a, _b;
4600
+ var _a, _b, _c;
4601
4601
  if (this._isDestroyed) return;
4602
4602
  const streamInfo = {
4603
- 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(),
4604
4604
  streamName: this._fullStreamName,
4605
4605
  sessionId: "[empty]"
4606
4606
  };
@@ -6324,6 +6324,11 @@
6324
6324
  * @param main reference to the main class
6325
6325
  */
6326
6326
  constructor(main) {
6327
+ /**
6328
+ * Object containing WebSocket Connection (only one is needed)
6329
+ * @private
6330
+ */
6331
+ this._connection = null;
6327
6332
  /**
6328
6333
  * Current streamKey
6329
6334
  * @private
@@ -6334,6 +6339,7 @@
6334
6339
  * @private
6335
6340
  */
6336
6341
  this._lastState = "";
6342
+ this._isDestroyed = false;
6337
6343
  //------------------------------------------------------------------------//
6338
6344
  // CONNECTION-RELATED METHODS
6339
6345
  //------------------------------------------------------------------------//
@@ -6356,6 +6362,7 @@
6356
6362
  // MAIN METHODS
6357
6363
  //------------------------------------------------------------------------//
6358
6364
  initialize() {
6365
+ if (this._isDestroyed) return;
6359
6366
  if (this._connection != null) {
6360
6367
  if (this._connection.getConnectionState() == ConnectionState.CONNECTING || this._connection.getConnectionState() == ConnectionState.CONNECTED) {
6361
6368
  this._logger.info(this, "Connection is alive, not doing anything!");
@@ -6369,10 +6376,12 @@
6369
6376
  this._connection = new WowzaConnection(this._main, this);
6370
6377
  }
6371
6378
  stop() {
6372
- this._connection.disconnect(true);
6379
+ var _a;
6380
+ (_a = this._connection) === null || _a === void 0 ? void 0 : _a.disconnect(true);
6373
6381
  this._lastState = "";
6374
6382
  }
6375
6383
  sendMessage(message) {
6384
+ if (this._isDestroyed || !this._connection) return;
6376
6385
  if (this._connection.isConnectionActive()) {
6377
6386
  this._connection.sendData(message);
6378
6387
  }
@@ -6392,6 +6401,16 @@
6392
6401
  getCurrentStreamKey() {
6393
6402
  return this._currentStreamKey;
6394
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
+ }
6395
6414
  }
6396
6415
 
6397
6416
  class StatsController {
@@ -6735,8 +6754,8 @@
6735
6754
  constructor(streamConfig, autoInitialize = false) {
6736
6755
  super();
6737
6756
  this.DEV_MODE = true;
6738
- this.STREAMER_VERSION = "1.0.4";
6739
- this.COMPILE_DATE = "2/19/2026, 11:12:11 AM";
6757
+ this.STREAMER_VERSION = "1.0.5";
6758
+ this.COMPILE_DATE = "2/20/2026, 10:02:20 AM";
6740
6759
  this.STREAMER_BRANCH = "Experimental";
6741
6760
  this.STREAMER_PROTOCOL_VERSION = 1;
6742
6761
  this._initialized = false;
@@ -6796,8 +6815,8 @@
6796
6815
  }
6797
6816
  // PLAYBACK / STREAMING
6798
6817
  isConnected() {
6799
- var _a, _b;
6800
- 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;
6801
6820
  }
6802
6821
  mute() {
6803
6822
  var _a;
@@ -7083,7 +7102,7 @@
7083
7102
  * All pending async operations will detect the destroyed state and abort.
7084
7103
  */
7085
7104
  destroy() {
7086
- var _a, _b, _c, _d, _e, _f, _g;
7105
+ var _a, _b, _c, _d, _e, _f;
7087
7106
  // Prevent double destroy
7088
7107
  if (this._isDestroyed) {
7089
7108
  (_a = this._logger) === null || _a === void 0 ? void 0 : _a.warning(this, "🔴 [DESTROY] Already destroyed, skipping");
@@ -7101,23 +7120,20 @@
7101
7120
  // Stop all graphs
7102
7121
  this.stopAllGraphs();
7103
7122
  this._graphs = [];
7104
- // Destroy network controller
7105
7123
  if (this._networkController) {
7106
7124
  (_c = this._logger) === null || _c === void 0 ? void 0 : _c.info(this, "🔴 [DESTROY] Destroying NetworkController...");
7107
- try {
7108
- (_d = this._networkController.getConnection()) === null || _d === void 0 ? void 0 : _d.destroy();
7109
- } catch (e) {/* ignore */}
7125
+ this._networkController.destroy(); // zamiast ręcznego getConnection()?.destroy()
7110
7126
  this._networkController = null;
7111
7127
  }
7112
7128
  // Destroy streamer controller (this is also sync now)
7113
7129
  if (this._streamerController) {
7114
- (_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...");
7115
7131
  this._streamerController.destroy();
7116
7132
  this._streamerController = null;
7117
7133
  }
7118
7134
  // Destroy stage controller
7119
7135
  if (this._stageController) {
7120
- (_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...");
7121
7137
  try {
7122
7138
  this._stageController.destroy();
7123
7139
  } catch (e) {/* ignore */}
@@ -7128,7 +7144,7 @@
7128
7144
  this._statsController = null;
7129
7145
  // Remove all event listeners
7130
7146
  this.removeAllEventListeners();
7131
- (_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)");
7132
7148
  }
7133
7149
  }
7134
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.4
8
- * Version: 2/19/2026, 11:12:13 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._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=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*(){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._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.4",this.COMPILE_DATE="2/19/2026, 11:12:11 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;