@stormstreaming/stormstreamer 0.9.0-beta.11 → 0.9.0-beta.13

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/dist/amd/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  * contact@stormstreaming.com
5
5
  * https://stormstreaming.com
6
6
  *
7
- * Version: 0.9.0-beta.11
8
- * Version: 1/14/2025, 2:09:31 PM
7
+ * Version: 0.9.0-beta.13
8
+ * Version: 1/14/2025, 3:03:41 PM
9
9
  *
10
10
  * LEGAL NOTICE:
11
11
  * This software is subject to the terms and conditions defined in
@@ -2763,6 +2763,47 @@
2763
2763
  }
2764
2764
  }
2765
2765
 
2766
+ class StreamMetaData {
2767
+ constructor() {
2768
+ this._streamWidth = 0;
2769
+ this._streamHeight = 0;
2770
+ this._aspectRatio = "";
2771
+ this._hasVideoTrack = false;
2772
+ this._hasAudioTrack = false;
2773
+ }
2774
+ StreamMetaData() {}
2775
+ getStreamWidth() {
2776
+ return this._streamWidth;
2777
+ }
2778
+ getStreamHeight() {
2779
+ return this._streamHeight;
2780
+ }
2781
+ setStreamWidth(newValue) {
2782
+ this._streamWidth = newValue;
2783
+ }
2784
+ setStreamHeight(newValue) {
2785
+ this._streamHeight = newValue;
2786
+ }
2787
+ getAspectRatio() {
2788
+ return this._aspectRatio;
2789
+ }
2790
+ setAspectRatio(newValue) {
2791
+ this._aspectRatio = newValue;
2792
+ }
2793
+ hasVideoTrack() {
2794
+ return this._hasVideoTrack;
2795
+ }
2796
+ setVideoTractPresence(hasVideoTrack) {
2797
+ this._hasVideoTrack = hasVideoTrack;
2798
+ }
2799
+ hasAudioTrack() {
2800
+ return this._hasAudioTrack;
2801
+ }
2802
+ setAudioTractPresence(hasVideoTrack) {
2803
+ this._hasAudioTrack = hasVideoTrack;
2804
+ }
2805
+ }
2806
+
2766
2807
  class PlaybackController {
2767
2808
  constructor(main) {
2768
2809
  var _a;
@@ -3037,6 +3078,8 @@
3037
3078
  onCameraStreamSuccess(stream) {
3038
3079
  this._logger.success(this, "Camera stream successfully retrieved");
3039
3080
  const videoTrack = stream.getVideoTracks()[0];
3081
+ const audioTrack = stream.getAudioTracks()[0];
3082
+ const streamData = new StreamMetaData();
3040
3083
  if (videoTrack) {
3041
3084
  const settings = videoTrack.getSettings();
3042
3085
  let width = settings.width;
@@ -3047,14 +3090,30 @@
3047
3090
  [width, height] = [height, width];
3048
3091
  }
3049
3092
  }
3050
- this._logger.info(this, `Actual stream dimensions (corrected): ${width}x${height}`);
3051
- this._main.dispatchEvent("streamDimensionsUpdate", {
3052
- ref: this._main,
3053
- width: width,
3054
- height: height,
3055
- aspectRatio: width && height ? width / height : null
3056
- });
3093
+ streamData.setStreamWidth(width);
3094
+ streamData.setStreamHeight(height);
3095
+ streamData.setVideoTractPresence(true);
3096
+ const gcd = (a, b) => b ? gcd(b, a % b) : a;
3097
+ const divisor = gcd(width, height);
3098
+ const widthRatio = width / divisor;
3099
+ const heightRatio = height / divisor;
3100
+ const ratio = width / height;
3101
+ let aspectRatioString = `${widthRatio}:${heightRatio}`;
3102
+ if (Math.abs(ratio - 16 / 9) < 0.1) {
3103
+ aspectRatioString = width > height ? "16:9" : "9:16";
3104
+ } else if (Math.abs(ratio - 4 / 3) < 0.1) {
3105
+ aspectRatioString = width > height ? "4:3" : "3:4";
3106
+ }
3107
+ streamData.setAspectRatio(aspectRatioString);
3108
+ } else {
3109
+ streamData.setVideoTractPresence(false);
3057
3110
  }
3111
+ streamData.setAudioTractPresence(!!audioTrack);
3112
+ this._logger.info(this, `Stream dimensions: ${streamData.getStreamWidth()}x${streamData.getStreamHeight()}, ` + `Aspect ratio: ${streamData.getAspectRatio()}, ` + `Video: ${streamData.hasVideoTrack()}, Audio: ${streamData.hasAudioTrack()}`);
3113
+ this._main.dispatchEvent("streamMetadataUpdate", {
3114
+ ref: this._main,
3115
+ metadata: streamData
3116
+ });
3058
3117
  this._stream = stream;
3059
3118
  if (this._pendingMicrophoneState !== null) {
3060
3119
  this.applyMicrophoneState(this._pendingMicrophoneState);
@@ -3997,8 +4056,8 @@
3997
4056
  constructor(streamConfig, autoInitialize = false) {
3998
4057
  super();
3999
4058
  this.DEV_MODE = true;
4000
- this.STREAMER_VERSION = "0.9.0-beta.11";
4001
- this.COMPILE_DATE = "1/14/2025, 2:09:29 PM";
4059
+ this.STREAMER_VERSION = "0.9.0-beta.13";
4060
+ this.COMPILE_DATE = "1/14/2025, 3:03:39 PM";
4002
4061
  this.STREAMER_BRANCH = "Experimental";
4003
4062
  this.STREAMER_PROTOCOL_VERSION = 1;
4004
4063
  this._initialized = false;
package/dist/cjs/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  * contact@stormstreaming.com
5
5
  * https://stormstreaming.com
6
6
  *
7
- * Version: 0.9.0-beta.11
8
- * Version: 1/14/2025, 2:09:31 PM
7
+ * Version: 0.9.0-beta.13
8
+ * Version: 1/14/2025, 3:03:41 PM
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}n+="\r\n"}return n}mungeSDPPlay(e){let n="";for(const r of e.split(/\r\n/))if(0!==r.length){if(r.includes("profile-level-id")){var s=r.substr(r.indexOf("profile-level-id")+17,6);let e=Number("0x"+s.substr(0,2)),t=Number("0x"+s.substr(2,2)),i=Number("0x"+s.substr(4,2));66<e&&(e=66,t=224,i=31),0===t&&(t=224);var o=("00"+e.toString(16)).slice(-2).toLowerCase()+("00"+t.toString(16)).slice(-2).toLowerCase()+("00"+i.toString(16)).slice(-2).toLowerCase();n+=r.replace(s,o)}else n+=r;n+="\r\n"}return n}}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}getLabel(){return this._label}getID(){return this._id}getGroupID(){return this._groupID}getIfSelected(){return this._isSelected}setSelected(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].getGroupID()&&this._internalList[e].getGroupID()==t.getGroupID()&&(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.PUBLISHED="PUBLISHED",e.PUBLISHED2="PUBLISHED2",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._instant=0,this._slow=0,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._analyser.smoothingTimeConstant=.3,this._microphone.connect(this._analyser),this.startMonitoring(),console.log("SoundMeter: Successfully attached to new audio stream")}catch(e){console.error("SoundMeter: Error during attach:",e),this.detach()}}else console.warn("SoundMeter: Attempted to attach stream without audio tracks")}detach(){var e,t;if(this._isMonitoring=!1,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("closed"!==(null==(e=this._audioContext)?void 0:e.state))try{null!=(t=this._audioContext)&&t.close()}catch(e){console.warn("SoundMeter: Error closing audio context:",e)}this._audioContext=null,this.clear(),console.log("SoundMeter: Successfully detached")}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){var e=Date.now();try{this._analyser.getFloatTimeDomainData(s);let t=0,i=0;for(let e=0;e<s.length;++e){var n=s[e];t+=n*n,.99<Math.abs(n)&&(i+=1)}this._instant=Math.sqrt(t/s.length),this._slow=.05*this._instant+.95*this._slow,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),void(this._isMonitoring=!1)}requestAnimationFrame(t)}};requestAnimationFrame(t)}}}exports.StreamerState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.INITIALIZED="INITIALIZED",e.READY="READY",e.UPDATING="UPDATING",e.INVALID="INVALID",e.UNKNOWN="UNKNOWN"}(exports.StreamerState||(exports.StreamerState={})),exports.DeviceState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.ENABLED="ENABLED",e.ACCESS_DENIED="ACCESS_DENIED",e.NOT_FOUND="NOT_FOUND"}(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 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._isConnected=!0}onSocketError(e){this._isConnected=!1,this._disconnectedByUser||this._logger.error(this,"Connection with the server failed")}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")}onSocketMessage(e){console.log(1),"string"==typeof e.data&&console.log(2)}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 PlaybackController{constructor(e){var t;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._inputDeviceState=exports.StreamerState.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.handleOrientationChange=()=>__awaiter(this,void 0,void 0,function*(){yield new Promise(e=>setTimeout(e,500));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;var e=null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey,t=this._publishState===exports.PublishState.PUBLISHED;this.closeWebRTCConnection(),this._stream&&(this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null);try{yield this.startCamera(),t&&e&&this.publish(e)}catch(e){this._logger.error(this,"Error restarting stream after orientation change: "+JSON.stringify(e)),this.setInputDeviceState(exports.StreamerState.INVALID)}}}),this.onServerDisconnect=()=>{},this.onStreamKeyTaken=()=>{null!=this._restartTimer&&(clearInterval(this._restartTimer),this._restartTimerCount=0),this._logger.info(this,"WebRTCStreamer :: Starting StreamKeyTaken Interval"),this._restartTimer=setInterval(()=>{var e;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.publish(e)),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._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)try{var e=yield this._peerConnection.createOffer();yield this.onDescriptionSuccess(e)}catch(e){this.onDescriptionError(e),console.error("Error creating offer:",e)}})},this.onDescriptionSuccess=t=>{var e;const i={applicationName:null==(e=null==(e=this._main.getNetworkController())?void 0:e.getConnection().getCurrentServer())?void 0:e.getApplication(),streamName:null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey,sessionId:"[empty]"};t.sdp=this._mungeSDP.mungeSDPPublish(t.sdp,{audioBitrate:"64",videoBitrate:"1500",videoFrameRate:30,videoCodec:"42e01f",audioCodec:"opus"}),this._peerConnection&&this._peerConnection.setLocalDescription(t).then(()=>{var e;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.initializeDevices()}initialize(){var e;this._main.addEventListener("serverConnect",this.onServerConnect,!1),this._main.addEventListener("serverDisconnect",this.onServerDisconnect,!1),this._main.addEventListener("streamKeyInUse",this.onStreamKeyTaken,!1),document.addEventListener("visibilitychange",this.visibilityChange),window.addEventListener("blur",this.onWindowBlur),window.addEventListener("focus",this.onWindowFocus),(this._selectedCamera||this._selectedMicrophone)&&this.startCamera().then(()=>{}),null!=(e=this._main.getConfigManager())&&e.getSettingsData().autoConnect?(this._logger.info(this,"Initializing NetworkController (autoConnect is true)"),null!=(e=this._main.getNetworkController())&&e.initialize()):this._logger.warning(this,"Warning - autoConnect is set to false, switching to standby mode!"),this.setupOrientationListener(),this.setupPermissionListeners()}initializeDevices(){return __awaiter(this,void 0,void 0,function*(){this._main.addEventListener("deviceStateChange",e=>{var t=this._main.getConfigManager().getStreamData().streamKey;e.state==exports.StreamerState.READY&&null!=t&&this.publish(t)},!1);try{(yield navigator.mediaDevices.getUserMedia({video:!0,audio:!0})).getTracks().forEach(e=>e.stop()),yield this.grabDevices(),this.setupPermissionListeners(),this.initialize()}catch(e){this._logger.error(this,"Error initializing devices: "+JSON.stringify(e)),yield this.grabDevices(),this.setupPermissionListeners(),this.initialize()}})}requestPermissions(){return __awaiter(this,void 0,void 0,function*(){try{return(yield navigator.mediaDevices.getUserMedia({video:!0,audio:!0})).getTracks().forEach(e=>e.stop()),yield this.grabDevices(),!0}catch(e){return this._logger.error(this,"Error requesting permissions: "+JSON.stringify(e)),!1}})}setupPermissionListeners(){navigator.permissions.query({name:"camera"}).then(e=>{e.onchange=()=>{this._permissionChecked=!1,this.handlePermissionChange("camera",e.state)}}),navigator.permissions.query({name:"microphone"}).then(e=>{e.onchange=()=>{this._permissionChecked=!1,this.handlePermissionChange("microphone",e.state)}})}handlePermissionChange(e,t){return __awaiter(this,void 0,void 0,function*(){"denied"===t&&(this.setInputDeviceState(exports.StreamerState.INVALID),this._publishState==exports.PublishState.PUBLISHED)&&this.closeStream(),yield this.grabDevices(),"granted"===t&&(yield this.startCamera())})}onCameraStreamSuccess(e){this._logger.success(this,"Camera stream successfully retrieved");var i=e.getVideoTracks()[0];if(i){i=i.getSettings();let e=i.width,t=i.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]),this._logger.info(this,`Actual stream dimensions (corrected): ${e}x`+t),this._main.dispatchEvent("streamDimensionsUpdate",{ref:this._main,width:e,height:t,aspectRatio:e&&t?e/t:null})}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();i=this._main.getStageController().getScreenElement().getVideoElement();i.srcObject=e,i.autoplay=!0,i.playsInline=!0,i.disableRemotePlayback=!0,i.controls=!1,i.muted=!0,this.setPublishState(exports.PublishState.INITIALIZED)}initializeWebRTC(){var e;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._logger.warning(this,"Publishing: "+e),this._main.getConfigManager().getStreamData().streamKey==e&&this._publishState==exports.PublishState.PUBLISHED?(this._logger.warning(this,"Already published!"),!1):(this._main.getConfigManager().getStreamData().streamKey=e,console.log(this.isStreamReady(!0,!0)),this.isStreamReady(!0,!0)?(this._logger.info(this,"Publish: "+e),this.createStatusConnection(),this.closeWebRTCConnection(),this._main.dispatchEvent("publish",{ref:this._main,streamKey:e}),this.initializeWebRTC(),!0):(this._logger.warning(this,"Cannot publish - stream not ready (missing video or audio track)"),!1))}unpublish(){clearTimeout(this._publishTimer),this._main.getConfigManager().getStreamData().streamKey=null,this._main.dispatchEvent("unpublish",{ref:this._main}),this.closeStream()}setupOrientationListener(){window.screen&&window.screen.orientation?window.screen.orientation.addEventListener("change",this.handleOrientationChange):window.addEventListener("orientationchange",this.handleOrientationChange)}onUserMediaError(e){return __awaiter(this,void 0,void 0,function*(){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}};try{var e=yield navigator.mediaDevices.enumerateDevices(),i=(t.camera.available=e.some(e=>"videoinput"===e.kind),t.microphone.available=e.some(e=>"audioinput"===e.kind),e.some(e=>""!==e.label));if(i)t.camera.allowed=e.some(e=>"videoinput"===e.kind&&""!==e.label),t.microphone.allowed=e.some(e=>"audioinput"===e.kind&&""!==e.label);else try{var n=yield navigator.mediaDevices.getUserMedia({video:t.camera.available,audio:t.microphone.available});t.camera.allowed=0<n.getVideoTracks().length,t.microphone.allowed=0<n.getAudioTracks().length,n.getTracks().forEach(e=>e.stop()),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),t.camera.available=!1,t.microphone.available=!1,t.camera.allowed=!1,t.microphone.allowed=!1}return t})}onSocketMessage(e){var t=JSON.parse(e);switch(Number(t.status)){case 200:this._logger.info(this,"SDP Exchange Successful");var i=t.sdp,n=(void 0!==i&&this._peerConnection.setRemoteDescription(new RTCSessionDescription(i),()=>{},()=>{}),t.iceCandidates);if(void 0!==n)for(var s in n)this._peerConnection&&this._peerConnection.addIceCandidate(new RTCIceCandidate(n[s]));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){var t;if(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.PUBLISHED),null!=this._statusConnection&&null!=(t=null==(t=this._main.getConfigManager())?void 0:t.getStreamData().streamKey)&&this._statusConnection.sendData('{"packetID":"STREAM_STATUS", "streamKey": "'+t+'"}'),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*(){try{var e,t,i=yield this.checkIndividualDeviceAccess(),n=(this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._permissionChecked||(i.camera.allowed?i.camera.available||(this._main.dispatchEvent("noCameraFound",{ref:this._main}),this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.StreamerState.INVALID)):(this._main.dispatchEvent("cameraAccessDenied",{ref:this._main}),this.setCameraState(exports.DeviceState.ACCESS_DENIED),this.setInputDeviceState(exports.StreamerState.INVALID)),i.microphone.allowed?i.microphone.available||(this._main.dispatchEvent("noMicrophoneFound",{ref:this._main}),this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.StreamerState.INVALID)):(this._main.dispatchEvent("microphoneAccessDenied",{ref:this._main}),this.setMicrophoneState(exports.DeviceState.ACCESS_DENIED),this.setInputDeviceState(exports.StreamerState.INVALID))),yield navigator.mediaDevices.enumerateDevices());for(const s of n)s.deviceId&&s.label&&("videoinput"===s.kind&&i.camera.allowed?(e=new InputDevice(s,this._cameraList.getSize()),this._cameraList.push(e)):"audioinput"===s.kind&&i.microphone.allowed&&(t=new InputDevice(s,this._microphoneList.getSize()),this._microphoneList.push(t)));try{i.camera.allowed&&(this._selectedCamera=this.pickCamera()),i.microphone.allowed&&(this._selectedMicrophone=this.pickMicrophone())}catch(e){this.setInputDeviceState(exports.StreamerState.INVALID),this._logger.error(this,"Errror on grab devices: "+JSON.stringify(e))}this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._permissionChecked=!0}catch(e){console.error("Error in grabDevices:",e),this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._main.dispatchEvent("inputDeviceError",{ref:this._main})}})}selectCamera(t){var e,i;this._selectedCamera=null,this.setInputDeviceState(exports.StreamerState.UPDATING),this.setCameraState(exports.DeviceState.NOT_INITIALIZED);const n=null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey,s=this._publishState===exports.PublishState.PUBLISHED;for(let e=0;e<this._cameraList.getSize();e++)if(this._cameraList.get(e).getID()==t){this._selectedCamera=this._cameraList.get(e),null!=(i=this._main.getStorageManager())&&i.saveField("cameraID",this._selectedCamera.getID());break}this.stopCameraStream(),null!=this._selectedCamera?(this._constraints.video.deviceId=this._selectedCamera.getID(),this.startCamera().then(()=>{this.setCameraState(exports.DeviceState.ENABLED),this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED?this.setInputDeviceState(exports.StreamerState.READY):this.setInputDeviceState(exports.StreamerState.INVALID),s&&n&&this.publish(n)})):this.setInputDeviceState(exports.StreamerState.INVALID)}selectMicrophone(i){var n,s;return __awaiter(this,void 0,void 0,function*(){this._selectedMicrophone=null,this.setInputDeviceState(exports.StreamerState.UPDATING),this.setMicrophoneState(exports.DeviceState.NOT_INITIALIZED),this._logger.info(this,"Selecting microphone: "+i);var e=null==(n=this._main.getConfigManager())?void 0:n.getStreamData().streamKey,t=this._publishState===exports.PublishState.PUBLISHED;for(let e=0;e<this._microphoneList.getSize();e++)if(this._microphoneList.get(e).getID()==i){this._selectedMicrophone=this._microphoneList.get(e),null!=(s=this._main.getStorageManager())&&s.saveField("microphoneID",this._selectedMicrophone.getID());break}this._soundMeter.detach(),this.closeWebRTCConnection(),this._stream&&(this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null);try{yield this.startCamera(),this.setMicrophoneState(exports.DeviceState.ENABLED),this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED?this.setInputDeviceState(exports.StreamerState.READY):this.setInputDeviceState(exports.StreamerState.INVALID),t&&e&&this.publish(e)}catch(e){console.error("Error changing microphone:",e),this._main.dispatchEvent("inputDeviceError",{ref:this._main}),this.setInputDeviceState(exports.StreamerState.INVALID)}})}startCamera(){return __awaiter(this,void 0,void 0,function*(){this._stream&&(this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null);try{var t={video:!!this._selectedCamera&&Object.assign(Object.assign({},this._constraints.video),{deviceId:{exact:this._selectedCamera.getID()}}),audio:!!this._selectedMicrophone&&{deviceId:{exact:this._selectedMicrophone.getID()}}};try{var e=yield navigator.mediaDevices.getUserMedia(t);this._stream=e,this.onCameraStreamSuccess(this._stream)}catch(e){t.video&&this.onUserMediaError({name:e.name||"Error",message:e.message||"Unknown error",deviceType:"video"}),t.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.StreamerState.READY)}catch(e){console.error("Error in startCamera:",e),yield this.grabDevices()}})}updateWebRTCStream(){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)}))}closeStream(){void 0!==this._peerConnection&&null!==this._peerConnection&&this._peerConnection.close(),this.setPublishState(exports.PublishState.UNPUBLISHED)}pickCamera(){var e;for(let e=0;e<this._cameraList.getSize();e++)this._cameraList.get(e).setSelected(!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).getID()===i){this._selectedCamera=this._cameraList.get(e),this._selectedCamera.setSelected(!0),this.setCameraState(exports.DeviceState.ENABLED),t=!0,this._constraints.video.deviceId=this._selectedCamera.getID();break}if(!t)return this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.StreamerState.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),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.StreamerState.INVALID),null;this._selectedCamera=this._cameraList.get(0),this._selectedCamera.setSelected(!0),null!=(e=this._main.getStorageManager())&&e.saveField("cameraID",this._selectedCamera.getID()),this._constraints.video.deviceId=this._selectedCamera.getID(),this.setCameraState(exports.DeviceState.ENABLED)}}return this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._selectedCamera}pickMicrophone(){var e;for(let e=0;e<this._microphoneList.getSize();e++)this._microphoneList.get(e).setSelected(!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).getID()===i){this._selectedMicrophone=this._microphoneList.get(e),t=!0,this.setMicrophoneState(exports.DeviceState.ENABLED);break}if(!t)return this._main.dispatchEvent("savedMicrophoneNotFound",{ref:this._main,savedDeviceID:i}),this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.StreamerState.INVALID),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null),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.StreamerState.INVALID),null;this._selectedMicrophone=this._microphoneList.get(0),this.setMicrophoneState(exports.DeviceState.ENABLED),null!=(e=this._main.getStorageManager())&&e.saveField("microphoneID",this._selectedMicrophone.getID())}this._selectedMicrophone.setSelected(!0),this._constraints.audio={deviceId:this._selectedMicrophone.getID()}}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){this._isMicrophoneMuted!==e&&(this._isMicrophoneMuted=e,this._stream?this.applyMicrophoneState(!e):(this._pendingMicrophoneState=!e,this._logger.info(this,`WebRTCStreamer :: Stream not yet available, storing microphone state (muted: ${e})`)),this._main.dispatchEvent("microphoneStateChange",{ref:this._main,isMuted:this._isMicrophoneMuted}))}applyMicrophoneState(t){var e;this._stream?(e=this._stream.getAudioTracks())&&0<e.length?(this._logger.success(this,`WebRTCStreamer :: ${t?"Unmuting":"Muting"} microphone`),e.forEach(e=>e.enabled=t)):this._logger.warning(this,"WebRTCStreamer :: No audio tracks found in stream"):this._logger.warning(this,"WebRTCStreamer :: Cannot apply microphone state - stream not available")}isStreamReady(e=!0,t=!0){var i,n;return!!this._stream&&(n=this._stream.getVideoTracks(),i=this._stream.getAudioTracks(),e=!e||0<n.length&&"live"===n[0].readyState,n=!t||0<i.length&&"live"===i[0].readyState,e)&&n}closeWebRTCConnection(){this._peerConnection&&(this._peerConnection.close(),this._peerConnection=null)}onDescriptionError(e){this._logger.info(this,"WebRTCStreamer :: onDescriptionError: "+JSON.stringify(e))}onIceCandidate(e){e.candidate}createStatusConnection(){var e=null==(e=null==(e=null==(e=this._main)?void 0:e.getNetworkController())?void 0:e.getConnection())?void 0:e.getCurrentServer();e&&(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._logger.info(this,"Publish State: "+e),this._publishState=e,this._main.dispatchEvent("publishStateChange",{ref:this._main,state:this._publishState})}setInputDeviceState(e){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._main.dispatchEvent("cameraDeviceStateChange",{ref:this._main,state:e,selectedCamera:this._selectedCamera})}getCamerState(){return this._cameraState}setMicrophoneState(e){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}stopCameraStream(){var e;this._stream&&(this._stream.getTracks().forEach(e=>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)}forceStopAllStreams(){var e,t;if(this._peerConnection)try{this._peerConnection.getSenders().forEach(e=>{var t;try{e.track&&(e.track.enabled=!1,e.track.stop(),null!=(t=this._peerConnection))&&t.removeTrack(e)}catch(e){console.error("Error stopping sender track:",e)}}),this._peerConnection.close(),this._peerConnection=null}catch(e){console.error("Error closing peer connection:",e)}try{var i=null==(t=null==(e=this._main.getStageController())?void 0:e.getScreenElement())?void 0:t.getVideoElement();i&&i.srcObject instanceof MediaStream&&(i.srcObject.getTracks().forEach(e=>{try{e.enabled=!1,e.stop()}catch(e){console.error("Error stopping video element track:",e)}}),i.srcObject=null,i.removeAttribute("src"),i.load())}catch(e){console.error("Error cleaning video element:",e)}if(this._stream)try{this._stream.getTracks().forEach(t=>{try{t.enabled=!1,t.stop()}catch(e){console.error(`Error stopping ${t.kind} track:`,e)}}),this._stream=null}catch(e){console.error("Error stopping main stream:",e)}}destroy(){window.screen&&window.screen.orientation?window.screen.orientation.removeEventListener("change",this.handleOrientationChange):window.removeEventListener("orientationchange",this.handleOrientationChange),this.forceStopAllStreams(),this._soundMeter&&this._soundMeter.detach(),clearTimeout(this._publishTimer),this._pendingMicrophoneState=null,this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._permissionChecked=!1,this._isWindowActive=!1,this._isMicrophoneMuted=!1;try{this._main.removeEventListener("serverConnect",this.onServerConnect),this._main.removeEventListener("serverDisconnect",this.onServerDisconnect),document.removeEventListener("visibilitychange",this.visibilityChange),window.removeEventListener("blur",this.onWindowBlur),window.removeEventListener("focus",this.onWindowFocus)}catch(e){console.error("Error removing event listeners:",e)}this._publishState=exports.PublishState.NOT_INITIALIZED,null!=this._restartTimer&&clearInterval(this._restartTimer)}}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.getPlaybackController())&&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 StormStreamer extends EventDispatcher{constructor(e,t=!1){super(),this.DEV_MODE=!0,this.STREAMER_VERSION="0.9.0-beta.11",this.COMPILE_DATE="1/14/2025, 2:09:29 PM",this.STREAMER_BRANCH="Experimental",this.STREAMER_PROTOCOL_VERSION=1,this._initialized=!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('StormLibrary Creation Error - No "window" element in the provided context!')}initialize(){if(!this._isRemoved){if(null==this._configManager)throw Error("Stream Config was not provided for this library! A properly configured object must be provided through the constructor or via the setConfig method before using the initialize() method.");this._storageManager=new StorageManager(this),this._stageController=new StageController(this),this._networkController=new NetworkController(this),this._playbackController=new PlaybackController(this),this._clientUser=new ClientUser,this._initialized=!0,this.dispatchEvent("streamerReady",{ref:this})}}setStreamConfig(e){this._isRemoved||(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,"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})))}stop(){}isConnected(){var e;return null!=(e=null==(e=this._networkController)?void 0:e.getConnection().isConnectionActive())&&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}mute(){null!=this._stageController&&null!=this._stageController.getScreenElement()?this._stageController.getScreenElement().setMuted(!0):this._configManager.getSettingsData().getAudioData().muted=!0}unmute(){null!=this._stageController&&null!=this._stageController.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._playbackController)?void 0:e.getCameraList())?e:[]}getMicrophoneList(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getMicrophoneList())?e:[]}setCamera(e){var t;null!=(t=this._playbackController)&&t.selectCamera(e)}setMicrophone(e){var t;null!=(t=this._playbackController)&&t.selectMicrophone(e)}getCurrentCamera(){return this._playbackController.getCurrentCamera()}getCurrentMicrophone(){return this._playbackController.getCurrentMicrophone()}muteMicrophone(e){var t;null!=(t=this._playbackController)&&t.muteMicrophone(e)}isMicrophoneMuted(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.isMicrophoneMuted())&&e}getPublishState(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getPublishState())?e:exports.PublishState.NOT_INITIALIZED}publish(e){var t;return null!=(t=null==(t=this._playbackController)?void 0:t.publish(e))&&t}getStreamerState(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getInputDeviceState())?e:exports.StreamerState.NOT_INITIALIZED}getCamerState(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getCamerState())?e:exports.DeviceState.NOT_INITIALIZED}getMicrophoneState(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getMicrophoneState())?e:exports.DeviceState.NOT_INITIALIZED}clearSavedDevices(){var e;return null==(e=this._playbackController)?void 0:e.clearSavedDevices()}messSavedDevices(){var e;return null==(e=this._playbackController)?void 0:e.messSavedDevices()}isStreamReady(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.isStreamReady())&&e}unpublish(){var e;null!=(e=this._playbackController)&&e.unpublish()}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"),n=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(),n)?(n.drawImage(e,0,0,i.width,i.height),i.toBlob(e=>{t(e)},"image/png")):t(null)})}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()}getStreamerID(){return this._streamerID}getLogger(){return this._logger}getConfigManager(){return this._configManager}getNetworkController(){return this._networkController}getPlaybackController(){return this._playbackController}getStageController(){return this._stageController}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}getVersion(){return this.STREAMER_VERSION}getBranch(){return this.STREAMER_BRANCH}getStorageManager(){return this._storageManager}dispatchEvent(e,t){super.dispatchEvent(e,t)}destroy(){var e;this._logger.warning(this,"Destroying library instance, bye, bye!"),this.DEV_MODE&&"StormStreamerArray"in window&&(window.StormStreamerArray[this._streamerID]=null),this._initialized=!1,this._isRemoved=!0,null!=(e=null==(e=this._networkController)?void 0:e.getConnection())&&e.destroy(),null!=(e=this._playbackController)&&e.destroy(),null!=(e=this._stageController)&&e.destroy(),this.removeAllEventListeners()}}function create(e){return new StormStreamer(e)}StormStreamer.NEXT_STREAMER_ID=0,exports.StormStreamer=StormStreamer,exports.create=create;
34
+ `;continue}n+="\r\n"}return n}mungeSDPPlay(e){let n="";for(const r of e.split(/\r\n/))if(0!==r.length){if(r.includes("profile-level-id")){var s=r.substr(r.indexOf("profile-level-id")+17,6);let e=Number("0x"+s.substr(0,2)),t=Number("0x"+s.substr(2,2)),i=Number("0x"+s.substr(4,2));66<e&&(e=66,t=224,i=31),0===t&&(t=224);var o=("00"+e.toString(16)).slice(-2).toLowerCase()+("00"+t.toString(16)).slice(-2).toLowerCase()+("00"+i.toString(16)).slice(-2).toLowerCase();n+=r.replace(s,o)}else n+=r;n+="\r\n"}return n}}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}getLabel(){return this._label}getID(){return this._id}getGroupID(){return this._groupID}getIfSelected(){return this._isSelected}setSelected(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].getGroupID()&&this._internalList[e].getGroupID()==t.getGroupID()&&(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.PUBLISHED="PUBLISHED",e.PUBLISHED2="PUBLISHED2",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._instant=0,this._slow=0,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._analyser.smoothingTimeConstant=.3,this._microphone.connect(this._analyser),this.startMonitoring(),console.log("SoundMeter: Successfully attached to new audio stream")}catch(e){console.error("SoundMeter: Error during attach:",e),this.detach()}}else console.warn("SoundMeter: Attempted to attach stream without audio tracks")}detach(){var e,t;if(this._isMonitoring=!1,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("closed"!==(null==(e=this._audioContext)?void 0:e.state))try{null!=(t=this._audioContext)&&t.close()}catch(e){console.warn("SoundMeter: Error closing audio context:",e)}this._audioContext=null,this.clear(),console.log("SoundMeter: Successfully detached")}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){var e=Date.now();try{this._analyser.getFloatTimeDomainData(s);let t=0,i=0;for(let e=0;e<s.length;++e){var n=s[e];t+=n*n,.99<Math.abs(n)&&(i+=1)}this._instant=Math.sqrt(t/s.length),this._slow=.05*this._instant+.95*this._slow,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),void(this._isMonitoring=!1)}requestAnimationFrame(t)}};requestAnimationFrame(t)}}}exports.StreamerState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.INITIALIZED="INITIALIZED",e.READY="READY",e.UPDATING="UPDATING",e.INVALID="INVALID",e.UNKNOWN="UNKNOWN"}(exports.StreamerState||(exports.StreamerState={})),exports.DeviceState=void 0,function(e){e.NOT_INITIALIZED="NOT_INITIALIZED",e.ENABLED="ENABLED",e.ACCESS_DENIED="ACCESS_DENIED",e.NOT_FOUND="NOT_FOUND"}(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 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._isConnected=!0}onSocketError(e){this._isConnected=!1,this._disconnectedByUser||this._logger.error(this,"Connection with the server failed")}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")}onSocketMessage(e){console.log(1),"string"==typeof e.data&&console.log(2)}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 StreamMetaData{constructor(){this._streamWidth=0,this._streamHeight=0,this._aspectRatio="",this._hasVideoTrack=!1,this._hasAudioTrack=!1}StreamMetaData(){}getStreamWidth(){return this._streamWidth}getStreamHeight(){return this._streamHeight}setStreamWidth(e){this._streamWidth=e}setStreamHeight(e){this._streamHeight=e}getAspectRatio(){return this._aspectRatio}setAspectRatio(e){this._aspectRatio=e}hasVideoTrack(){return this._hasVideoTrack}setVideoTractPresence(e){this._hasVideoTrack=e}hasAudioTrack(){return this._hasAudioTrack}setAudioTractPresence(e){this._hasAudioTrack=e}}class PlaybackController{constructor(e){var t;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._inputDeviceState=exports.StreamerState.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.handleOrientationChange=()=>__awaiter(this,void 0,void 0,function*(){yield new Promise(e=>setTimeout(e,500));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;var e=null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey,t=this._publishState===exports.PublishState.PUBLISHED;this.closeWebRTCConnection(),this._stream&&(this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null);try{yield this.startCamera(),t&&e&&this.publish(e)}catch(e){this._logger.error(this,"Error restarting stream after orientation change: "+JSON.stringify(e)),this.setInputDeviceState(exports.StreamerState.INVALID)}}}),this.onServerDisconnect=()=>{},this.onStreamKeyTaken=()=>{null!=this._restartTimer&&(clearInterval(this._restartTimer),this._restartTimerCount=0),this._logger.info(this,"WebRTCStreamer :: Starting StreamKeyTaken Interval"),this._restartTimer=setInterval(()=>{var e;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.publish(e)),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._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)try{var e=yield this._peerConnection.createOffer();yield this.onDescriptionSuccess(e)}catch(e){this.onDescriptionError(e),console.error("Error creating offer:",e)}})},this.onDescriptionSuccess=t=>{var e;const i={applicationName:null==(e=null==(e=this._main.getNetworkController())?void 0:e.getConnection().getCurrentServer())?void 0:e.getApplication(),streamName:null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey,sessionId:"[empty]"};t.sdp=this._mungeSDP.mungeSDPPublish(t.sdp,{audioBitrate:"64",videoBitrate:"1500",videoFrameRate:30,videoCodec:"42e01f",audioCodec:"opus"}),this._peerConnection&&this._peerConnection.setLocalDescription(t).then(()=>{var e;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.initializeDevices()}initialize(){var e;this._main.addEventListener("serverConnect",this.onServerConnect,!1),this._main.addEventListener("serverDisconnect",this.onServerDisconnect,!1),this._main.addEventListener("streamKeyInUse",this.onStreamKeyTaken,!1),document.addEventListener("visibilitychange",this.visibilityChange),window.addEventListener("blur",this.onWindowBlur),window.addEventListener("focus",this.onWindowFocus),(this._selectedCamera||this._selectedMicrophone)&&this.startCamera().then(()=>{}),null!=(e=this._main.getConfigManager())&&e.getSettingsData().autoConnect?(this._logger.info(this,"Initializing NetworkController (autoConnect is true)"),null!=(e=this._main.getNetworkController())&&e.initialize()):this._logger.warning(this,"Warning - autoConnect is set to false, switching to standby mode!"),this.setupOrientationListener(),this.setupPermissionListeners()}initializeDevices(){return __awaiter(this,void 0,void 0,function*(){this._main.addEventListener("deviceStateChange",e=>{var t=this._main.getConfigManager().getStreamData().streamKey;e.state==exports.StreamerState.READY&&null!=t&&this.publish(t)},!1);try{(yield navigator.mediaDevices.getUserMedia({video:!0,audio:!0})).getTracks().forEach(e=>e.stop()),yield this.grabDevices(),this.setupPermissionListeners(),this.initialize()}catch(e){this._logger.error(this,"Error initializing devices: "+JSON.stringify(e)),yield this.grabDevices(),this.setupPermissionListeners(),this.initialize()}})}requestPermissions(){return __awaiter(this,void 0,void 0,function*(){try{return(yield navigator.mediaDevices.getUserMedia({video:!0,audio:!0})).getTracks().forEach(e=>e.stop()),yield this.grabDevices(),!0}catch(e){return this._logger.error(this,"Error requesting permissions: "+JSON.stringify(e)),!1}})}setupPermissionListeners(){navigator.permissions.query({name:"camera"}).then(e=>{e.onchange=()=>{this._permissionChecked=!1,this.handlePermissionChange("camera",e.state)}}),navigator.permissions.query({name:"microphone"}).then(e=>{e.onchange=()=>{this._permissionChecked=!1,this.handlePermissionChange("microphone",e.state)}})}handlePermissionChange(e,t){return __awaiter(this,void 0,void 0,function*(){"denied"===t&&(this.setInputDeviceState(exports.StreamerState.INVALID),this._publishState==exports.PublishState.PUBLISHED)&&this.closeStream(),yield this.grabDevices(),"granted"===t&&(yield this.startCamera())})}onCameraStreamSuccess(e){this._logger.success(this,"Camera stream successfully retrieved");var n=e.getVideoTracks()[0],t=e.getAudioTracks()[0],s=new StreamMetaData;if(n){n=n.getSettings();let e=n.width,t=n.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]),s.setStreamWidth(e),s.setStreamHeight(t),s.setVideoTractPresence(!0);const a=(e,t)=>t?a(t,e%t):e;var n=a(e,t),o=e/n,n=t/n,r=e/t;let i=o+":"+n;Math.abs(r-16/9)<.1?i=e>t?"16:9":"9:16":Math.abs(r-4/3)<.1&&(i=e>t?"4:3":"3:4"),s.setAspectRatio(i)}else s.setVideoTractPresence(!1);s.setAudioTractPresence(!!t),this._logger.info(this,`Stream dimensions: ${s.getStreamWidth()}x${s.getStreamHeight()}, `+`Aspect ratio: ${s.getAspectRatio()}, `+`Video: ${s.hasVideoTrack()}, Audio: `+s.hasAudioTrack()),this._main.dispatchEvent("streamMetadataUpdate",{ref:this._main,metadata:s}),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();o=this._main.getStageController().getScreenElement().getVideoElement();o.srcObject=e,o.autoplay=!0,o.playsInline=!0,o.disableRemotePlayback=!0,o.controls=!1,o.muted=!0,this.setPublishState(exports.PublishState.INITIALIZED)}initializeWebRTC(){var e;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._logger.warning(this,"Publishing: "+e),this._main.getConfigManager().getStreamData().streamKey==e&&this._publishState==exports.PublishState.PUBLISHED?(this._logger.warning(this,"Already published!"),!1):(this._main.getConfigManager().getStreamData().streamKey=e,console.log(this.isStreamReady(!0,!0)),this.isStreamReady(!0,!0)?(this._logger.info(this,"Publish: "+e),this.createStatusConnection(),this.closeWebRTCConnection(),this._main.dispatchEvent("publish",{ref:this._main,streamKey:e}),this.initializeWebRTC(),!0):(this._logger.warning(this,"Cannot publish - stream not ready (missing video or audio track)"),!1))}unpublish(){clearTimeout(this._publishTimer),this._main.getConfigManager().getStreamData().streamKey=null,this._main.dispatchEvent("unpublish",{ref:this._main}),this.closeStream()}setupOrientationListener(){window.screen&&window.screen.orientation?window.screen.orientation.addEventListener("change",this.handleOrientationChange):window.addEventListener("orientationchange",this.handleOrientationChange)}onUserMediaError(e){return __awaiter(this,void 0,void 0,function*(){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}};try{var e=yield navigator.mediaDevices.enumerateDevices(),i=(t.camera.available=e.some(e=>"videoinput"===e.kind),t.microphone.available=e.some(e=>"audioinput"===e.kind),e.some(e=>""!==e.label));if(i)t.camera.allowed=e.some(e=>"videoinput"===e.kind&&""!==e.label),t.microphone.allowed=e.some(e=>"audioinput"===e.kind&&""!==e.label);else try{var n=yield navigator.mediaDevices.getUserMedia({video:t.camera.available,audio:t.microphone.available});t.camera.allowed=0<n.getVideoTracks().length,t.microphone.allowed=0<n.getAudioTracks().length,n.getTracks().forEach(e=>e.stop()),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),t.camera.available=!1,t.microphone.available=!1,t.camera.allowed=!1,t.microphone.allowed=!1}return t})}onSocketMessage(e){var t=JSON.parse(e);switch(Number(t.status)){case 200:this._logger.info(this,"SDP Exchange Successful");var i=t.sdp,n=(void 0!==i&&this._peerConnection.setRemoteDescription(new RTCSessionDescription(i),()=>{},()=>{}),t.iceCandidates);if(void 0!==n)for(var s in n)this._peerConnection&&this._peerConnection.addIceCandidate(new RTCIceCandidate(n[s]));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){var t;if(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.PUBLISHED),null!=this._statusConnection&&null!=(t=null==(t=this._main.getConfigManager())?void 0:t.getStreamData().streamKey)&&this._statusConnection.sendData('{"packetID":"STREAM_STATUS", "streamKey": "'+t+'"}'),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*(){try{var e,t,i=yield this.checkIndividualDeviceAccess(),n=(this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._permissionChecked||(i.camera.allowed?i.camera.available||(this._main.dispatchEvent("noCameraFound",{ref:this._main}),this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.StreamerState.INVALID)):(this._main.dispatchEvent("cameraAccessDenied",{ref:this._main}),this.setCameraState(exports.DeviceState.ACCESS_DENIED),this.setInputDeviceState(exports.StreamerState.INVALID)),i.microphone.allowed?i.microphone.available||(this._main.dispatchEvent("noMicrophoneFound",{ref:this._main}),this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.StreamerState.INVALID)):(this._main.dispatchEvent("microphoneAccessDenied",{ref:this._main}),this.setMicrophoneState(exports.DeviceState.ACCESS_DENIED),this.setInputDeviceState(exports.StreamerState.INVALID))),yield navigator.mediaDevices.enumerateDevices());for(const s of n)s.deviceId&&s.label&&("videoinput"===s.kind&&i.camera.allowed?(e=new InputDevice(s,this._cameraList.getSize()),this._cameraList.push(e)):"audioinput"===s.kind&&i.microphone.allowed&&(t=new InputDevice(s,this._microphoneList.getSize()),this._microphoneList.push(t)));try{i.camera.allowed&&(this._selectedCamera=this.pickCamera()),i.microphone.allowed&&(this._selectedMicrophone=this.pickMicrophone())}catch(e){this.setInputDeviceState(exports.StreamerState.INVALID),this._logger.error(this,"Errror on grab devices: "+JSON.stringify(e))}this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._permissionChecked=!0}catch(e){console.error("Error in grabDevices:",e),this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._main.dispatchEvent("inputDeviceError",{ref:this._main})}})}selectCamera(t){var e,i;this._selectedCamera=null,this.setInputDeviceState(exports.StreamerState.UPDATING),this.setCameraState(exports.DeviceState.NOT_INITIALIZED);const n=null==(e=this._main.getConfigManager())?void 0:e.getStreamData().streamKey,s=this._publishState===exports.PublishState.PUBLISHED;for(let e=0;e<this._cameraList.getSize();e++)if(this._cameraList.get(e).getID()==t){this._selectedCamera=this._cameraList.get(e),null!=(i=this._main.getStorageManager())&&i.saveField("cameraID",this._selectedCamera.getID());break}this.stopCameraStream(),null!=this._selectedCamera?(this._constraints.video.deviceId=this._selectedCamera.getID(),this.startCamera().then(()=>{this.setCameraState(exports.DeviceState.ENABLED),this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED?this.setInputDeviceState(exports.StreamerState.READY):this.setInputDeviceState(exports.StreamerState.INVALID),s&&n&&this.publish(n)})):this.setInputDeviceState(exports.StreamerState.INVALID)}selectMicrophone(i){var n,s;return __awaiter(this,void 0,void 0,function*(){this._selectedMicrophone=null,this.setInputDeviceState(exports.StreamerState.UPDATING),this.setMicrophoneState(exports.DeviceState.NOT_INITIALIZED),this._logger.info(this,"Selecting microphone: "+i);var e=null==(n=this._main.getConfigManager())?void 0:n.getStreamData().streamKey,t=this._publishState===exports.PublishState.PUBLISHED;for(let e=0;e<this._microphoneList.getSize();e++)if(this._microphoneList.get(e).getID()==i){this._selectedMicrophone=this._microphoneList.get(e),null!=(s=this._main.getStorageManager())&&s.saveField("microphoneID",this._selectedMicrophone.getID());break}this._soundMeter.detach(),this.closeWebRTCConnection(),this._stream&&(this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null);try{yield this.startCamera(),this.setMicrophoneState(exports.DeviceState.ENABLED),this._cameraState==exports.DeviceState.ENABLED&&this._microphoneState==exports.DeviceState.ENABLED?this.setInputDeviceState(exports.StreamerState.READY):this.setInputDeviceState(exports.StreamerState.INVALID),t&&e&&this.publish(e)}catch(e){console.error("Error changing microphone:",e),this._main.dispatchEvent("inputDeviceError",{ref:this._main}),this.setInputDeviceState(exports.StreamerState.INVALID)}})}startCamera(){return __awaiter(this,void 0,void 0,function*(){this._stream&&(this._stream.getTracks().forEach(e=>{e.stop()}),this._stream=null);try{var t={video:!!this._selectedCamera&&Object.assign(Object.assign({},this._constraints.video),{deviceId:{exact:this._selectedCamera.getID()}}),audio:!!this._selectedMicrophone&&{deviceId:{exact:this._selectedMicrophone.getID()}}};try{var e=yield navigator.mediaDevices.getUserMedia(t);this._stream=e,this.onCameraStreamSuccess(this._stream)}catch(e){t.video&&this.onUserMediaError({name:e.name||"Error",message:e.message||"Unknown error",deviceType:"video"}),t.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.StreamerState.READY)}catch(e){console.error("Error in startCamera:",e),yield this.grabDevices()}})}updateWebRTCStream(){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)}))}closeStream(){void 0!==this._peerConnection&&null!==this._peerConnection&&this._peerConnection.close(),this.setPublishState(exports.PublishState.UNPUBLISHED)}pickCamera(){var e;for(let e=0;e<this._cameraList.getSize();e++)this._cameraList.get(e).setSelected(!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).getID()===i){this._selectedCamera=this._cameraList.get(e),this._selectedCamera.setSelected(!0),this.setCameraState(exports.DeviceState.ENABLED),t=!0,this._constraints.video.deviceId=this._selectedCamera.getID();break}if(!t)return this.setCameraState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.StreamerState.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),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.StreamerState.INVALID),null;this._selectedCamera=this._cameraList.get(0),this._selectedCamera.setSelected(!0),null!=(e=this._main.getStorageManager())&&e.saveField("cameraID",this._selectedCamera.getID()),this._constraints.video.deviceId=this._selectedCamera.getID(),this.setCameraState(exports.DeviceState.ENABLED)}}return this._main.dispatchEvent("deviceListUpdate",{ref:this._main,cameraList:this._cameraList.getArray(),microphoneList:this._microphoneList.getArray()}),this._selectedCamera}pickMicrophone(){var e;for(let e=0;e<this._microphoneList.getSize();e++)this._microphoneList.get(e).setSelected(!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).getID()===i){this._selectedMicrophone=this._microphoneList.get(e),t=!0,this.setMicrophoneState(exports.DeviceState.ENABLED);break}if(!t)return this._main.dispatchEvent("savedMicrophoneNotFound",{ref:this._main,savedDeviceID:i}),this.setMicrophoneState(exports.DeviceState.NOT_FOUND),this.setInputDeviceState(exports.StreamerState.INVALID),null!=(e=this._main.getConfigManager())&&e.getSettingsData().getIfCancelPublishOnError()&&(this._logger.info(this,"Canceling Publish!"),this._main.getConfigManager().getStreamData().streamKey=null),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.StreamerState.INVALID),null;this._selectedMicrophone=this._microphoneList.get(0),this.setMicrophoneState(exports.DeviceState.ENABLED),null!=(e=this._main.getStorageManager())&&e.saveField("microphoneID",this._selectedMicrophone.getID())}this._selectedMicrophone.setSelected(!0),this._constraints.audio={deviceId:this._selectedMicrophone.getID()}}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){this._isMicrophoneMuted!==e&&(this._isMicrophoneMuted=e,this._stream?this.applyMicrophoneState(!e):(this._pendingMicrophoneState=!e,this._logger.info(this,`WebRTCStreamer :: Stream not yet available, storing microphone state (muted: ${e})`)),this._main.dispatchEvent("microphoneStateChange",{ref:this._main,isMuted:this._isMicrophoneMuted}))}applyMicrophoneState(t){var e;this._stream?(e=this._stream.getAudioTracks())&&0<e.length?(this._logger.success(this,`WebRTCStreamer :: ${t?"Unmuting":"Muting"} microphone`),e.forEach(e=>e.enabled=t)):this._logger.warning(this,"WebRTCStreamer :: No audio tracks found in stream"):this._logger.warning(this,"WebRTCStreamer :: Cannot apply microphone state - stream not available")}isStreamReady(e=!0,t=!0){var i,n;return!!this._stream&&(n=this._stream.getVideoTracks(),i=this._stream.getAudioTracks(),e=!e||0<n.length&&"live"===n[0].readyState,n=!t||0<i.length&&"live"===i[0].readyState,e)&&n}closeWebRTCConnection(){this._peerConnection&&(this._peerConnection.close(),this._peerConnection=null)}onDescriptionError(e){this._logger.info(this,"WebRTCStreamer :: onDescriptionError: "+JSON.stringify(e))}onIceCandidate(e){e.candidate}createStatusConnection(){var e=null==(e=null==(e=null==(e=this._main)?void 0:e.getNetworkController())?void 0:e.getConnection())?void 0:e.getCurrentServer();e&&(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._logger.info(this,"Publish State: "+e),this._publishState=e,this._main.dispatchEvent("publishStateChange",{ref:this._main,state:this._publishState})}setInputDeviceState(e){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._main.dispatchEvent("cameraDeviceStateChange",{ref:this._main,state:e,selectedCamera:this._selectedCamera})}getCamerState(){return this._cameraState}setMicrophoneState(e){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}stopCameraStream(){var e;this._stream&&(this._stream.getTracks().forEach(e=>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)}forceStopAllStreams(){var e,t;if(this._peerConnection)try{this._peerConnection.getSenders().forEach(e=>{var t;try{e.track&&(e.track.enabled=!1,e.track.stop(),null!=(t=this._peerConnection))&&t.removeTrack(e)}catch(e){console.error("Error stopping sender track:",e)}}),this._peerConnection.close(),this._peerConnection=null}catch(e){console.error("Error closing peer connection:",e)}try{var i=null==(t=null==(e=this._main.getStageController())?void 0:e.getScreenElement())?void 0:t.getVideoElement();i&&i.srcObject instanceof MediaStream&&(i.srcObject.getTracks().forEach(e=>{try{e.enabled=!1,e.stop()}catch(e){console.error("Error stopping video element track:",e)}}),i.srcObject=null,i.removeAttribute("src"),i.load())}catch(e){console.error("Error cleaning video element:",e)}if(this._stream)try{this._stream.getTracks().forEach(t=>{try{t.enabled=!1,t.stop()}catch(e){console.error(`Error stopping ${t.kind} track:`,e)}}),this._stream=null}catch(e){console.error("Error stopping main stream:",e)}}destroy(){window.screen&&window.screen.orientation?window.screen.orientation.removeEventListener("change",this.handleOrientationChange):window.removeEventListener("orientationchange",this.handleOrientationChange),this.forceStopAllStreams(),this._soundMeter&&this._soundMeter.detach(),clearTimeout(this._publishTimer),this._pendingMicrophoneState=null,this._cameraList=new InputDeviceList,this._microphoneList=new InputDeviceList,this._permissionChecked=!1,this._isWindowActive=!1,this._isMicrophoneMuted=!1;try{this._main.removeEventListener("serverConnect",this.onServerConnect),this._main.removeEventListener("serverDisconnect",this.onServerDisconnect),document.removeEventListener("visibilitychange",this.visibilityChange),window.removeEventListener("blur",this.onWindowBlur),window.removeEventListener("focus",this.onWindowFocus)}catch(e){console.error("Error removing event listeners:",e)}this._publishState=exports.PublishState.NOT_INITIALIZED,null!=this._restartTimer&&clearInterval(this._restartTimer)}}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.getPlaybackController())&&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 StormStreamer extends EventDispatcher{constructor(e,t=!1){super(),this.DEV_MODE=!0,this.STREAMER_VERSION="0.9.0-beta.13",this.COMPILE_DATE="1/14/2025, 3:03:39 PM",this.STREAMER_BRANCH="Experimental",this.STREAMER_PROTOCOL_VERSION=1,this._initialized=!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('StormLibrary Creation Error - No "window" element in the provided context!')}initialize(){if(!this._isRemoved){if(null==this._configManager)throw Error("Stream Config was not provided for this library! A properly configured object must be provided through the constructor or via the setConfig method before using the initialize() method.");this._storageManager=new StorageManager(this),this._stageController=new StageController(this),this._networkController=new NetworkController(this),this._playbackController=new PlaybackController(this),this._clientUser=new ClientUser,this._initialized=!0,this.dispatchEvent("streamerReady",{ref:this})}}setStreamConfig(e){this._isRemoved||(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,"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})))}stop(){}isConnected(){var e;return null!=(e=null==(e=this._networkController)?void 0:e.getConnection().isConnectionActive())&&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}mute(){null!=this._stageController&&null!=this._stageController.getScreenElement()?this._stageController.getScreenElement().setMuted(!0):this._configManager.getSettingsData().getAudioData().muted=!0}unmute(){null!=this._stageController&&null!=this._stageController.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._playbackController)?void 0:e.getCameraList())?e:[]}getMicrophoneList(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getMicrophoneList())?e:[]}setCamera(e){var t;null!=(t=this._playbackController)&&t.selectCamera(e)}setMicrophone(e){var t;null!=(t=this._playbackController)&&t.selectMicrophone(e)}getCurrentCamera(){return this._playbackController.getCurrentCamera()}getCurrentMicrophone(){return this._playbackController.getCurrentMicrophone()}muteMicrophone(e){var t;null!=(t=this._playbackController)&&t.muteMicrophone(e)}isMicrophoneMuted(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.isMicrophoneMuted())&&e}getPublishState(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getPublishState())?e:exports.PublishState.NOT_INITIALIZED}publish(e){var t;return null!=(t=null==(t=this._playbackController)?void 0:t.publish(e))&&t}getStreamerState(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getInputDeviceState())?e:exports.StreamerState.NOT_INITIALIZED}getCamerState(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getCamerState())?e:exports.DeviceState.NOT_INITIALIZED}getMicrophoneState(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.getMicrophoneState())?e:exports.DeviceState.NOT_INITIALIZED}clearSavedDevices(){var e;return null==(e=this._playbackController)?void 0:e.clearSavedDevices()}messSavedDevices(){var e;return null==(e=this._playbackController)?void 0:e.messSavedDevices()}isStreamReady(){var e;return null!=(e=null==(e=this._playbackController)?void 0:e.isStreamReady())&&e}unpublish(){var e;null!=(e=this._playbackController)&&e.unpublish()}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"),n=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(),n)?(n.drawImage(e,0,0,i.width,i.height),i.toBlob(e=>{t(e)},"image/png")):t(null)})}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()}getStreamerID(){return this._streamerID}getLogger(){return this._logger}getConfigManager(){return this._configManager}getNetworkController(){return this._networkController}getPlaybackController(){return this._playbackController}getStageController(){return this._stageController}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}getVersion(){return this.STREAMER_VERSION}getBranch(){return this.STREAMER_BRANCH}getStorageManager(){return this._storageManager}dispatchEvent(e,t){super.dispatchEvent(e,t)}destroy(){var e;this._logger.warning(this,"Destroying library instance, bye, bye!"),this.DEV_MODE&&"StormStreamerArray"in window&&(window.StormStreamerArray[this._streamerID]=null),this._initialized=!1,this._isRemoved=!0,null!=(e=null==(e=this._networkController)?void 0:e.getConnection())&&e.destroy(),null!=(e=this._playbackController)&&e.destroy(),null!=(e=this._stageController)&&e.destroy(),this.removeAllEventListeners()}}function create(e){return new StormStreamer(e)}StormStreamer.NEXT_STREAMER_ID=0,exports.StormStreamer=StormStreamer,exports.create=create;