@yang__yj/pixelstreaming-core 1.0.1 → 1.0.3
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/lib-pixelstreamingfrontend.esm.js +1 -1
- package/dist/lib-pixelstreamingfrontend.js +1 -1
- package/package.json +2 -1
- package/src/Inputs/TouchController.ts +11 -11
- package/src/WebRtcPlayer/WebRtcPlayerController.ts +256 -177
- package/types/Config/Config.d.ts +5 -4
- package/types/DataChannel/DataChannelLatencyTestController.d.ts +26 -0
- package/types/DataChannel/DataChannelLatencyTestResults.d.ts +46 -0
- package/types/Inputs/HoveringMouseEvents.d.ts +1 -1
- package/types/PeerConnectionController/PeerConnectionController.d.ts +1 -1
- package/types/PixelStreaming/PixelStreaming.d.ts +31 -6
- package/types/UeInstanceMessage/SendMessageController.d.ts +1 -1
- package/types/UeInstanceMessage/StreamMessageController.d.ts +3 -5
- package/types/Util/EventEmitter.d.ts +40 -3
- package/types/Util/RTCUtils.d.ts +8 -0
- package/types/VideoPlayer/StreamController.d.ts +3 -3
- package/types/VideoPlayer/VideoPlayer.d.ts +2 -0
- package/types/WebRtcPlayer/WebRtcPlayerController.d.ts +30 -27
- package/types/WebSockets/MessageReceive.d.ts +9 -9
- package/types/WebSockets/MessageSend.d.ts +13 -9
- package/types/WebSockets/SignallingProtocol.d.ts +3 -3
- package/types/WebSockets/WebSocketController.d.ts +16 -12
- package/types/pixelstreamingfrontend.d.ts +2 -1
- package/yang__yj-pixelstreaming-core-1.0.1.tgz +0 -0
- package/yang__yj-pixelstreaming-core-1.0.3.tgz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("sdp")):"function"==typeof define&&define.amd?define(["sdp"],t):"object"==typeof exports?exports["lib-pixelstreamingfrontend"]=t(require("sdp")):e["lib-pixelstreamingfrontend"]=t(e.sdp)}(this,(e=>(()=>{"use strict";var t={366:t=>{t.exports=e}},s={};function n(e){var r=s[e];if(void 0!==r)return r.exports;var i=s[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.d=(e,t)=>{for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{n.r(r),n.d(r,{AfkLogic:()=>Se,AfkTimedOutEvent:()=>x,AfkWarningActivateEvent:()=>R,AfkWarningDeactivateEvent:()=>L,AfkWarningUpdateEvent:()=>k,AggregatedStats:()=>Pe,CandidatePairStats:()=>ye,CandidateStat:()=>Ee,Config:()=>me,ControlSchemeType:()=>pe,DataChannelCloseEvent:()=>B,DataChannelErrorEvent:()=>_,DataChannelOpenEvent:()=>z,DataChannelStats:()=>Te,EncoderSettings:()=>Oe,EventEmitter:()=>ie,Flags:()=>oe,HideFreezeFrameEvent:()=>j,InboundAudioStats:()=>Ce,InboundVideoStats:()=>fe,InitialSettings:()=>Fe,InitialSettingsEvent:()=>ee,LatencyTestResultEvent:()=>Z,LatencyTestResults:()=>Ge,LoadFreezeFrameEvent:()=>X,Logger:()=>e,MessageRecv:()=>p,MessageSend:()=>i,MessageStreamerList:()=>S,NumericParameters:()=>de,OptionParameters:()=>ge,OutBoundVideoStats:()=>be,PixelStreaming:()=>vt,PlayStreamErrorEvent:()=>Q,PlayStreamEvent:()=>$,PlayStreamRejectedEvent:()=>q,SettingBase:()=>y,SettingFlag:()=>b,SettingNumber:()=>M,SettingOption:()=>P,SettingText:()=>w,SettingsChangedEvent:()=>te,SignallingProtocol:()=>v,StatsReceivedEvent:()=>J,StreamLoadingEvent:()=>H,StreamPreConnectEvent:()=>V,StreamPreDisconnectEvent:()=>N,StreamReconnectEvent:()=>K,StreamerListMessageEvent:()=>Y,TextParameters:()=>ce,UnquantizedAndDenormalizeUnsigned:()=>lt,VideoEncoderAvgQPEvent:()=>A,VideoInitializedEvent:()=>W,WebRTCSettings:()=>Ue,WebRtcAutoConnectEvent:()=>D,WebRtcConnectedEvent:()=>U,WebRtcConnectingEvent:()=>O,WebRtcDisconnectedEvent:()=>I,WebRtcFailedEvent:()=>G,WebRtcPlayerController:()=>ht,WebRtcSdpEvent:()=>F,WebSocketController:()=>C,WebXRController:()=>pt,XrFrameEvent:()=>re,XrSessionEndedEvent:()=>ne,XrSessionStartedEvent:()=>se});class e{static GetStackTrace(){const e=new Error;let t="No Stack Available for this browser";return e.stack&&(t=e.stack.toString().replace(/Error/g,"")),t}static SetLoggerVerbosity(e){null!=this.verboseLogLevel&&(this.verboseLogLevel=e)}static Log(e,t,s){if(s>this.verboseLogLevel)return;const n=`Level: Log\nMsg: ${t}\nCaller: ${e}`;console.log(n)}static Info(e,t,s){if(s>this.verboseLogLevel)return;const n=`Level: Info\nMsg: ${t}`;console.info(n)}static Error(e,t){const s=`Level: Error\nMsg: ${t}\nCaller: ${e}`;console.error(s)}static Warning(e,t){const s=`Level: Warning\nCaller: ${e}\nMsg: ${t}`;console.warn(s)}}var t,s;e.verboseLogLevel=5,function(e){e.LIST_STREAMERS="listStreamers",e.SUBSCRIBE="subscribe",e.UNSUBSCRIBE="unsubscribe",e.ICE_CANDIDATE="iceCandidate",e.OFFER="offer",e.ANSWER="answer",e.DATACHANNELREQUEST="dataChannelRequest",e.SFURECVDATACHANNELREADY="peerDataChannelsReady",e.PONG="pong"}(t||(t={}));class i{payload(){return e.Log(e.GetStackTrace(),"Sending => \n"+JSON.stringify(this,void 0,4),6),JSON.stringify(this)}}class o extends i{constructor(){super(),this.type=t.LIST_STREAMERS}}class a extends i{constructor(e){super(),this.type=t.SUBSCRIBE,this.streamerId=e}}class d extends i{constructor(){super(),this.type=t.UNSUBSCRIBE}}class l extends i{constructor(e){super(),this.type=t.PONG,this.time=e}}class c extends i{constructor(e){super(),this.type=t.OFFER,e&&(this.type=e.type,this.sdp=e.sdp)}}class h extends i{constructor(e){super(),this.type=t.ANSWER,e&&(this.type=e.type,this.sdp=e.sdp)}}class g extends i{constructor(){super(),this.type=t.DATACHANNELREQUEST}}class u extends i{constructor(){super(),this.type=t.SFURECVDATACHANNELREADY}}class m{constructor(e){this.type=t.ICE_CANDIDATE,this.candidate=e}payload(){return e.Log(e.GetStackTrace(),"Sending => \n"+JSON.stringify(this,void 0,4),6),JSON.stringify(this)}}!function(e){e.CONFIG="config",e.STREAMER_LIST="streamerList",e.PLAYER_COUNT="playerCount",e.OFFER="offer",e.ANSWER="answer",e.ICE_CANDIDATE="iceCandidate",e.PEER_DATA_CHANNELS="peerDataChannels",e.PING="ping",e.WARNING="warning"}(s||(s={}));class p{}class S extends p{}class v{constructor(){this.FromUEMessageHandlers=new Map}addMessageHandler(e,t){this.FromUEMessageHandlers.set(e,t)}handleMessage(t,s){this.FromUEMessageHandlers.has(t)?this.FromUEMessageHandlers.get(t)(s):e.Error(e.GetStackTrace(),`Message type of ${t} does not have a message handler registered on the frontend - ignoring message.`)}static setupDefaultHandlers(t){t.signallingProtocol.addMessageHandler(s.PING,(n=>{const r=new l((new Date).getTime()).payload();e.Log(e.GetStackTrace(),s.PING+": "+n,6),t.webSocket.send(r)})),t.signallingProtocol.addMessageHandler(s.CONFIG,(n=>{e.Log(e.GetStackTrace(),s.CONFIG,6);const r=JSON.parse(n);t.onConfig(r)})),t.signallingProtocol.addMessageHandler(s.STREAMER_LIST,(n=>{e.Log(e.GetStackTrace(),s.STREAMER_LIST,6);const r=JSON.parse(n);t.onStreamerList(r)})),t.signallingProtocol.addMessageHandler(s.PLAYER_COUNT,(t=>{e.Log(e.GetStackTrace(),s.PLAYER_COUNT,6);const n=JSON.parse(t);e.Log(e.GetStackTrace(),"Player Count: "+n.count,6)})),t.signallingProtocol.addMessageHandler(s.ANSWER,(n=>{e.Log(e.GetStackTrace(),s.ANSWER,6);const r=JSON.parse(n);t.onWebRtcAnswer(r)})),t.signallingProtocol.addMessageHandler(s.OFFER,(n=>{e.Log(e.GetStackTrace(),s.OFFER,6);const r=JSON.parse(n);t.onWebRtcOffer(r)})),t.signallingProtocol.addMessageHandler(s.ICE_CANDIDATE,(n=>{e.Log(e.GetStackTrace(),s.ICE_CANDIDATE,6);const r=JSON.parse(n);t.onIceCandidate(r.candidate)})),t.signallingProtocol.addMessageHandler(s.WARNING,(t=>{e.Warning(e.GetStackTrace(),`Warning received: ${t}`)})),t.signallingProtocol.addMessageHandler(s.PEER_DATA_CHANNELS,(n=>{e.Log(e.GetStackTrace(),s.PEER_DATA_CHANNELS,6);const r=JSON.parse(n);t.onWebRtcPeerDataChannels(r)}))}}class C{constructor(){this.WS_OPEN_STATE=1,this.onOpen=new EventTarget,this.onClose=new EventTarget,this.signallingProtocol=new v,v.setupDefaultHandlers(this)}connect(t){e.Log(e.GetStackTrace(),t,6);try{return this.webSocket=new WebSocket(t),this.webSocket.onopen=e=>this.handleOnOpen(e),this.webSocket.onerror=()=>this.handleOnError(),this.webSocket.onclose=e=>this.handleOnClose(e),this.webSocket.onmessage=e=>this.handleOnMessage(e),this.webSocket.onmessagebinary=e=>this.handleOnMessageBinary(e),!0}catch(t){return e.Error(t,t),!1}}handleOnMessageBinary(t){t&&t.data&&t.data.text().then((e=>{const t=new MessageEvent("messageFromBinary",{data:e});this.handleOnMessage(t)})).catch((t=>{e.Error(e.GetStackTrace(),`Failed to parse binary blob from websocket, reason: ${t}`)}))}handleOnMessage(t){if(t.data&&t.data instanceof Blob)return void this.handleOnMessageBinary(t);const s=JSON.parse(t.data);e.Log(e.GetStackTrace(),"received => \n"+JSON.stringify(JSON.parse(t.data),void 0,4),6),this.signallingProtocol.handleMessage(s.type,t.data)}handleOnOpen(t){e.Log(e.GetStackTrace(),"Connected to the signalling server via WebSocket",6),this.onOpen.dispatchEvent(new Event("open"))}handleOnError(){e.Error(e.GetStackTrace(),"WebSocket error")}handleOnClose(t){this.onWebSocketOncloseOverlayMessage(t),e.Log(e.GetStackTrace(),"Disconnected to the signalling server via WebSocket: "+JSON.stringify(t.code)+" - "+t.reason),this.onClose.dispatchEvent(new CustomEvent("close",{detail:t}))}requestStreamerList(){const e=new o;this.webSocket.send(e.payload())}sendSubscribe(e){const t=new a(e);this.webSocket.send(t.payload())}sendUnsubscribe(){const e=new d;this.webSocket.send(e.payload())}sendWebRtcOffer(e){const t=new c(e);this.webSocket.send(t.payload())}sendWebRtcAnswer(e){const t=new h(e);this.webSocket.send(t.payload())}sendWebRtcDatachannelRequest(){const e=new g;this.webSocket.send(e.payload())}sendSFURecvDataChannelReady(){const e=new u;this.webSocket.send(e.payload())}sendIceCandidate(t){if(e.Log(e.GetStackTrace(),"Sending Ice Candidate"),this.webSocket&&this.webSocket.readyState===this.WS_OPEN_STATE){const e=new m(t);this.webSocket.send(e.payload())}}close(){var e;null===(e=this.webSocket)||void 0===e||e.close()}onWebSocketOncloseOverlayMessage(e){}onConfig(e){}onStreamerList(e){}onIceCandidate(e){}onWebRtcAnswer(e){}onWebRtcOffer(e){}onWebRtcPeerDataChannels(e){}}class f{constructor(e){this.videoElementProvider=e,this.audioElement=document.createElement("Audio")}handleOnTrack(t){e.Log(e.GetStackTrace(),"handleOnTrack "+JSON.stringify(t.streams),6);const s=this.videoElementProvider.getVideoElement();if(t.track&&e.Log(e.GetStackTrace(),"Got track - "+t.track.kind+" id="+t.track.id+" readyState="+t.track.readyState,6),"audio"!=t.track.kind)return"video"==t.track.kind&&s.srcObject!==t.streams[0]?(s.srcObject=t.streams[0],void e.Log(e.GetStackTrace(),"Set video source from video track ontrack.")):void 0;this.CreateAudioTrack(t.streams[0])}CreateAudioTrack(t){const s=this.videoElementProvider.getVideoElement();s.srcObject!=t&&s.srcObject&&s.srcObject!==t&&(this.audioElement.srcObject=t,e.Log(e.GetStackTrace(),"Created new audio element to play separate audio stream."))}}class T{constructor(e){this.freezeFrameHeight=0,this.freezeFrameWidth=0,this.rootDiv=e,this.rootElement=document.createElement("div"),this.rootElement.id="freezeFrame",this.rootElement.style.display="none",this.rootElement.style.pointerEvents="none",this.rootElement.style.position="absolute",this.rootElement.style.zIndex="20",this.imageElement=document.createElement("img"),this.imageElement.style.position="absolute",this.rootElement.appendChild(this.imageElement),this.rootDiv.appendChild(this.rootElement)}setElementForShow(){this.rootElement.style.display="block"}setElementForHide(){this.rootElement.style.display="none"}updateImageElementSource(e){const t=btoa(e.reduce(((e,t)=>e+String.fromCharCode(t)),""));this.imageElement.src="data:image/jpeg;base64,"+t}setDimensionsFromElementAndResize(){this.freezeFrameHeight=this.imageElement.naturalHeight,this.freezeFrameWidth=this.imageElement.naturalWidth,this.resize()}resize(){if(0!==this.freezeFrameWidth&&0!==this.freezeFrameHeight){let e=0,t=0,s=0,n=0;const r=this.rootDiv.clientWidth/this.rootDiv.clientHeight,i=this.freezeFrameWidth/this.freezeFrameHeight;r<i?(e=this.rootDiv.clientWidth,t=Math.floor(this.rootDiv.clientWidth/i),s=Math.floor(.5*(this.rootDiv.clientHeight-t)),n=0):(e=Math.floor(this.rootDiv.clientHeight*i),t=this.rootDiv.clientHeight,s=0,n=Math.floor(.5*(this.rootDiv.clientWidth-e))),this.rootElement.style.width=this.rootDiv.offsetWidth+"px",this.rootElement.style.height=this.rootDiv.offsetHeight+"px",this.rootElement.style.left="0px",this.rootElement.style.top="0px",this.imageElement.style.width=e+"px",this.imageElement.style.height=t+"px",this.imageElement.style.left=n+"px",this.imageElement.style.top=s+"px"}}}class E{constructor(e){this.receiving=!1,this.size=0,this.jpeg=void 0,this.valid=!1,this.freezeFrameDelay=50,this.freezeFrame=new T(e)}showFreezeFrame(){this.valid&&this.freezeFrame.setElementForShow()}hideFreezeFrame(){this.valid=!1,this.freezeFrame.setElementForHide()}updateFreezeFrameAndShow(e,t){this.freezeFrame.updateImageElementSource(e),this.freezeFrame.imageElement.onload=()=>{this.freezeFrame.setDimensionsFromElementAndResize(),t()}}processFreezeFrameMessage(t,s){this.receiving||(this.receiving=!0,this.valid=!1,this.size=0,this.jpeg=void 0),this.size=new DataView(t.slice(1,5).buffer).getInt32(0,!0);const n=t.slice(5);if(this.jpeg){const e=new Uint8Array(this.jpeg.length+n.length);e.set(this.jpeg,0),e.set(n,this.jpeg.length),this.jpeg=e}else this.jpeg=n,this.receiving=!0,e.Log(e.GetStackTrace(),`received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`,6);this.jpeg.length===this.size?(this.receiving=!1,this.valid=!0,e.Log(e.GetStackTrace(),`received complete freeze frame ${this.size}`,6),this.updateFreezeFrameAndShow(this.jpeg,s)):this.jpeg.length>this.size&&(e.Error(e.GetStackTrace(),`received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`),this.jpeg=void 0,this.receiving=!1)}}class y{constructor(e,t,s,n,r=(()=>{})){this.onChange=r,this.onChangeEmit=()=>{},this.id=e,this.description=s,this.label=t,this.value=n}set label(e){this._label=e,this.onChangeEmit(this._value)}get label(){return this._label}get value(){return this._value}set value(e){this._value=e,this.onChange(this._value,this),this.onChangeEmit(this._value)}}class b extends y{constructor(e,t,s,n,r,i=(()=>{})){super(e,t,s,n,i);const o=new URLSearchParams(window.location.search);if(r&&o.has(this.id)){const e=this.getUrlParamFlag();this.flag=e}else this.flag=n;this.useUrlParams=r}getUrlParamFlag(){const e=new URLSearchParams(window.location.search);return!!e.has(this.id)&&"false"!==e.get(this.id)&&"False"!==e.get(this.id)}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);!0===this.flag?e.set(this.id,"true"):e.set(this.id,"false"),window.history.replaceState({},"",""!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}enable(){this.flag=!0}get flag(){return!!this.value}set flag(e){this.value=e}}class M extends y{constructor(e,t,s,n,r,i,o,a=(()=>{})){super(e,t,s,i,a),this._min=n,this._max=r;const d=new URLSearchParams(window.location.search);if(o&&d.has(this.id)){const e=Number.parseInt(d.get(this.id));this.number=Number.isNaN(e)?i:e}else this.number=i;this.useUrlParams=o}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.number.toString()),window.history.replaceState({},"",""!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}set number(e){this.value=this.clamp(e)}get number(){return this.value}clamp(e){return Math.max(Math.min(this._max,e),this._min)}get min(){return this._min}get max(){return this._max}addOnChangedListener(e){this.onChange=e}}class w extends y{constructor(e,t,s,n,r,i=(()=>{})){super(e,t,s,n,i);const o=new URLSearchParams(window.location.search);if(r&&o.has(this.id)){const e=this.getUrlParamText();this.text=e}else this.text=n;this.useUrlParams=r}getUrlParamText(){var e;const t=new URLSearchParams(window.location.search);return t.has(this.id)&&null!==(e=t.get(this.id))&&void 0!==e?e:""}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.text),window.history.replaceState({},"",""!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}get text(){return this.value}set text(e){this.value=e}}class P extends y{constructor(e,t,s,n,r,i,o=(()=>{})){super(e,t,s,[n,n],o),this.options=r;const a=new URLSearchParams(window.location.search),d=i&&a.has(this.id)?this.getUrlParamText():n;this.selected=d,this.useUrlParams=i}getUrlParamText(){var e;const t=new URLSearchParams(window.location.search);return t.has(this.id)&&null!==(e=t.get(this.id))&&void 0!==e?e:""}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.selected),window.history.replaceState({},"",""!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}addOnChangedListener(e){this.onChange=e}get options(){return this._options}set options(e){this._options=e,this.onChangeEmit(this.selected)}get selected(){return this.value}set selected(e){const t=this.options.filter((t=>-1!==t.indexOf(e)));t.length&&(this.value=t[0])}}class R extends Event{constructor(e){super("afkWarningActivate"),this.data=e}}class k extends Event{constructor(e){super("afkWarningUpdate"),this.data=e}}class L extends Event{constructor(){super("afkWarningDeactivate")}}class x extends Event{constructor(){super("afkTimedOut")}}class A extends Event{constructor(e){super("videoEncoderAvgQP"),this.data=e}}class F extends Event{constructor(){super("webRtcSdp")}}class D extends Event{constructor(){super("webRtcAutoConnect")}}class O extends Event{constructor(){super("webRtcConnecting")}}class U extends Event{constructor(){super("webRtcConnected")}}class G extends Event{constructor(){super("webRtcFailed")}}class I extends Event{constructor(e){super("webRtcDisconnected"),this.data=e}}class z extends Event{constructor(e){super("dataChannelOpen"),this.data=e}}class B extends Event{constructor(e){super("dataChannelClose"),this.data=e}}class _ extends Event{constructor(e){super("dataChannelError"),this.data=e}}class W extends Event{constructor(){super("videoInitialized")}}class H extends Event{constructor(){super("streamLoading")}}class V extends Event{constructor(){super("streamConnect")}}class N extends Event{constructor(){super("streamDisconnect")}}class K extends Event{constructor(){super("streamReconnect")}}class Q extends Event{constructor(e){super("playStreamError"),this.data=e}}class $ extends Event{constructor(){super("playStream")}}class q extends Event{constructor(e){super("playStreamRejected"),this.data=e}}class X extends Event{constructor(e){super("loadFreezeFrame"),this.data=e}}class j extends Event{constructor(){super("hideFreezeFrame")}}class J extends Event{constructor(e){super("statsReceived"),this.data=e}}class Y extends Event{constructor(e){super("streamerListMessage"),this.data=e}}class Z extends Event{constructor(e){super("latencyTestResult"),this.data=e}}class ee extends Event{constructor(e){super("initialSettings"),this.data=e}}class te extends Event{constructor(e){super("settingsChanged"),this.data=e}}class se extends Event{constructor(){super("xrSessionStarted")}}class ne extends Event{constructor(){super("xrSessionEnded")}}class re extends Event{constructor(e){super("xrFrame"),this.data=e}}class ie extends EventTarget{dispatchEvent(e){return super.dispatchEvent(e)}addEventListener(e,t){super.addEventListener(e,t)}removeEventListener(e,t){super.removeEventListener(e,t)}}class oe{}oe.AutoConnect="AutoConnect",oe.AutoPlayVideo="AutoPlayVideo",oe.AFKDetection="TimeoutIfIdle",oe.BrowserSendOffer="OfferToReceive",oe.HoveringMouseMode="HoveringMouse",oe.ForceMonoAudio="ForceMonoAudio",oe.ForceTURN="ForceTURN",oe.FakeMouseWithTouches="FakeMouseWithTouches",oe.IsQualityController="ControlsQuality",oe.MatchViewportResolution="MatchViewportRes",oe.PreferSFU="preferSFU",oe.StartVideoMuted="StartVideoMuted",oe.SuppressBrowserKeys="SuppressBrowserKeys",oe.UseMic="UseMic",oe.KeyboardInput="KeyboardInput",oe.MouseInput="MouseInput",oe.TouchInput="TouchInput",oe.GamepadInput="GamepadInput",oe.XRControllerInput="XRControllerInput";const ae=e=>Object.getOwnPropertyNames(oe).some((t=>oe[t]===e));class de{}de.AFKTimeoutSecs="AFKTimeout",de.MinQP="MinQP",de.MaxQP="MaxQP",de.WebRTCFPS="WebRTCFPS",de.WebRTCMinBitrate="WebRTCMinBitrate",de.WebRTCMaxBitrate="WebRTCMaxBitrate",de.MaxReconnectAttempts="MaxReconnectAttempts";const le=e=>Object.getOwnPropertyNames(de).some((t=>de[t]===e));class ce{}ce.SignallingServerUrl="ss";const he=e=>Object.getOwnPropertyNames(ce).some((t=>ce[t]===e));class ge{}ge.PreferredCodec="PreferredCodec",ge.StreamerId="StreamerId";const ue=e=>Object.getOwnPropertyNames(ge).some((t=>ge[t]===e));class me{constructor(e={}){this.flags=new Map,this.numericParameters=new Map,this.textParameters=new Map,this.optionParameters=new Map;const{initialSettings:t,useUrlParams:s}=e;this._useUrlParams=!!s,this.populateDefaultSettings(this._useUrlParams),t&&this.setSettings(t)}get useUrlParams(){return this._useUrlParams}populateDefaultSettings(e){this.textParameters.set(ce.SignallingServerUrl,new w(ce.SignallingServerUrl,"Signalling url","Url of the signalling server",("https:"===location.protocol?"wss://":"ws://")+window.location.hostname+("80"===window.location.port||""===window.location.port?"":`:${window.location.port}`),e)),this.optionParameters.set(ge.StreamerId,new P(ge.StreamerId,"Streamer ID","The ID of the streamer to stream.","",[],e)),this.optionParameters.set(ge.PreferredCodec,new P(ge.PreferredCodec,"Preferred Codec","The preferred codec to be used during codec negotiation","H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f",function(){const e=[];if(!RTCRtpReceiver.getCapabilities)return e.push("Only available on Chrome"),e;const t=/(VP\d|H26\d|AV1).*/;return RTCRtpReceiver.getCapabilities("video").codecs.forEach((s=>{const n=s.mimeType.split("/")[1]+" "+(s.sdpFmtpLine||"");null!==t.exec(n)&&e.push(n)})),e}(),e)),this.flags.set(oe.AutoConnect,new b(oe.AutoConnect,"Auto connect to stream","Whether we should attempt to auto connect to the signalling server or show a click to start prompt.",!1,e)),this.flags.set(oe.AutoPlayVideo,new b(oe.AutoPlayVideo,"Auto play video","When video is ready automatically start playing it as opposed to showing a play button.",!0,e)),this.flags.set(oe.BrowserSendOffer,new b(oe.BrowserSendOffer,"Browser send offer","Browser will initiate the WebRTC handshake by sending the offer to the streamer",!1,e)),this.flags.set(oe.UseMic,new b(oe.UseMic,"Use microphone","Make browser request microphone access and open an input audio track.",!1,e)),this.flags.set(oe.StartVideoMuted,new b(oe.StartVideoMuted,"Start video muted","Video will start muted if true.",!1,e)),this.flags.set(oe.SuppressBrowserKeys,new b(oe.SuppressBrowserKeys,"Suppress browser keys","Suppress certain browser keys that we use in UE, for example F5 to show shader complexity instead of refresh the page.",!0,e)),this.flags.set(oe.PreferSFU,new b(oe.PreferSFU,"Prefer SFU","Try to connect to the SFU instead of P2P.",!1,e)),this.flags.set(oe.IsQualityController,new b(oe.IsQualityController,"Is quality controller?","True if this peer controls stream quality",!0,e)),this.flags.set(oe.ForceMonoAudio,new b(oe.ForceMonoAudio,"Force mono audio","Force browser to request mono audio in the SDP",!1,e)),this.flags.set(oe.ForceTURN,new b(oe.ForceTURN,"Force TURN","Only generate TURN/Relayed ICE candidates.",!1,e)),this.flags.set(oe.AFKDetection,new b(oe.AFKDetection,"AFK if idle","Timeout the experience if user is AFK for a period.",!1,e)),this.flags.set(oe.MatchViewportResolution,new b(oe.MatchViewportResolution,"Match viewport resolution","Pixel Streaming will be instructed to dynamically resize the video stream to match the size of the video element.",!1,e)),this.flags.set(oe.HoveringMouseMode,new b(oe.HoveringMouseMode,"Control Scheme: Locked Mouse","Either locked mouse, where the pointer is consumed by the video and locked to it, or hovering mouse, where the mouse is not consumed.",!1,e,((e,t)=>{t.label=`Control Scheme: ${e?"Hovering":"Locked"} Mouse`}))),this.flags.set(oe.FakeMouseWithTouches,new b(oe.FakeMouseWithTouches,"Fake mouse with touches","A single finger touch is converted into a mouse event. This allows a non-touch application to be controlled partially via a touch device.",!1,e)),this.flags.set(oe.KeyboardInput,new b(oe.KeyboardInput,"Keyboard input","If enabled, send keyboard events to streamer",!0,e)),this.flags.set(oe.MouseInput,new b(oe.MouseInput,"Mouse input","If enabled, send mouse events to streamer",!0,e)),this.flags.set(oe.TouchInput,new b(oe.TouchInput,"Touch input","If enabled, send touch events to streamer",!0,e)),this.flags.set(oe.GamepadInput,new b(oe.GamepadInput,"Gamepad input","If enabled, send gamepad events to streamer",!0,e)),this.flags.set(oe.XRControllerInput,new b(oe.XRControllerInput,"XR controller input","If enabled, send XR controller events to streamer",!0,e)),this.numericParameters.set(de.AFKTimeoutSecs,new M(de.AFKTimeoutSecs,"AFK timeout","The time (in seconds) it takes for the application to time out if AFK timeout is enabled.",0,600,120,e)),this.numericParameters.set(de.MaxReconnectAttempts,new M(de.MaxReconnectAttempts,"Max Reconnects","Maximum number of reconnects the application will attempt when a streamer disconnects.",0,999,3,e)),this.numericParameters.set(de.MinQP,new M(de.MinQP,"Min QP","The lower bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.",0,51,0,e)),this.numericParameters.set(de.MaxQP,new M(de.MaxQP,"Max QP","The upper bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.",0,51,51,e)),this.numericParameters.set(de.WebRTCFPS,new M(de.WebRTCFPS,"Max FPS","The maximum FPS that WebRTC will try to transmit frames at.",1,999,60,e)),this.numericParameters.set(de.WebRTCMinBitrate,new M(de.WebRTCMinBitrate,"Min Bitrate (kbps)","The minimum bitrate that WebRTC should use.",0,5e5,0,e)),this.numericParameters.set(de.WebRTCMaxBitrate,new M(de.WebRTCMaxBitrate,"Max Bitrate (kbps)","The maximum bitrate that WebRTC should use.",0,5e5,0,e))}_addOnNumericSettingChangedListener(e,t){this.numericParameters.has(e)&&this.numericParameters.get(e).addOnChangedListener(t)}_addOnOptionSettingChangedListener(e,t){this.optionParameters.has(e)&&this.optionParameters.get(e).addOnChangedListener(t)}getNumericSettingValue(e){if(this.numericParameters.has(e))return this.numericParameters.get(e).number;throw new Error(`There is no numeric setting with the id of ${e}`)}getTextSettingValue(e){if(this.textParameters.has(e))return this.textParameters.get(e).value;throw new Error(`There is no numeric setting with the id of ${e}`)}setNumericSetting(e,t){if(!this.numericParameters.has(e))throw new Error(`There is no numeric setting with the id of ${e}`);this.numericParameters.get(e).number=t}_addOnSettingChangedListener(e,t){this.flags.has(e)&&(this.flags.get(e).onChange=t)}_addOnTextSettingChangedListener(e,t){this.textParameters.has(e)&&(this.textParameters.get(e).onChange=t)}getSettingOption(e){return this.optionParameters.get(e)}isFlagEnabled(e){return this.flags.get(e).flag}setFlagEnabled(t,s){this.flags.has(t)?this.flags.get(t).flag=s:e.Warning(e.GetStackTrace(),`Cannot toggle flag called ${t} - it does not exist in the Config.flags map.`)}setTextSetting(t,s){this.textParameters.has(t)?this.textParameters.get(t).text=s:e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.textParameters map.`)}setOptionSettingOptions(t,s){this.optionParameters.has(t)?this.optionParameters.get(t).options=s:e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.optionParameters map.`)}setOptionSettingValue(t,s){this.optionParameters.has(t)?this.optionParameters.get(t).selected=s:e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.enumParameters map.`)}setFlagLabel(t,s){this.flags.has(t)?this.flags.get(t).label=s:e.Warning(e.GetStackTrace(),`Cannot set label for flag called ${t} - it does not exist in the Config.flags map.`)}setSettings(e){for(const t of Object.keys(e))ae(t)?this.setFlagEnabled(t,e[t]):le(t)?this.setNumericSetting(t,e[t]):he(t)?this.setTextSetting(t,e[t]):ue(t)&&this.setOptionSettingValue(t,e[t])}getSettings(){const e={};for(const[t,s]of this.flags.entries())e[t]=s.flag;for(const[t,s]of this.numericParameters.entries())e[t]=s.number;for(const[t,s]of this.textParameters.entries())e[t]=s.text;for(const[t,s]of this.optionParameters.entries())e[t]=s.selected;return e}getFlags(){return Array.from(this.flags.values())}getTextSettings(){return Array.from(this.textParameters.values())}getNumericSettings(){return Array.from(this.numericParameters.values())}getOptionSettings(){return Array.from(this.optionParameters.values())}_registerOnChangeEvents(e){for(const t of this.flags.keys()){const s=this.flags.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new te({id:s.id,type:"flag",value:t,target:s})))}for(const t of this.numericParameters.keys()){const s=this.numericParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new te({id:s.id,type:"number",value:t,target:s})))}for(const t of this.textParameters.keys()){const s=this.textParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new te({id:s.id,type:"text",value:t,target:s})))}for(const t of this.optionParameters.keys()){const s=this.optionParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new te({id:s.id,type:"option",value:t,target:s})))}}}var pe;!function(e){e[e.LockedMouse=0]="LockedMouse",e[e.HoveringMouse=1]="HoveringMouse"}(pe||(pe={}));class Se{constructor(e,t,s){this.closeTimeout=10,this.active=!1,this.countdownActive=!1,this.warnTimer=void 0,this.countDown=0,this.countDownTimer=void 0,this.config=e,this.pixelStreaming=t,this.onDismissAfk=s,this.onAFKTimedOutCallback=()=>{console.log("AFK timed out, did you want to override this callback?")}}onAfkClick(){clearInterval(this.countDownTimer),(this.active||this.countdownActive)&&(this.startAfkWarningTimer(),this.pixelStreaming.dispatchEvent(new L))}startAfkWarningTimer(){this.config.getNumericSettingValue(de.AFKTimeoutSecs)>0&&this.config.isFlagEnabled(oe.AFKDetection)?this.active=!0:this.active=!1,this.resetAfkWarningTimer()}stopAfkWarningTimer(){this.active=!1,this.countdownActive=!1,clearTimeout(this.warnTimer),clearInterval(this.countDownTimer)}pauseAfkWarningTimer(){this.active=!1}resetAfkWarningTimer(){this.active&&this.config.isFlagEnabled(oe.AFKDetection)&&(clearTimeout(this.warnTimer),this.warnTimer=setTimeout((()=>this.activateAfkEvent()),1e3*this.config.getNumericSettingValue(de.AFKTimeoutSecs)))}activateAfkEvent(){this.pauseAfkWarningTimer(),this.pixelStreaming.dispatchEvent(new R({countDown:this.countDown,dismissAfk:this.onDismissAfk})),this.countDown=this.closeTimeout,this.countdownActive=!0,this.pixelStreaming.dispatchEvent(new k({countDown:this.countDown})),this.config.isFlagEnabled(oe.HoveringMouseMode)||document.exitPointerLock&&document.exitPointerLock(),this.countDownTimer=setInterval((()=>{this.countDown--,0==this.countDown?(this.pixelStreaming.dispatchEvent(new x),this.onAFKTimedOutCallback(),e.Log(e.GetStackTrace(),"You have been disconnected due to inactivity"),this.stopAfkWarningTimer()):this.pixelStreaming.dispatchEvent(new k({countDown:this.countDown}))}),1e3)}}class ve{constructor(){this.isReceivingFreezeFrame=!1}getDataChannelInstance(){return this}createDataChannel(e,t,s){this.peerConnection=e,this.label=t,this.datachannelOptions=s,null==s&&(this.datachannelOptions={},this.datachannelOptions.ordered=!0),this.dataChannel=this.peerConnection.createDataChannel(this.label,this.datachannelOptions),this.setupDataChannel()}setupDataChannel(){this.dataChannel.binaryType="arraybuffer",this.dataChannel.onopen=e=>this.handleOnOpen(e),this.dataChannel.onclose=e=>this.handleOnClose(e),this.dataChannel.onmessage=e=>this.handleOnMessage(e),this.dataChannel.onerror=e=>this.handleOnError(e)}handleOnOpen(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) opened.`,7),this.onOpen(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}handleOnClose(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) closed.`,7),this.onClose(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}handleOnMessage(t){e.Log(e.GetStackTrace(),`Data Channel (${this.label}) message: ${t}`,8)}handleOnError(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) error: ${t}`,7),this.onError(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}onOpen(e,t){}onClose(e,t){}onError(e,t){}}class Ce{}class fe{}class Te{}class Ee{}class ye{}class be{}class Me{}class we{}class Pe{constructor(){this.inboundVideoStats=new fe,this.inboundAudioStats=new Ce,this.candidatePair=new ye,this.DataChannelStats=new Te,this.outBoundVideoStats=new be,this.sessionStats=new Me,this.streamStats=new we,this.codecs=new Map}processStats(t){this.localCandidates=new Array,this.remoteCandidates=new Array,t.forEach((t=>{switch(t.type){case"candidate-pair":this.handleCandidatePair(t);break;case"certificate":case"media-source":case"media-playout":case"outbound-rtp":case"peer-connection":case"remote-inbound-rtp":case"transport":break;case"codec":this.handleCodec(t);break;case"data-channel":this.handleDataChannel(t);break;case"inbound-rtp":this.handleInBoundRTP(t);break;case"local-candidate":this.handleLocalCandidate(t);break;case"remote-candidate":this.handleRemoteCandidate(t);break;case"remote-outbound-rtp":this.handleRemoteOutBound(t);break;case"track":this.handleTrack(t);break;case"stream":this.handleStream(t);break;default:e.Error(e.GetStackTrace(),"unhandled Stat Type"),e.Log(e.GetStackTrace(),t)}}))}handleStream(e){this.streamStats=e}handleCandidatePair(e){this.candidatePair.bytesReceived=e.bytesReceived,this.candidatePair.bytesSent=e.bytesSent,this.candidatePair.localCandidateId=e.localCandidateId,this.candidatePair.remoteCandidateId=e.remoteCandidateId,this.candidatePair.nominated=e.nominated,this.candidatePair.readable=e.readable,this.candidatePair.selected=e.selected,this.candidatePair.writable=e.writable,this.candidatePair.state=e.state,this.candidatePair.currentRoundTripTime=e.currentRoundTripTime}handleDataChannel(e){this.DataChannelStats.bytesReceived=e.bytesReceived,this.DataChannelStats.bytesSent=e.bytesSent,this.DataChannelStats.dataChannelIdentifier=e.dataChannelIdentifier,this.DataChannelStats.id=e.id,this.DataChannelStats.label=e.label,this.DataChannelStats.messagesReceived=e.messagesReceived,this.DataChannelStats.messagesSent=e.messagesSent,this.DataChannelStats.protocol=e.protocol,this.DataChannelStats.state=e.state,this.DataChannelStats.timestamp=e.timestamp}handleLocalCandidate(e){const t=new Ee;t.label="local-candidate",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.candidateType=e.candidateType,t.id=e.id,this.localCandidates.push(t)}handleRemoteCandidate(e){const t=new Ee;t.label="local-candidate",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.id=e.id,t.candidateType=e.candidateType,this.remoteCandidates.push(t)}handleInBoundRTP(t){switch(t.kind){case"video":this.inboundVideoStats=t,null!=this.lastVideoStats&&(this.inboundVideoStats.bitrate=8*(this.inboundVideoStats.bytesReceived-this.lastVideoStats.bytesReceived)/(this.inboundVideoStats.timestamp-this.lastVideoStats.timestamp),this.inboundVideoStats.bitrate=Math.floor(this.inboundVideoStats.bitrate)),this.lastVideoStats=Object.assign({},this.inboundVideoStats);break;case"audio":this.inboundAudioStats=t,null!=this.lastAudioStats&&(this.inboundAudioStats.bitrate=8*(this.inboundAudioStats.bytesReceived-this.lastAudioStats.bytesReceived)/(this.inboundAudioStats.timestamp-this.lastAudioStats.timestamp),this.inboundAudioStats.bitrate=Math.floor(this.inboundAudioStats.bitrate)),this.lastAudioStats=Object.assign({},this.inboundAudioStats);break;default:e.Log(e.GetStackTrace(),"Kind is not handled")}}handleRemoteOutBound(e){"video"===e.kind&&(this.outBoundVideoStats.bytesSent=e.bytesSent,this.outBoundVideoStats.id=e.id,this.outBoundVideoStats.localId=e.localId,this.outBoundVideoStats.packetsSent=e.packetsSent,this.outBoundVideoStats.remoteTimestamp=e.remoteTimestamp,this.outBoundVideoStats.timestamp=e.timestamp)}handleTrack(e){"track"!==e.type||"video_label"!==e.trackIdentifier&&"video"!==e.kind||(this.inboundVideoStats.framesDropped=e.framesDropped,this.inboundVideoStats.framesReceived=e.framesReceived,this.inboundVideoStats.frameHeight=e.frameHeight,this.inboundVideoStats.frameWidth=e.frameWidth)}handleCodec(e){const t=e.id,s=`${e.mimeType.replace("video/","").replace("audio/","")}${e.sdpFmtpLine?` ${e.sdpFmtpLine}`:""}`;this.codecs.set(t,s)}handleSessionStatistics(e,t,s){const n=Date.now()-e;this.sessionStats.runTime=new Date(n).toISOString().substr(11,8).toString();const r=null===t?"Not sent yet":t?"true":"false";this.sessionStats.controlsStreamInput=r,this.sessionStats.videoEncoderAvgQP=s}isNumber(e){return"number"==typeof e&&isFinite(e)}}var Re,ke,Le=n(366),xe=function(e,t,s,n){return new(s||(s=Promise))((function(r,i){function o(e){try{d(n.next(e))}catch(e){i(e)}}function a(e){try{d(n.throw(e))}catch(e){i(e)}}function d(e){var t;e.done?r(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}d((n=n.apply(e,t||[])).next())}))};class Ae{constructor(e,t,s){this.config=t,this.createPeerConnection(e,s)}createPeerConnection(t,s){this.config.isFlagEnabled(oe.ForceTURN)&&(t.iceTransportPolicy="relay",e.Log(e.GetStackTrace(),"Forcing TURN usage by setting ICE Transport Policy in peer connection config.")),this.peerConnection=new RTCPeerConnection(t),this.peerConnection.onsignalingstatechange=e=>this.handleSignalStateChange(e),this.peerConnection.oniceconnectionstatechange=e=>this.handleIceConnectionStateChange(e),this.peerConnection.onicegatheringstatechange=e=>this.handleIceGatheringStateChange(e),this.peerConnection.ontrack=e=>this.handleOnTrack(e),this.peerConnection.onicecandidate=e=>this.handleIceCandidate(e),this.peerConnection.ondatachannel=e=>this.handleDataChannel(e),this.aggregatedStats=new Pe,this.preferredCodec=s,this.updateCodecSelection=!0}createOffer(t,s){return xe(this,void 0,void 0,(function*(){e.Log(e.GetStackTrace(),"Create Offer",6);const n="localhost"===location.hostname||"127.0.0.1"===location.hostname,r="https:"===location.protocol;let i=s.isFlagEnabled(oe.UseMic);!i||n||r||(i=!1,e.Error(e.GetStackTrace(),"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access."),e.Error(e.GetStackTrace(),"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'")),this.setupTransceiversAsync(i).finally((()=>{var e;null===(e=this.peerConnection)||void 0===e||e.createOffer(t).then((e=>{var t;this.showTextOverlayConnecting(),e.sdp=this.mungeSDP(e.sdp,i),null===(t=this.peerConnection)||void 0===t||t.setLocalDescription(e),this.onSendWebRTCOffer(e)})).catch((()=>{this.showTextOverlaySetupFailure()}))}))}))}receiveOffer(t,s){var n;return xe(this,void 0,void 0,(function*(){e.Log(e.GetStackTrace(),"Receive Offer",6),null===(n=this.peerConnection)||void 0===n||n.setRemoteDescription(t).then((()=>{const t="localhost"===location.hostname||"127.0.0.1"===location.hostname,n="https:"===location.protocol;let r=s.isFlagEnabled(oe.UseMic);!r||t||n||(r=!1,e.Error(e.GetStackTrace(),"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access."),e.Error(e.GetStackTrace(),"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'")),this.setupTransceiversAsync(r).finally((()=>{var t;null===(t=this.peerConnection)||void 0===t||t.createAnswer().then((e=>{var t;return e.sdp=this.mungeSDP(e.sdp,r),null===(t=this.peerConnection)||void 0===t?void 0:t.setLocalDescription(e)})).then((()=>{var e;this.onSendWebRTCAnswer(null===(e=this.peerConnection)||void 0===e?void 0:e.currentLocalDescription)})).catch((()=>{e.Error(e.GetStackTrace(),"createAnswer() failed")}))}))})),this.config.setOptionSettingOptions(ge.PreferredCodec,this.parseAvailableCodecs(t).filter((e=>this.config.getSettingOption(ge.PreferredCodec).options.includes(e))))}))}receiveAnswer(e){var t;null===(t=this.peerConnection)||void 0===t||t.setRemoteDescription(e),this.config.setOptionSettingOptions(ge.PreferredCodec,this.parseAvailableCodecs(e).filter((e=>this.config.getSettingOption(ge.PreferredCodec).options.includes(e))))}generateStats(){var e;null===(e=this.peerConnection)||void 0===e||e.getStats(null).then((e=>{this.aggregatedStats.processStats(e),this.onVideoStats(this.aggregatedStats),this.updateCodecSelection&&this.config.setOptionSettingValue(ge.PreferredCodec,this.aggregatedStats.codecs.get(this.aggregatedStats.inboundVideoStats.codecId))}))}close(){this.peerConnection&&(this.peerConnection.close(),this.peerConnection=null)}mungeSDP(e,t){const s=e;s.replace(/(a=fmtp:\d+ .*level-asymmetry-allowed=.*)\r\n/gm,"$1;x-google-start-bitrate=10000;x-google-max-bitrate=100000\r\n");let n="";return n+="maxaveragebitrate=510000;",t&&(n+="sprop-maxcapturerate=48000;"),n+=this.config.isFlagEnabled(oe.ForceMonoAudio)?"stereo=0;":"stereo=1;",n+="useinbandfec=1",s.replace("useinbandfec=1",n),s}handleOnIce(t){var s;e.Log(e.GetStackTrace(),"peerconnection handleOnIce",6),this.config.isFlagEnabled(oe.ForceTURN)&&t.candidate.indexOf("relay")<0?e.Info(e.GetStackTrace(),`Dropping candidate because it was not TURN relay. | Type= ${t.type} | Protocol= ${t.protocol} | Address=${t.address} | Port=${t.port} |`,6):null===(s=this.peerConnection)||void 0===s||s.addIceCandidate(t)}handleSignalStateChange(t){e.Log(e.GetStackTrace(),"signaling state change: "+t,6)}handleIceConnectionStateChange(t){e.Log(e.GetStackTrace(),"ice connection state change: "+t,6),this.onIceConnectionStateChange(t)}handleIceGatheringStateChange(t){e.Log(e.GetStackTrace(),"ice gathering state change: "+JSON.stringify(t),6)}handleOnTrack(e){this.onTrack(e)}handleIceCandidate(e){this.onPeerIceCandidate(e)}handleDataChannel(e){this.onDataChannel(e)}onTrack(e){}onIceConnectionStateChange(e){}onPeerIceCandidate(e){}onDataChannel(e){}setupTransceiversAsync(e){var t,s,n,r,i,o,a,d,l;return xe(this,void 0,void 0,(function*(){const c=(null===(t=this.peerConnection)||void 0===t?void 0:t.getTransceivers().length)>0;if(null===(s=this.peerConnection)||void 0===s||s.addTransceiver("video",{direction:"recvonly"}),RTCRtpReceiver.getCapabilities&&""!=this.preferredCodec)for(const e of null!==(r=null===(n=this.peerConnection)||void 0===n?void 0:n.getTransceivers())&&void 0!==r?r:[])if(e&&e.receiver&&e.receiver.track&&"video"===e.receiver.track.kind){const t=this.preferredCodec.split(" "),s=[{mimeType:"video/"+t[0],clockRate:9e4,sdpFmtpLine:t[1]?t[1]:""}];this.config.getSettingOption(ge.PreferredCodec).options.filter((e=>e!=this.preferredCodec)).forEach((e=>{const t=e.split(" ");s.push({mimeType:"video/"+t[0],clockRate:9e4,sdpFmtpLine:t[1]?t[1]:""})}));for(const e of s)""===e.sdpFmtpLine&&delete e.sdpFmtpLine;e.setCodecPreferences(s)}if(e){const t={video:!1,audio:!!e&&{autoGainControl:!1,channelCount:1,echoCancellation:!1,latency:0,noiseSuppression:!1,sampleRate:48e3,sampleSize:16,volume:1}},s=yield navigator.mediaDevices.getUserMedia(t);if(s)if(c){for(const e of null!==(a=null===(o=this.peerConnection)||void 0===o?void 0:o.getTransceivers())&&void 0!==a?a:[])if(e&&e.receiver&&e.receiver.track&&"audio"===e.receiver.track.kind)for(const t of s.getTracks())t.kind&&"audio"==t.kind&&(e.sender.replaceTrack(t),e.direction="sendrecv")}else for(const e of s.getTracks())e.kind&&"audio"==e.kind&&(null===(d=this.peerConnection)||void 0===d||d.addTransceiver(e,{direction:"sendrecv"}));else null===(l=this.peerConnection)||void 0===l||l.addTransceiver("audio",{direction:"recvonly"})}else null===(i=this.peerConnection)||void 0===i||i.addTransceiver("audio",{direction:"recvonly"})}))}onVideoStats(e){}onSendWebRTCOffer(e){}onSendWebRTCAnswer(e){}showTextOverlayConnecting(){}showTextOverlaySetupFailure(){}parseAvailableCodecs(e){if(!RTCRtpReceiver.getCapabilities)return["Only available on Chrome"];const t=[],s=(0,Le.splitSections)(e.sdp);return s.shift(),s.forEach((e=>{const{codecs:s}=(0,Le.parseRtpParameters)(e),n=/(VP\d|H26\d|AV1).*/;s.forEach((e=>{const s=e.name+" "+Object.keys(e.parameters||{}).map((t=>t+"="+e.parameters[t])).join(";");if(null!==n.exec(s)){"VP9"==e.name&&(e.parameters={"profile-id":"0"});const s=e.name+" "+Object.keys(e.parameters||{}).map((t=>t+"="+e.parameters[t])).join(";");t.push(s)}}))})),t}}class Fe{constructor(){this.PixelStreamingSettings=new De,this.EncoderSettings=new Oe,this.WebRTCSettings=new Ue}ueCompatible(){null!=this.WebRTCSettings.MaxFPS&&(this.WebRTCSettings.FPS=this.WebRTCSettings.MaxFPS)}}class De{}class Oe{}class Ue{}class Ge{constructor(){this.ReceiptTimeMs=null,this.TransmissionTimeMs=null,this.PreCaptureTimeMs=null,this.PostCaptureTimeMs=null,this.PreEncodeTimeMs=null,this.PostEncodeTimeMs=null,this.EncodeMs=null,this.CaptureToSendMs=null,this.testStartTimeMs=0,this.browserReceiptTimeMs=0,this.latencyExcludingDecode=0,this.testDuration=0,this.networkLatency=0,this.browserSendLatency=0,this.frameDisplayDeltaTimeMs=0,this.endToEndLatency=0,this.encodeLatency=0}setFrameDisplayDeltaTime(e){0==this.frameDisplayDeltaTimeMs&&(this.frameDisplayDeltaTimeMs=Math.round(e))}processFields(){null!=this.EncodeMs||null==this.PreEncodeTimeMs&&null==this.PostEncodeTimeMs||(e.Log(e.GetStackTrace(),`Setting Encode Ms \n ${this.PostEncodeTimeMs} \n ${this.PreEncodeTimeMs}`,6),this.EncodeMs=this.PostEncodeTimeMs-this.PreEncodeTimeMs),null!=this.CaptureToSendMs||null==this.PreCaptureTimeMs&&null==this.PostCaptureTimeMs||(e.Log(e.GetStackTrace(),`Setting CaptureToSendMs Ms \n ${this.PostCaptureTimeMs} \n ${this.PreCaptureTimeMs}`,6),this.CaptureToSendMs=this.PostCaptureTimeMs-this.PreCaptureTimeMs)}}class Ie{static setExtensionFromBytes(t,s){s.receiving||(s.mimetype="",s.extension="",s.receiving=!0,s.valid=!1,s.size=0,s.data=[],s.timestampStart=(new Date).getTime(),e.Log(e.GetStackTrace(),"Received first chunk of file",6));const n=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),n,6),s.extension=n}static setMimeTypeFromBytes(t,s){s.receiving||(s.mimetype="",s.extension="",s.receiving=!0,s.valid=!1,s.size=0,s.data=[],s.timestampStart=(new Date).getTime(),e.Log(e.GetStackTrace(),"Received first chunk of file",6));const n=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),n,6),s.mimetype=n}static setContentsFromBytes(t,s){if(!s.receiving)return;s.size=Math.ceil(new DataView(t.slice(1,5).buffer).getInt32(0,!0)/16379);const n=t.slice(5);if(s.data.push(n),e.Log(e.GetStackTrace(),`Received file chunk: ${s.data.length}/${s.size}`,6),s.data.length===s.size){s.receiving=!1,s.valid=!0,e.Log(e.GetStackTrace(),"Received complete file",6);const t=(new Date).getTime()-s.timestampStart,n=Math.round(16*s.size*1024/t);e.Log(e.GetStackTrace(),`Average transfer bitrate: ${n}kb/s over ${t/1e3} seconds`,6);const r=new Blob(s.data,{type:s.mimetype}),i=document.createElement("a");i.setAttribute("href",URL.createObjectURL(r)),i.setAttribute("download",`transfer.${s.extension}`),document.body.append(i),i.remove()}else s.data.length>s.size&&(s.receiving=!1,e.Error(e.GetStackTrace(),`Received bigger file than advertised: ${s.data.length}/${s.size}`))}}class ze{constructor(){this.mimetype="",this.extension="",this.receiving=!1,this.size=0,this.data=[],this.valid=!1}}class Be{}Be.mainButton=0,Be.auxiliaryButton=1,Be.secondaryButton=2,Be.fourthButton=3,Be.fifthButton=4;class _e{}_e.primaryButton=1,_e.secondaryButton=2,_e.auxiliaryButton=4,_e.fourthButton=8,_e.fifthButton=16;class We{constructor(){this.unregisterCallbacks=[]}addUnregisterCallback(e){this.unregisterCallbacks.push(e)}unregisterAll(){for(const e of this.unregisterCallbacks)e();this.unregisterCallbacks=[]}}class He{constructor(e,t,s){this.touchEventListenerTracker=new We,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s;const n=e=>this.onTouchStart(e),r=e=>this.onTouchEnd(e),i=e=>this.onTouchMove(e);document.addEventListener("touchstart",n,{passive:!1}),document.addEventListener("touchend",r,{passive:!1}),document.addEventListener("touchmove",i,{passive:!1}),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchstart",n))),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchend",r))),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchmove",i)))}unregisterTouchEvents(){this.touchEventListenerTracker.unregisterAll()}setVideoElementParentClientRect(e){this.videoElementParentClientRect=e}onTouchStart(e){if(this.videoElementProvider.isVideoReady()){if(null==this.fakeTouchFinger){const t=e.changedTouches[0];this.fakeTouchFinger=new Ve(t.identifier,t.clientX-this.videoElementParentClientRect.left,t.clientY-this.videoElementParentClientRect.top);const s=this.videoElementProvider.getVideoParentElement(),n=new MouseEvent("mouseenter",t);s.dispatchEvent(n);const r=this.coordinateConverter.normalizeAndQuantizeUnsigned(this.fakeTouchFinger.x,this.fakeTouchFinger.y);this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([Be.mainButton,r.x,r.y])}e.preventDefault()}}onTouchEnd(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.videoElementProvider.getVideoParentElement(),s=this.toStreamerMessagesProvider.toStreamerHandlers;for(let n=0;n<e.changedTouches.length;n++){const r=e.changedTouches[n];if(r.identifier===this.fakeTouchFinger.id){const e=r.clientX-this.videoElementParentClientRect.left,n=r.clientY-this.videoElementParentClientRect.top,i=this.coordinateConverter.normalizeAndQuantizeUnsigned(e,n);s.get("MouseUp")([Be.mainButton,i.x,i.y]);const o=new MouseEvent("mouseleave",r);t.dispatchEvent(o),this.fakeTouchFinger=null;break}}e.preventDefault()}onTouchMove(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.toStreamerMessagesProvider.toStreamerHandlers;for(let s=0;s<e.touches.length;s++){const n=e.touches[s];if(n.identifier===this.fakeTouchFinger.id){const e=n.clientX-this.videoElementParentClientRect.left,s=n.clientY-this.videoElementParentClientRect.top,r=this.coordinateConverter.normalizeAndQuantizeUnsigned(e,s),i=this.coordinateConverter.normalizeAndQuantizeSigned(e-this.fakeTouchFinger.x,s-this.fakeTouchFinger.y);t.get("MouseMove")([r.x,r.y,i.x,i.y]),this.fakeTouchFinger.x=e,this.fakeTouchFinger.y=s;break}}e.preventDefault()}}class Ve{constructor(e,t,s){this.id=e,this.x=t,this.y=s}}class Ne{}Ne.backSpace=8,Ne.shift=16,Ne.control=17,Ne.alt=18,Ne.rightShift=253,Ne.rightControl=254,Ne.rightAlt=255;class Ke{constructor(e,t,s){this.keyboardEventListenerTracker=new We,this.CodeToKeyCode={Escape:27,Digit0:48,Digit1:49,Digit2:50,Digit3:51,Digit4:52,Digit5:53,Digit6:54,Digit7:55,Digit8:56,Digit9:57,Minus:173,Equal:187,Backspace:8,Tab:9,KeyQ:81,KeyW:87,KeyE:69,KeyR:82,KeyT:84,KeyY:89,KeyU:85,KeyI:73,KeyO:79,KeyP:80,BracketLeft:219,BracketRight:221,Enter:13,ControlLeft:17,KeyA:65,KeyS:83,KeyD:68,KeyF:70,KeyG:71,KeyH:72,KeyJ:74,KeyK:75,KeyL:76,Semicolon:186,Quote:222,Backquote:192,ShiftLeft:16,Backslash:220,KeyZ:90,KeyX:88,KeyC:67,KeyV:86,KeyB:66,KeyN:78,KeyM:77,Comma:188,Period:190,Slash:191,ShiftRight:253,AltLeft:18,Space:32,CapsLock:20,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,Pause:19,ScrollLock:145,NumpadDivide:111,NumpadMultiply:106,NumpadSubtract:109,NumpadAdd:107,NumpadDecimal:110,Numpad9:105,Numpad8:104,Numpad7:103,Numpad6:102,Numpad5:101,Numpad4:100,Numpad3:99,Numpad2:98,Numpad1:97,Numpad0:96,NumLock:144,ControlRight:254,AltRight:255,Home:36,End:35,ArrowUp:38,ArrowLeft:37,ArrowRight:39,ArrowDown:40,PageUp:33,PageDown:34,Insert:45,Delete:46,ContextMenu:93},this.toStreamerMessagesProvider=e,this.config=t,this.activeKeysProvider=s}registerKeyBoardEvents(){const e=e=>this.handleOnKeyDown(e),t=e=>this.handleOnKeyUp(e),s=e=>this.handleOnKeyPress(e);document.addEventListener("keydown",e),document.addEventListener("keyup",t),document.addEventListener("keypress",s),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keydown",e))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keyup",t))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keypress",s)))}unregisterKeyBoardEvents(){this.keyboardEventListenerTracker.unregisterAll()}handleOnKeyDown(t){const s=this.getKeycode(t);s&&(e.Log(e.GetStackTrace(),`key down ${s}, repeat = ${t.repeat}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyDown")([this.getKeycode(t),t.repeat?1:0]),this.activeKeysProvider.getActiveKeys().push(s),s===Ne.backSpace&&document.dispatchEvent(new KeyboardEvent("keypress",{charCode:Ne.backSpace})),this.config.isFlagEnabled(oe.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(s)&&t.preventDefault())}handleOnKeyUp(t){const s=this.getKeycode(t);s&&(e.Log(e.GetStackTrace(),`key up ${s}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyUp")([s,t.repeat?1:0]),this.config.isFlagEnabled(oe.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(s)&&t.preventDefault())}handleOnKeyPress(t){if(!("charCode"in t))return void e.Warning(e.GetStackTrace(),"KeyboardEvent.charCode is deprecated in this browser, cannot send key press.");const s=t.charCode;e.Log(e.GetStackTrace(),`key press ${s}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyPress")([s])}getKeycode(t){if(!("keyCode"in t)){const s=t;return s.code in this.CodeToKeyCode?this.CodeToKeyCode[s.code]:(e.Warning(e.GetStackTrace(),`Keyboard code of ${s.code} is not supported in our mapping, ignoring this key.`),null)}return t.keyCode===Ne.shift&&"ShiftRight"===t.code?Ne.rightShift:t.keyCode===Ne.control&&"ControlRight"===t.code?Ne.rightControl:t.keyCode===Ne.alt&&"AltRight"===t.code?Ne.rightAlt:t.keyCode}isKeyCodeBrowserKey(e){return e>=112&&e<=123||9===e}}class Qe{constructor(e,t,s){this.x=0,this.y=0,this.updateMouseMovePositionEvent=e=>{this.updateMouseMovePosition(e)},this.mouseEventListenerTracker=new We,this.videoElementProvider=e,this.mouseController=t,this.activeKeysProvider=s;const n=this.videoElementProvider.getVideoParentElement();this.x=n.getBoundingClientRect().width/2,this.y=n.getBoundingClientRect().height/2,this.coord=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(this.x,this.y)}unregisterMouseEvents(){this.mouseEventListenerTracker.unregisterAll()}lockStateChange(){const t=this.videoElementProvider.getVideoParentElement(),s=this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;if(document.pointerLockElement===t||document.mozPointerLockElement===t)e.Log(e.GetStackTrace(),"Pointer locked",6),document.addEventListener("mousemove",this.updateMouseMovePositionEvent,!1),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("mousemove",this.updateMouseMovePositionEvent,!1)));else{e.Log(e.GetStackTrace(),"The pointer lock status is now unlocked",6),document.removeEventListener("mousemove",this.updateMouseMovePositionEvent,!1);let t=this.activeKeysProvider.getActiveKeys();const n=new Set(t),r=[];n.forEach((e=>{r[e]})),r.forEach((e=>{s.get("KeyUp")([e])})),t=[]}}updateMouseMovePosition(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.mouseController.toStreamerMessagesProvider.toStreamerHandlers,s=this.videoElementProvider.getVideoParentElement().clientWidth,n=this.videoElementProvider.getVideoParentElement().clientHeight;this.x+=e.movementX,this.y+=e.movementY,this.x>s&&(this.x-=s),this.y>n&&(this.y-=n),this.x<0&&(this.x=s+this.x),this.y<0&&(this.y=n-this.y),this.coord=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(this.x,this.y);const r=this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(e.movementX,e.movementY);t.get("MouseMove")([this.coord.x,this.coord.y,r.x,r.y])}handleMouseDown(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([e.button,this.coord.x,this.coord.y])}handleMouseUp(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([e.button,this.coord.x,this.coord.y])}handleMouseWheel(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseWheel")([e.wheelDelta,this.coord.x,this.coord.y])}handleMouseDouble(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDouble")([e.button,this.coord.x,this.coord.y])}handlePressMouseButtons(e){this.videoElementProvider.isVideoReady()&&this.mouseController.pressMouseButtons(e.buttons,this.x,this.y)}handleReleaseMouseButtons(e){this.videoElementProvider.isVideoReady()&&this.mouseController.releaseMouseButtons(e.buttons,this.x,this.y)}}class $e{constructor(e){this.mouseController=e}unregisterMouseEvents(){}updateMouseMovePosition(t){if(!this.mouseController.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),"MouseMove",6);const s=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(t.offsetX,t.offsetY),n=this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(t.movementX,t.movementY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseMove")([s.x,s.y,n.x,n.y]),t.preventDefault()}handleMouseDown(t){if(!this.mouseController.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),"onMouse Down",6);const s=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(t.offsetX,t.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([t.button,s.x,s.y]),t.preventDefault()}handleMouseUp(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([e.button,t.x,t.y]),e.preventDefault()}handleContextMenu(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([e.button,t.x,t.y]),e.preventDefault()}handleMouseWheel(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseWheel")([e.wheelDelta,t.x,t.y]),e.preventDefault()}handleMouseDouble(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDouble")([e.button,t.x,t.y])}handlePressMouseButtons(e){this.mouseController.videoElementProvider.isVideoReady()&&this.mouseController.pressMouseButtons(e.buttons,e.offsetX,e.offsetY)}handleReleaseMouseButtons(e){this.mouseController.videoElementProvider.isVideoReady()&&this.mouseController.releaseMouseButtons(e.buttons,e.offsetX,e.offsetY)}}class qe{constructor(e,t,s,n){this.mouseEventListenerTracker=new We,this.toStreamerMessagesProvider=e,this.coordinateConverter=s,this.videoElementProvider=t,this.activeKeysProvider=n,this.registerMouseEnterAndLeaveEvents()}unregisterMouseEvents(){this.mouseEventListenerTracker.unregisterAll()}registerLockedMouseEvents(e){const t=this.videoElementProvider.getVideoParentElement(),s=new Qe(this.videoElementProvider,e,this.activeKeysProvider);if(t.requestPointerLock=t.requestPointerLock||t.mozRequestPointerLock,document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock,t.requestPointerLock){const e=()=>{t.requestPointerLock()};t.addEventListener("click",e),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("click",e)))}const n=()=>s.lockStateChange();document.addEventListener("pointerlockchange",n,!1),document.addEventListener("mozpointerlockchange",n,!1),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("pointerlockchange",n,!1))),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("mozpointerlockchange",n,!1)));const r=e=>s.handleMouseDown(e),i=e=>s.handleMouseUp(e),o=e=>s.handleMouseWheel(e),a=e=>s.handleMouseDouble(e);t.addEventListener("mousedown",r),t.addEventListener("mouseup",i),t.addEventListener("wheel",o),t.addEventListener("dblclick",a),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mousedown",r))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseup",i))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("wheel",o))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("dblclick",a))),this.mouseEventListenerTracker.addUnregisterCallback((()=>s.unregisterMouseEvents())),this.mouseEventListenerTracker.addUnregisterCallback((()=>{!document.exitPointerLock||document.pointerLockElement!==t&&document.mozPointerLockElement!==t||document.exitPointerLock()}))}registerHoveringMouseEvents(e){const t=this.videoElementProvider.getVideoParentElement(),s=new $e(e),n=e=>s.updateMouseMovePosition(e),r=e=>s.handleMouseDown(e),i=e=>s.handleMouseUp(e),o=e=>s.handleContextMenu(e),a=e=>s.handleMouseWheel(e),d=e=>s.handleMouseDouble(e);t.addEventListener("mousemove",n),t.addEventListener("mousedown",r),t.addEventListener("mouseup",i),t.addEventListener("contextmenu",o),t.addEventListener("wheel",a),t.addEventListener("dblclick",d),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mousemove",n))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mousedown",r))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseup",i))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("contextmenu",o))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("wheel",a))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("dblclick",d))),this.mouseEventListenerTracker.addUnregisterCallback((()=>s.unregisterMouseEvents()))}registerMouseEnterAndLeaveEvents(){const t=this.videoElementProvider.getVideoParentElement(),s=t=>{this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"Mouse Entered",6),this.sendMouseEnter(),this.pressMouseButtons(t.buttons,t.x,t.y))},n=t=>{this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"Mouse Left",6),this.sendMouseLeave(),this.releaseMouseButtons(t.buttons,t.x,t.y))};t.addEventListener("mouseenter",s),t.addEventListener("mouseleave",n),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseenter",s))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseleave",n)))}releaseMouseButtons(e,t,s){const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&_e.primaryButton&&this.sendMouseUp(Be.mainButton,n.x,n.y),e&_e.secondaryButton&&this.sendMouseUp(Be.secondaryButton,n.x,n.y),e&_e.auxiliaryButton&&this.sendMouseUp(Be.auxiliaryButton,n.x,n.y),e&_e.fourthButton&&this.sendMouseUp(Be.fourthButton,n.x,n.y),e&_e.fifthButton&&this.sendMouseUp(Be.fifthButton,n.x,n.y)}pressMouseButtons(e,t,s){if(!this.videoElementProvider.isVideoReady())return;const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&_e.primaryButton&&this.sendMouseDown(Be.mainButton,n.x,n.y),e&_e.secondaryButton&&this.sendMouseDown(Be.secondaryButton,n.x,n.y),e&_e.auxiliaryButton&&this.sendMouseDown(Be.auxiliaryButton,n.x,n.y),e&_e.fourthButton&&this.sendMouseDown(Be.fourthButton,n.x,n.y),e&_e.fifthButton&&this.sendMouseDown(Be.fifthButton,n.x,n.y)}sendMouseEnter(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseEnter")()}sendMouseLeave(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseLeave")()}sendMouseDown(t,s,n){this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),`mouse button ${t} down at (${s}, ${n})`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([t,s,n]))}sendMouseUp(t,s,n){if(!this.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),`mouse button ${t} up at (${s}, ${n})`,6);const r=this.coordinateConverter.normalizeAndQuantizeUnsigned(s,n);this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([t,r.x,r.y])}}class Xe{constructor(t,s,n){this.fingers=[9,8,7,6,5,4,3,2,1,0],this.fingerIds=new Map,this.maxByteValue=255,this.touchEventListenerTracker=new We,this.toStreamerMessagesProvider=t,this.videoElementProvider=s,this.coordinateConverter=n,this.videoElementParent=s.getVideoElement();const r=e=>this.onTouchStart(e),i=e=>this.onTouchEnd(e),o=e=>this.onTouchMove(e);this.videoElementParent.addEventListener("touchstart",r),this.videoElementParent.addEventListener("touchend",i),this.videoElementParent.addEventListener("touchmove",o),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchstart",r))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchend",i))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchmove",o))),e.Log(e.GetStackTrace(),"Touch Events Registered",6);const a=e=>{e.preventDefault()};document.addEventListener("touchmove",a),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchmove",a)))}unregisterTouchEvents(){this.touchEventListenerTracker.unregisterAll()}rememberTouch(t){const s=this.fingers.pop();void 0===s&&e.Log(e.GetStackTrace(),"exhausted touch identifiers",6),this.fingerIds.set(t.identifier,s)}forgetTouch(e){this.fingers.push(this.fingerIds.get(e.identifier)),this.fingers.sort((function(e,t){return t-e})),this.fingerIds.delete(e.identifier)}onTouchStart(t){if(this.videoElementProvider.isVideoReady()){for(let e=0;e<t.changedTouches.length;e++)this.rememberTouch(t.changedTouches[e]);e.Log(e.GetStackTrace(),"touch start",6),this.emitTouchData("TouchStart",t.changedTouches),t.preventDefault()}}onTouchEnd(t){if(this.videoElementProvider.isVideoReady()){e.Log(e.GetStackTrace(),"touch end",6),this.emitTouchData("TouchEnd",t.changedTouches);for(let e=0;e<t.changedTouches.length;e++)this.forgetTouch(t.changedTouches[e]);t.preventDefault()}}onTouchMove(t){this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"touch move",6),this.emitTouchData("TouchMove",t.touches),t.preventDefault())}emitTouchData(t,s){if(!this.videoElementProvider.isVideoReady())return;const n=this.videoElementProvider.getVideoParentElement(),r=this.toStreamerMessagesProvider.toStreamerHandlers;for(let i=0;i<s.length;i++){const o=1,a=s[i],d=a.clientX-n.offsetLeft,l=a.clientY-n.offsetTop;e.Log(e.GetStackTrace(),`F${this.fingerIds.get(a.identifier)}=(${d}, ${l})`,6);const c=this.coordinateConverter.normalizeAndQuantizeUnsigned(d,l);switch(t){case"TouchStart":r.get("TouchStart")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0]);break;case"TouchEnd":r.get("TouchEnd")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0]);break;case"TouchMove":r.get("TouchMove")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0])}}}}class je{constructor(e){this.gamePadEventListenerTracker=new We,this.toStreamerMessagesProvider=e,this.requestAnimationFrame=(window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.requestAnimationFrame).bind(window);const t=window;if("GamepadEvent"in t){const e=e=>this.gamePadConnectHandler(e),t=e=>this.gamePadDisconnectHandler(e);window.addEventListener("gamepadconnected",e),window.addEventListener("gamepaddisconnected",t),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener("gamepadconnected",e))),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener("gamepaddisconnected",t)))}else if("WebKitGamepadEvent"in t){const e=e=>this.gamePadConnectHandler(e),t=e=>this.gamePadDisconnectHandler(e);window.addEventListener("webkitgamepadconnected",e),window.addEventListener("webkitgamepaddisconnected",t),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener("webkitgamepadconnected",e))),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener("webkitgamepaddisconnected",t)))}if(this.controllers=[],navigator.getGamepads)for(const e of navigator.getGamepads())e&&this.gamePadConnectHandler(new GamepadEvent("gamepadconnected",{gamepad:e}))}unregisterGamePadEvents(){this.gamePadEventListenerTracker.unregisterAll();for(const e of this.controllers)void 0!==e.id&&this.onGamepadDisconnected(e.id);this.controllers=[],this.onGamepadConnected=()=>{},this.onGamepadDisconnected=()=>{}}gamePadConnectHandler(t){e.Log(e.GetStackTrace(),"Gamepad connect handler",6);const s=t.gamepad,n={currentState:s,prevState:s,id:void 0};this.controllers.push(n),this.controllers[s.index].currentState=s,this.controllers[s.index].prevState=s,e.Log(e.GetStackTrace(),"gamepad: "+s.id+" connected",6),window.requestAnimationFrame((()=>this.updateStatus())),this.onGamepadConnected()}gamePadDisconnectHandler(t){e.Log(e.GetStackTrace(),"Gamepad disconnect handler",6),e.Log(e.GetStackTrace(),"gamepad: "+t.gamepad.id+" disconnected",6);const s=this.controllers[t.gamepad.index];delete this.controllers[t.gamepad.index],this.controllers=this.controllers.filter((e=>void 0!==e)),this.onGamepadDisconnected(s.id)}scanGamePads(){const e=navigator.getGamepads?navigator.getGamepads():navigator.webkitGetGamepads?navigator.webkitGetGamepads():[];for(let t=0;t<e.length;t++)e[t]&&e[t].index in this.controllers&&(this.controllers[e[t].index].currentState=e[t])}updateStatus(){this.scanGamePads();const e=this.toStreamerMessagesProvider.toStreamerHandlers;for(const t of this.controllers){const s=void 0===t.id?this.controllers.indexOf(t):t.id,n=t.currentState;for(let n=0;n<t.currentState.buttons.length;n++){const r=t.currentState.buttons[n],i=t.prevState.buttons[n];r.pressed?n==Re.LeftTrigger?e.get("GamepadAnalog")([s,5,r.value]):n==Re.RightTrigger?e.get("GamepadAnalog")([s,6,r.value]):e.get("GamepadButtonPressed")([s,n,i.pressed?1:0]):!r.pressed&&i.pressed&&(n==Re.LeftTrigger?e.get("GamepadAnalog")([s,5,0]):n==Re.RightTrigger?e.get("GamepadAnalog")([s,6,0]):e.get("GamepadButtonReleased")([s,n]))}for(let t=0;t<n.axes.length;t+=2){const r=parseFloat(n.axes[t].toFixed(4)),i=-parseFloat(n.axes[t+1].toFixed(4));e.get("GamepadAnalog")([s,t+1,r]),e.get("GamepadAnalog")([s,t+2,i])}this.controllers[s].prevState=n}this.controllers.length>0&&this.requestAnimationFrame((()=>this.updateStatus()))}onGamepadResponseReceived(e){for(const t of this.controllers)if(void 0===t.id){t.id=e;break}}onGamepadConnected(){}onGamepadDisconnected(e){}}!function(e){e[e.RightClusterBottomButton=0]="RightClusterBottomButton",e[e.RightClusterRightButton=1]="RightClusterRightButton",e[e.RightClusterLeftButton=2]="RightClusterLeftButton",e[e.RightClusterTopButton=3]="RightClusterTopButton",e[e.LeftShoulder=4]="LeftShoulder",e[e.RightShoulder=5]="RightShoulder",e[e.LeftTrigger=6]="LeftTrigger",e[e.RightTrigger=7]="RightTrigger",e[e.SelectOrBack=8]="SelectOrBack",e[e.StartOrForward=9]="StartOrForward",e[e.LeftAnalogPress=10]="LeftAnalogPress",e[e.RightAnalogPress=11]="RightAnalogPress",e[e.LeftClusterTopButton=12]="LeftClusterTopButton",e[e.LeftClusterBottomButton=13]="LeftClusterBottomButton",e[e.LeftClusterLeftButton=14]="LeftClusterLeftButton",e[e.LeftClusterRightButton=15]="LeftClusterRightButton",e[e.CentreButton=16]="CentreButton",e[e.LeftStickHorizontal=0]="LeftStickHorizontal",e[e.LeftStickVertical=1]="LeftStickVertical",e[e.RightStickHorizontal=2]="RightStickHorizontal",e[e.RightStickVertical=3]="RightStickVertical"}(Re||(Re={}));class Je{constructor(e,t,s){this.activeKeys=new Ye,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s}registerKeyBoard(t){e.Log(e.GetStackTrace(),"Register Keyboard Events",7);const s=new Ke(this.toStreamerMessagesProvider,t,this.activeKeys);return s.registerKeyBoardEvents(),s}registerMouse(t){e.Log(e.GetStackTrace(),"Register Mouse Events",7);const s=new qe(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter,this.activeKeys);switch(t){case pe.LockedMouse:s.registerLockedMouseEvents(s);break;case pe.HoveringMouse:s.registerHoveringMouseEvents(s);break;default:e.Info(e.GetStackTrace(),"unknown Control Scheme Type Defaulting to Locked Mouse Events"),s.registerLockedMouseEvents(s)}return s}registerTouch(t,s){if(e.Log(e.GetStackTrace(),"Registering Touch",6),t){const e=new He(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter);return e.setVideoElementParentClientRect(s),e}return new Xe(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter)}registerGamePad(){return e.Log(e.GetStackTrace(),"Register Game Pad",7),new je(this.toStreamerMessagesProvider)}}class Ye{constructor(){this.activeKeys=[],this.activeKeys=[]}getActiveKeys(){return this.activeKeys}}class Ze{constructor(e,t){this.lastTimeResized=(new Date).getTime(),this.videoElement=document.createElement("video"),this.config=t,this.videoElement.id="streamingVideo",this.videoElement.disablePictureInPicture=!0,this.videoElement.playsInline=!0,this.videoElement.style.width="100%",this.videoElement.style.height="100%",this.videoElement.style.position="absolute",this.videoElement.style.pointerEvents="all",e.appendChild(this.videoElement),this.onResizePlayerCallback=()=>{console.log("Resolution changed, restyling player, did you forget to override this function?")},this.onMatchViewportResolutionCallback=()=>{console.log("Resolution changed and match viewport resolution is turned on, did you forget to override this function?")},this.videoElement.onclick=()=>{this.videoElement.paused&&this.videoElement.play()},this.videoElement.onloadedmetadata=()=>{this.onVideoInitialized()},window.addEventListener("resize",(()=>this.resizePlayerStyle()),!0),window.addEventListener("orientationchange",(()=>this.onOrientationChange()))}play(){return this.videoElement.muted=this.config.isFlagEnabled(oe.StartVideoMuted),this.videoElement.autoplay=this.config.isFlagEnabled(oe.AutoPlayVideo),this.videoElement.play()}isPaused(){return this.videoElement.paused}isVideoReady(){return void 0!==this.videoElement.readyState&&this.videoElement.readyState>0}hasVideoSource(){return void 0!==this.videoElement.srcObject&&null!==this.videoElement.srcObject}getVideoElement(){return this.videoElement}getVideoParentElement(){return this.videoElement.parentElement}setVideoEnabled(e){this.videoElement.srcObject.getTracks().forEach((t=>t.enabled=e))}onVideoInitialized(){}onOrientationChange(){clearTimeout(this.orientationChangeTimeout),this.orientationChangeTimeout=window.setTimeout((()=>{this.resizePlayerStyle()}),500)}resizePlayerStyle(){const e=this.getVideoParentElement();e&&(this.updateVideoStreamSize(),e.classList.contains("fixed-size")||this.resizePlayerStyleToFillParentElement(),this.onResizePlayerCallback())}resizePlayerStyleToFillParentElement(){this.getVideoParentElement().setAttribute("style","top: 0px; left: 0px; width: 100%; height: 100%; cursor: default;")}updateVideoStreamSize(){if(this.config.isFlagEnabled(oe.MatchViewportResolution))if((new Date).getTime()-this.lastTimeResized>300){const e=this.getVideoParentElement();if(!e)return;this.onMatchViewportResolutionCallback(e.clientWidth,e.clientHeight),this.lastTimeResized=(new Date).getTime()}else e.Log(e.GetStackTrace(),"Resizing too often - skipping",6),clearTimeout(this.resizeTimeoutHandle),this.resizeTimeoutHandle=window.setTimeout((()=>this.updateVideoStreamSize()),100)}}class et{constructor(){this.map=new Map,this.reverseMap=new Map}getFromKey(e){return this.map.get(e)}getFromValue(e){return this.reverseMap.get(e)}add(e,t){this.map.set(e,t),this.reverseMap.set(t,e)}remove(e,t){this.map.delete(e),this.reverseMap.delete(t)}}class tt{constructor(){this.toStreamerHandlers=new Map,this.fromStreamerHandlers=new Map,this.toStreamerMessages=new et,this.fromStreamerMessages=new et}populateDefaultProtocol(){this.toStreamerMessages.add("IFrameRequest",{id:0,byteLength:0,structure:[]}),this.toStreamerMessages.add("RequestQualityControl",{id:1,byteLength:0,structure:[]}),this.toStreamerMessages.add("FpsRequest",{id:2,byteLength:0,structure:[]}),this.toStreamerMessages.add("AverageBitrateRequest",{id:3,byteLength:0,structure:[]}),this.toStreamerMessages.add("StartStreaming",{id:4,byteLength:0,structure:[]}),this.toStreamerMessages.add("StopStreaming",{id:5,byteLength:0,structure:[]}),this.toStreamerMessages.add("LatencyTest",{id:6,byteLength:0,structure:[]}),this.toStreamerMessages.add("RequestInitialSettings",{id:7,byteLength:0,structure:[]}),this.toStreamerMessages.add("TestEcho",{id:8,byteLength:0,structure:[]}),this.toStreamerMessages.add("UIInteraction",{id:50,byteLength:0,structure:[]}),this.toStreamerMessages.add("Command",{id:51,byteLength:0,structure:[]}),this.toStreamerMessages.add("KeyDown",{id:60,byteLength:2,structure:["uint8","uint8"]}),this.toStreamerMessages.add("KeyUp",{id:61,byteLength:1,structure:["uint8"]}),this.toStreamerMessages.add("KeyPress",{id:62,byteLength:2,structure:["uint16"]}),this.toStreamerMessages.add("MouseEnter",{id:70,byteLength:0,structure:[]}),this.toStreamerMessages.add("MouseLeave",{id:71,byteLength:0,structure:[]}),this.toStreamerMessages.add("MouseDown",{id:72,byteLength:5,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.add("MouseUp",{id:73,byteLength:5,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.add("MouseMove",{id:74,byteLength:8,structure:["uint16","uint16","int16","int16"]}),this.toStreamerMessages.add("MouseWheel",{id:75,byteLength:6,structure:["int16","uint16","uint16"]}),this.toStreamerMessages.add("MouseDouble",{id:76,byteLength:5,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.add("TouchStart",{id:80,byteLength:8,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.add("TouchEnd",{id:81,byteLength:8,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.add("TouchMove",{id:82,byteLength:8,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.add("GamepadConnected",{id:93,byteLength:0,structure:[]}),this.toStreamerMessages.add("GamepadButtonPressed",{id:90,byteLength:3,structure:["uint8","uint8","uint8"]}),this.toStreamerMessages.add("GamepadButtonReleased",{id:91,byteLength:3,structure:["uint8","uint8","uint8"]}),this.toStreamerMessages.add("GamepadAnalog",{id:92,byteLength:10,structure:["uint8","uint8","double"]}),this.toStreamerMessages.add("GamepadDisconnected",{id:94,byteLength:1,structure:["uint8"]}),this.fromStreamerMessages.add("QualityControlOwnership",0),this.fromStreamerMessages.add("Response",1),this.fromStreamerMessages.add("Command",2),this.fromStreamerMessages.add("FreezeFrame",3),this.fromStreamerMessages.add("UnfreezeFrame",4),this.fromStreamerMessages.add("VideoEncoderAvgQP",5),this.fromStreamerMessages.add("LatencyTest",6),this.fromStreamerMessages.add("InitialSettings",7),this.fromStreamerMessages.add("FileExtension",8),this.fromStreamerMessages.add("FileMimeType",9),this.fromStreamerMessages.add("FileContents",10),this.fromStreamerMessages.add("TestEcho",11),this.fromStreamerMessages.add("InputControlOwnership",12),this.fromStreamerMessages.add("GamepadResponse",13),this.fromStreamerMessages.add("Protocol",255)}registerMessageHandler(t,s,n){switch(t){case ke.ToStreamer:this.toStreamerHandlers.set(s,n);break;case ke.FromStreamer:this.fromStreamerHandlers.set(s,n);break;default:e.Log(e.GetStackTrace(),`Unknown message direction ${t}`)}}}!function(e){e[e.ToStreamer=0]="ToStreamer",e[e.FromStreamer=1]="FromStreamer"}(ke||(ke={}));class st{constructor(){this.responseEventListeners=new Map}addResponseEventListener(e,t){this.responseEventListeners.set(e,t)}removeResponseEventListener(e){this.responseEventListeners.delete(e)}onResponse(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.Response",6);const s=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),s,6),this.responseEventListeners.forEach((e=>{e(s)}))}}class nt{constructor(e,t){this.dataChannelSender=e,this.toStreamerMessagesMapProvider=t}sendLatencyTest(e){this.sendDescriptor("LatencyTest",e)}emitCommand(e){this.sendDescriptor("Command",e)}emitUIInteraction(e){this.sendDescriptor("UIInteraction",e)}sendDescriptor(t,s){const n=JSON.stringify(s),r=this.toStreamerMessagesMapProvider.toStreamerMessages.getFromKey(t);void 0===r&&e.Error(e.GetStackTrace(),`Attempted to emit descriptor with message type: ${t}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`),e.Log(e.GetStackTrace(),"Sending: "+s,6);const i=new DataView(new ArrayBuffer(3+2*n.length));let o=0;i.setUint8(o,r.id),o++,i.setUint16(o,n.length,!0),o+=2;for(let e=0;e<n.length;e++)i.setUint16(o,n.charCodeAt(e),!0),o+=2;this.dataChannelSender.canSend()?this.dataChannelSender.sendData(i.buffer):e.Info(e.GetStackTrace(),`Data channel cannot send yet, skipping sending descriptor message: ${t} - ${n}`)}}class rt{constructor(e,t){this.dataChannelSender=e,this.toStreamerMessagesMapProvider=t}sendMessageToStreamer(t,s){void 0===s&&(s=[]);const n=this.toStreamerMessagesMapProvider.toStreamerMessages.getFromKey(t);if(void 0===n)return void e.Error(e.GetStackTrace(),`Attempted to send a message to the streamer with message type: ${t}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`);const r=new DataView(new ArrayBuffer(n.byteLength+1));r.setUint8(0,n.id);let i=1;s.forEach(((e,t)=>{switch(n.structure[t]){case"uint8":r.setUint8(i,e),i+=1;break;case"uint16":r.setUint16(i,e,!0),i+=2;break;case"int16":r.setInt16(i,e,!0),i+=2;break;case"float":r.setFloat32(i,e,!0),i+=4;break;case"double":r.setFloat64(i,e,!0),i+=8}})),this.dataChannelSender.canSend()?this.dataChannelSender.sendData(r.buffer):e.Info(e.GetStackTrace(),`Data channel cannot send yet, skipping sending message: ${t} - ${new Uint8Array(r.buffer)}`)}}class it{constructor(e){this.sendMessageController=e}SendRequestQualityControl(){this.sendMessageController.sendMessageToStreamer("RequestQualityControl")}SendMaxFpsRequest(){this.sendMessageController.sendMessageToStreamer("FpsRequest")}SendAverageBitrateRequest(){this.sendMessageController.sendMessageToStreamer("AverageBitrateRequest")}SendStartStreaming(){this.sendMessageController.sendMessageToStreamer("StartStreaming")}SendStopStreaming(){this.sendMessageController.sendMessageToStreamer("StopStreaming")}SendRequestInitialSettings(){this.sendMessageController.sendMessageToStreamer("RequestInitialSettings")}}class ot{constructor(e){this.dataChannelProvider=e}canSend(){return void 0!==this.dataChannelProvider.getDataChannelInstance().dataChannel&&"open"==this.dataChannelProvider.getDataChannelInstance().dataChannel.readyState}sendData(t){const s=this.dataChannelProvider.getDataChannelInstance();"open"==s.dataChannel.readyState?(s.dataChannel.send(t),e.Log(e.GetStackTrace(),`Message Sent: ${new Uint8Array(t)}`,6),this.resetAfkWarningTimerOnDataSend()):e.Error(e.GetStackTrace(),`Message Failed: ${new Uint8Array(t)}`)}resetAfkWarningTimerOnDataSend(){}}class at{constructor(e){this.videoElementProvider=e,this.normalizeAndQuantizeUnsignedFunc=()=>{throw new Error("Normalize and quantize unsigned, method not implemented.")},this.normalizeAndQuantizeSignedFunc=()=>{throw new Error("Normalize and unquantize signed, method not implemented.")},this.denormalizeAndUnquantizeUnsignedFunc=()=>{throw new Error("Denormalize and unquantize unsigned, method not implemented.")}}normalizeAndQuantizeUnsigned(e,t){return this.normalizeAndQuantizeUnsignedFunc(e,t)}unquantizeAndDenormalizeUnsigned(e,t){return this.denormalizeAndUnquantizeUnsignedFunc(e,t)}normalizeAndQuantizeSigned(e,t){return this.normalizeAndQuantizeSignedFunc(e,t)}setupNormalizeAndQuantize(){if(this.videoElementParent=this.videoElementProvider.getVideoParentElement(),this.videoElement=this.videoElementProvider.getVideoElement(),this.videoElementParent&&this.videoElement){const t=this.videoElementParent.clientHeight/this.videoElementParent.clientWidth,s=this.videoElement.videoHeight/this.videoElement.videoWidth;t>s?(e.Log(e.GetStackTrace(),"Setup Normalize and Quantize for playerAspectRatio > videoAspectRatio",6),this.ratio=t/s,this.normalizeAndQuantizeUnsignedFunc=(e,t)=>this.normalizeAndQuantizeUnsignedPlayerBigger(e,t),this.normalizeAndQuantizeSignedFunc=(e,t)=>this.normalizeAndQuantizeSignedPlayerBigger(e,t),this.denormalizeAndUnquantizeUnsignedFunc=(e,t)=>this.denormalizeAndUnquantizeUnsignedPlayerBigger(e,t)):(e.Log(e.GetStackTrace(),"Setup Normalize and Quantize for playerAspectRatio <= videoAspectRatio",6),this.ratio=s/t,this.normalizeAndQuantizeUnsignedFunc=(e,t)=>this.normalizeAndQuantizeUnsignedPlayerSmaller(e,t),this.normalizeAndQuantizeSignedFunc=(e,t)=>this.normalizeAndQuantizeSignedPlayerSmaller(e,t),this.denormalizeAndUnquantizeUnsignedFunc=(e,t)=>this.denormalizeAndUnquantizeUnsignedPlayerSmaller(e,t))}}normalizeAndQuantizeUnsignedPlayerBigger(e,t){const s=e/this.videoElementParent.clientWidth,n=this.ratio*(t/this.videoElementParent.clientHeight-.5)+.5;return s<0||s>1||n<0||n>1?new dt(!1,65535,65535):new dt(!0,65536*s,65536*n)}denormalizeAndUnquantizeUnsignedPlayerBigger(e,t){const s=e/65536,n=(t/65536-.5)/this.ratio+.5;return new lt(s*this.videoElementParent.clientWidth,n*this.videoElementParent.clientHeight)}normalizeAndQuantizeSignedPlayerBigger(e,t){const s=e/(.5*this.videoElementParent.clientWidth),n=this.ratio*t/(.5*this.videoElementParent.clientHeight);return new ct(32767*s,32767*n)}normalizeAndQuantizeUnsignedPlayerSmaller(e,t){const s=this.ratio*(e/this.videoElementParent.clientWidth-.5)+.5,n=t/this.videoElementParent.clientHeight;return s<0||s>1||n<0||n>1?new dt(!1,65535,65535):new dt(!0,65536*s,65536*n)}denormalizeAndUnquantizeUnsignedPlayerSmaller(e,t){const s=(e/65536-.5)/this.ratio+.5,n=t/65536;return new lt(s*this.videoElementParent.clientWidth,n*this.videoElementParent.clientHeight)}normalizeAndQuantizeSignedPlayerSmaller(e,t){const s=this.ratio*e/(.5*this.videoElementParent.clientWidth),n=t/(.5*this.videoElementParent.clientHeight);return new ct(32767*s,32767*n)}}class dt{constructor(e,t,s){this.inRange=e,this.x=t,this.y=s}}class lt{constructor(e,t){this.x=e,this.y=t}}class ct{constructor(e,t){this.x=e,this.y=t}}class ht{constructor(e,t){this.shouldShowPlayOverlay=!0,this.config=e,this.pixelStreaming=t,this.responseController=new st,this.file=new ze,this.sdpConstraints={offerToReceiveAudio:!0,offerToReceiveVideo:!0},this.afkController=new Se(this.config,this.pixelStreaming,this.onAfkTriggered.bind(this)),this.afkController.onAFKTimedOutCallback=()=>{this.setDisconnectMessageOverride("You have been disconnected due to inactivity"),this.closeSignalingServer()},this.freezeFrameController=new E(this.pixelStreaming.videoElementParent),this.videoPlayer=new Ze(this.pixelStreaming.videoElementParent,this.config),this.videoPlayer.onVideoInitialized=()=>this.handleVideoInitialized(),this.videoPlayer.onMatchViewportResolutionCallback=(e,t)=>{const s={"Resolution.Width":e,"Resolution.Height":t};this.sendDescriptorController.emitCommand(s)},this.videoPlayer.onResizePlayerCallback=()=>{this.setUpMouseAndFreezeFrame()},this.streamController=new f(this.videoPlayer),this.coordinateConverter=new at(this.videoPlayer),this.sendrecvDataChannelController=new ve,this.recvDataChannelController=new ve,this.registerDataChannelEventEmitters(this.sendrecvDataChannelController),this.registerDataChannelEventEmitters(this.recvDataChannelController),this.dataChannelSender=new ot(this.sendrecvDataChannelController),this.dataChannelSender.resetAfkWarningTimerOnDataSend=()=>this.afkController.resetAfkWarningTimer(),this.streamMessageController=new tt,this.webSocketController=new C,this.webSocketController.onConfig=e=>this.handleOnConfigMessage(e),this.webSocketController.onStreamerList=e=>this.handleStreamerListMessage(e),this.webSocketController.onWebSocketOncloseOverlayMessage=e=>{this.pixelStreaming._onDisconnect(`Websocket disconnect (${e.code}) ${""!=e.reason?"- "+e.reason:""}`),this.setVideoEncoderAvgQP(0)},this.webSocketController.onOpen.addEventListener("open",(()=>{this.config.isFlagEnabled(oe.BrowserSendOffer)||this.webSocketController.requestStreamerList()})),this.webSocketController.onClose.addEventListener("close",(e=>{this.afkController.stopAfkWarningTimer(),this.statsTimerHandle&&void 0!==this.statsTimerHandle&&window.clearInterval(this.statsTimerHandle),this.setTouchInputEnabled(!1),this.setMouseInputEnabled(!1),this.setKeyboardInputEnabled(!1),this.setGamePadInputEnabled(!1),this.shouldReconnect&&1001!=e.detail.code&&this.config.getNumericSettingValue(de.MaxReconnectAttempts)>0&&(this.isReconnecting=!0,this.reconnectAttempt++,this.restartStreamAutomatically())})),this.sendDescriptorController=new nt(this.dataChannelSender,this.streamMessageController),this.sendMessageController=new rt(this.dataChannelSender,this.streamMessageController),this.toStreamerMessagesController=new it(this.sendMessageController),this.registerMessageHandlers(),this.streamMessageController.populateDefaultProtocol(),this.inputClassesFactory=new Je(this.streamMessageController,this.videoPlayer,this.coordinateConverter),this.isUsingSFU=!1,this.isQualityController=!1,this.preferredCodec="",this.shouldReconnect=!0,this.isReconnecting=!1,this.reconnectAttempt=0,this.config._addOnOptionSettingChangedListener(ge.StreamerId,(e=>{""!==e&&(this.peerConnectionController.peerConnection.close(),this.peerConnectionController.createPeerConnection(this.peerConfig,this.preferredCodec),this.subscribedStream=e,this.webSocketController.sendSubscribe(e))})),this.setVideoEncoderAvgQP(-1),this.signallingUrlBuilder=()=>{let e=this.config.getTextSettingValue(ce.SignallingServerUrl);return this.config.isFlagEnabled(oe.BrowserSendOffer)&&(e+="?"+oe.BrowserSendOffer+"=true"),e}}requestUnquantizedAndDenormalizeUnsigned(e,t){return this.coordinateConverter.unquantizeAndDenormalizeUnsigned(e,t)}handleOnMessage(t){const s=new Uint8Array(t.data);e.Log(e.GetStackTrace(),"Message incoming:"+s,6);const n=this.streamMessageController.fromStreamerMessages.getFromValue(s[0]);this.streamMessageController.fromStreamerHandlers.get(n)(t.data)}registerMessageHandlers(){this.streamMessageController.registerMessageHandler(ke.FromStreamer,"QualityControlOwnership",(e=>this.onQualityControlOwnership(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"Response",(e=>this.responseController.onResponse(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"Command",(e=>{this.onCommand(e)})),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"FreezeFrame",(e=>this.onFreezeFrameMessage(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"UnfreezeFrame",(()=>this.invalidateFreezeFrameAndEnableVideo())),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"VideoEncoderAvgQP",(e=>this.handleVideoEncoderAvgQP(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"LatencyTest",(e=>this.handleLatencyTestResult(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"InitialSettings",(e=>this.handleInitialSettings(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"FileExtension",(e=>this.onFileExtension(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"FileMimeType",(e=>this.onFileMimeType(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"FileContents",(e=>this.onFileContents(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"TestEcho",(()=>{})),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"InputControlOwnership",(e=>this.onInputControlOwnership(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"GamepadResponse",(e=>this.onGamepadResponse(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"Protocol",(e=>this.onProtocolMessage(e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"IFrameRequest",(()=>this.sendMessageController.sendMessageToStreamer("IFrameRequest"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"RequestQualityControl",(()=>this.sendMessageController.sendMessageToStreamer("RequestQualityControl"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"FpsRequest",(()=>this.sendMessageController.sendMessageToStreamer("FpsRequest"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"AverageBitrateRequest",(()=>this.sendMessageController.sendMessageToStreamer("AverageBitrateRequest"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"StartStreaming",(()=>this.sendMessageController.sendMessageToStreamer("StartStreaming"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"StopStreaming",(()=>this.sendMessageController.sendMessageToStreamer("StopStreaming"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"LatencyTest",(()=>this.sendMessageController.sendMessageToStreamer("LatencyTest"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"RequestInitialSettings",(()=>this.sendMessageController.sendMessageToStreamer("RequestInitialSettings"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"TestEcho",(()=>{})),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"UIInteraction",(e=>this.sendDescriptorController.emitUIInteraction(e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"Command",(e=>this.sendDescriptorController.emitCommand(e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"KeyDown",(e=>this.sendMessageController.sendMessageToStreamer("KeyDown",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"KeyUp",(e=>this.sendMessageController.sendMessageToStreamer("KeyUp",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"KeyPress",(e=>this.sendMessageController.sendMessageToStreamer("KeyPress",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseEnter",(e=>this.sendMessageController.sendMessageToStreamer("MouseEnter",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseLeave",(e=>this.sendMessageController.sendMessageToStreamer("MouseLeave",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseDown",(e=>this.sendMessageController.sendMessageToStreamer("MouseDown",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseUp",(e=>this.sendMessageController.sendMessageToStreamer("MouseUp",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseMove",(e=>this.sendMessageController.sendMessageToStreamer("MouseMove",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseWheel",(e=>this.sendMessageController.sendMessageToStreamer("MouseWheel",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseDouble",(e=>this.sendMessageController.sendMessageToStreamer("MouseDouble",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"TouchStart",(e=>this.sendMessageController.sendMessageToStreamer("TouchStart",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"TouchEnd",(e=>this.sendMessageController.sendMessageToStreamer("TouchEnd",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"TouchMove",(e=>this.sendMessageController.sendMessageToStreamer("TouchMove",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadConnected",(()=>this.sendMessageController.sendMessageToStreamer("GamepadConnected"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadButtonPressed",(e=>this.sendMessageController.sendMessageToStreamer("GamepadButtonPressed",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadButtonReleased",(e=>this.sendMessageController.sendMessageToStreamer("GamepadButtonReleased",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadAnalog",(e=>this.sendMessageController.sendMessageToStreamer("GamepadAnalog",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadDisconnected",(e=>this.sendMessageController.sendMessageToStreamer("GamepadDisconnected",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRHMDTransform",(e=>this.sendMessageController.sendMessageToStreamer("XRHMDTransform",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRControllerTransform",(e=>this.sendMessageController.sendMessageToStreamer("XRControllerTransform",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRSystem",(e=>this.sendMessageController.sendMessageToStreamer("XRSystem",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRButtonTouched",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonTouched",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRButtonPressed",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonPressed",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRButtonReleased",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonReleased",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRAnalog",(e=>this.sendMessageController.sendMessageToStreamer("XRAnalog",e)))}onCommand(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.Command",6);const s=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),"Data Channel Command: "+s,6);const n=JSON.parse(s);"onScreenKeyboard"===n.command&&this.pixelStreaming._activateOnScreenKeyboard(n)}onProtocolMessage(t){try{const s=new TextDecoder("utf-16").decode(t.slice(1)),n=JSON.parse(s);Object.prototype.hasOwnProperty.call(n,"Direction")||e.Error(e.GetStackTrace(),"Malformed protocol received. Ensure the protocol message contains a direction");const r=n.Direction;delete n.Direction,e.Log(e.GetStackTrace(),`Received new ${r==ke.FromStreamer?"FromStreamer":"ToStreamer"} protocol. Updating existing protocol...`),Object.keys(n).forEach((t=>{const s=n[t];switch(r){case ke.ToStreamer:if(!Object.prototype.hasOwnProperty.call(s,"id")||!Object.prototype.hasOwnProperty.call(s,"byteLength"))return void e.Error(e.GetStackTrace(),`ToStreamer->${t} protocol definition was malformed as it didn't contain at least an id and a byteLength\n\n Definition was: ${JSON.stringify(s,null,2)}`);if(s.byteLength>0&&!Object.prototype.hasOwnProperty.call(s,"structure"))return void e.Error(e.GetStackTrace(),`ToStreamer->${t} protocol definition was malformed as it specified a byteLength but no accompanying structure`);this.streamMessageController.toStreamerHandlers.get(t)?this.streamMessageController.toStreamerMessages.add(t,s):e.Error(e.GetStackTrace(),`There was no registered handler for "${t}" - try adding one using registerMessageHandler(MessageDirection.ToStreamer, "${t}", myHandler)`);break;case ke.FromStreamer:if(!Object.prototype.hasOwnProperty.call(s,"id"))return void e.Error(e.GetStackTrace(),`FromStreamer->${t} protocol definition was malformed as it didn't contain at least an id\n\n Definition was: ${JSON.stringify(s,null,2)}`);this.streamMessageController.fromStreamerHandlers.get(t)?this.streamMessageController.fromStreamerMessages.add(t,s.id):e.Error(e.GetStackTrace(),`There was no registered handler for "${s}" - try adding one using registerMessageHandler(MessageDirection.FromStreamer, "${t}", myHandler)`);break;default:e.Error(e.GetStackTrace(),`Unknown direction: ${r}`)}})),this.toStreamerMessagesController.SendRequestInitialSettings(),this.toStreamerMessagesController.SendRequestQualityControl()}catch(t){e.Log(e.GetStackTrace(),t)}}onInputControlOwnership(t){const s=new Uint8Array(t);e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.InputControlOwnership",6);const n=new Boolean(s[1]).valueOf();e.Log(e.GetStackTrace(),`Received input controller message - will your input control the stream: ${n}`),this.pixelStreaming._onInputControlOwnership(n)}onGamepadResponse(e){const t=new TextDecoder("utf-16").decode(e.slice(1)),s=JSON.parse(t);this.gamePadController.onGamepadResponseReceived(s.controllerId)}onAfkTriggered(){this.afkController.onAfkClick(),this.videoPlayer.isPaused()&&this.videoPlayer.hasVideoSource()&&this.playStream()}setAfkEnabled(e){e?this.onAfkTriggered():this.afkController.stopAfkWarningTimer()}restartStreamAutomatically(){if(this.webSocketController)if(this.webSocketController.webSocket&&this.webSocketController.webSocket.readyState!==WebSocket.CLOSED){this.pixelStreaming._showActionOrErrorOnDisconnect=!1,this.setDisconnectMessageOverride("Restarting stream..."),this.closeSignalingServer();const e=setTimeout((()=>{this.pixelStreaming._onWebRtcAutoConnect(),this.connectToSignallingServer(),clearTimeout(e)}),3e3)}else e.Log(e.GetStackTrace(),"A websocket connection has not been made yet so we will start the stream"),this.pixelStreaming._onWebRtcAutoConnect(),this.connectToSignallingServer();else e.Log(e.GetStackTrace(),"The Web Socket Controller does not exist so this will not work right now.")}loadFreezeFrameOrShowPlayOverlay(){this.pixelStreaming.dispatchEvent(new X({shouldShowPlayOverlay:this.shouldShowPlayOverlay,isValid:this.freezeFrameController.valid,jpegData:this.freezeFrameController.jpeg})),!0===this.shouldShowPlayOverlay?(e.Log(e.GetStackTrace(),"showing play overlay"),this.resizePlayerStyle()):(e.Log(e.GetStackTrace(),"showing freeze frame"),this.freezeFrameController.showFreezeFrame()),setTimeout((()=>{this.videoPlayer.setVideoEnabled(!1)}),this.freezeFrameController.freezeFrameDelay)}onFreezeFrameMessage(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.FreezeFrame",6);const s=new Uint8Array(t);this.freezeFrameController.processFreezeFrameMessage(s,(()=>this.loadFreezeFrameOrShowPlayOverlay()))}invalidateFreezeFrameAndEnableVideo(){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.FreezeFrame",6),setTimeout((()=>{this.pixelStreaming.dispatchEvent(new j),this.freezeFrameController.hideFreezeFrame()}),this.freezeFrameController.freezeFrameDelay),this.videoPlayer.getVideoElement()&&this.videoPlayer.setVideoEnabled(!0)}onFileExtension(e){const t=new Uint8Array(e);Ie.setExtensionFromBytes(t,this.file)}onFileMimeType(e){const t=new Uint8Array(e);Ie.setMimeTypeFromBytes(t,this.file)}onFileContents(e){const t=new Uint8Array(e);Ie.setContentsFromBytes(t,this.file)}playStream(){if(!this.videoPlayer.getVideoElement()){const t="Could not play video stream because the video player was not initialized correctly.";return this.pixelStreaming.dispatchEvent(new Q({message:t})),e.Error(e.GetStackTrace(),t),this.setDisconnectMessageOverride("Stream not initialized correctly"),void this.closeSignalingServer()}this.videoPlayer.hasVideoSource()?(this.setTouchInputEnabled(this.config.isFlagEnabled(oe.TouchInput)),this.pixelStreaming.dispatchEvent(new $),this.streamController.audioElement.srcObject?(this.streamController.audioElement.muted=this.config.isFlagEnabled(oe.StartVideoMuted),this.streamController.audioElement.play().then((()=>{this.playVideo()})).catch((t=>{e.Log(e.GetStackTrace(),t),e.Log(e.GetStackTrace(),"Browser does not support autoplaying video without interaction - to resolve this we are going to show the play button overlay."),this.pixelStreaming.dispatchEvent(new q({reason:t}))}))):this.playVideo(),this.shouldShowPlayOverlay=!1,this.freezeFrameController.showFreezeFrame()):e.Warning(e.GetStackTrace(),"Cannot play stream, the video element has no srcObject to play.")}playVideo(){this.videoPlayer.play().catch((t=>{this.streamController.audioElement.srcObject&&this.streamController.audioElement.pause(),e.Log(e.GetStackTrace(),t),e.Log(e.GetStackTrace(),"Browser does not support autoplaying video without interaction - to resolve this we are going to show the play button overlay."),this.pixelStreaming.dispatchEvent(new q({reason:t}))}))}autoPlayVideoOrSetUpPlayOverlay(){this.config.isFlagEnabled(oe.AutoPlayVideo)&&this.playStream(),this.resizePlayerStyle()}connectToSignallingServer(){const e=this.signallingUrlBuilder();this.webSocketController.connect(e)}startSession(t){if(this.peerConfig=t,this.config.isFlagEnabled(oe.ForceTURN)&&!this.checkTurnServerAvailability(t))return e.Info(e.GetStackTrace(),"No turn server was found in the Peer Connection Options. TURN cannot be forced, closing connection. Please use STUN instead"),this.setDisconnectMessageOverride("TURN cannot be forced, closing connection. Please use STUN instead."),void this.closeSignalingServer();this.peerConnectionController=new Ae(this.peerConfig,this.config,this.preferredCodec),this.peerConnectionController.onVideoStats=e=>this.handleVideoStats(e),this.peerConnectionController.onSendWebRTCOffer=e=>this.handleSendWebRTCOffer(e),this.peerConnectionController.onSendWebRTCAnswer=e=>this.handleSendWebRTCAnswer(e),this.peerConnectionController.onPeerIceCandidate=e=>this.handleSendIceCandidate(e),this.peerConnectionController.onDataChannel=e=>this.handleDataChannel(e),this.peerConnectionController.showTextOverlayConnecting=()=>this.pixelStreaming._onWebRtcConnecting(),this.peerConnectionController.showTextOverlaySetupFailure=()=>this.pixelStreaming._onWebRtcFailed();let s=!1;this.peerConnectionController.onIceConnectionStateChange=()=>{!s&&["connected","completed"].includes(this.peerConnectionController.peerConnection.iceConnectionState)&&(this.pixelStreaming._onWebRtcConnected(),s=!0)},this.peerConnectionController.onTrack=e=>this.streamController.handleOnTrack(e),this.config.isFlagEnabled(oe.BrowserSendOffer)&&(this.sendrecvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,"cirrus",this.datachannelOptions),this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e),this.peerConnectionController.createOffer(this.sdpConstraints,this.config))}checkTurnServerAvailability(t){if(!t.iceServers)return e.Info(e.GetStackTrace(),"A turn sever was not found"),!1;for(const s of t.iceServers)for(const t of s.urls)if(t.includes("turn"))return e.Log(e.GetStackTrace(),`A turn sever was found at ${t}`),!0;return e.Info(e.GetStackTrace(),"A turn sever was not found"),!1}handleOnConfigMessage(e){this.resizePlayerStyle(),this.startSession(e.peerConnectionOptions),this.webSocketController.onWebRtcAnswer=e=>this.handleWebRtcAnswer(e),this.webSocketController.onWebRtcOffer=e=>this.handleWebRtcOffer(e),this.webSocketController.onWebRtcPeerDataChannels=e=>this.handleWebRtcSFUPeerDatachannels(e),this.webSocketController.onIceCandidate=e=>this.handleIceCandidate(e)}handleStreamerListMessage(t){if(e.Log(e.GetStackTrace(),`Got streamer list ${t.ids}`,6),this.isReconnecting)t.ids.includes(this.subscribedStream)?(this.isReconnecting=!1,this.reconnectAttempt=0,this.webSocketController.sendSubscribe(this.subscribedStream)):this.reconnectAttempt<this.config.getNumericSettingValue(de.MaxReconnectAttempts)?(this.reconnectAttempt++,setTimeout((()=>{this.webSocketController.requestStreamerList()}),2e3)):(this.reconnectAttempt=0,this.isReconnecting=!1,this.shouldReconnect=!1,this.webSocketController.close(),this.config.setOptionSettingValue(ge.StreamerId,""),this.config.setOptionSettingOptions(ge.StreamerId,[]));else{const e=[...t.ids];e.unshift(""),this.config.setOptionSettingOptions(ge.StreamerId,e);const s=new URLSearchParams(window.location.search);let n=null;1==t.ids.length?n=t.ids[0]:this.config.isFlagEnabled(oe.PreferSFU)&&t.ids.includes("SFU")?n="SFU":s.has(ge.StreamerId)&&t.ids.includes(s.get(ge.StreamerId))&&(n=s.get(ge.StreamerId)),null!==n&&this.config.setOptionSettingValue(ge.StreamerId,n),this.pixelStreaming.dispatchEvent(new Y({messageStreamerList:t,autoSelectedStreamerId:n}))}}handleWebRtcAnswer(t){e.Log(e.GetStackTrace(),`Got answer sdp ${t.sdp}`,6);const s={sdp:t.sdp,type:"answer"};this.peerConnectionController.receiveAnswer(s),this.handlePostWebrtcNegotiation()}handleWebRtcOffer(t){e.Log(e.GetStackTrace(),`Got offer sdp ${t.sdp}`,6),this.isUsingSFU=!!t.sfu&&t.sfu,this.isUsingSFU&&(this.peerConnectionController.preferredCodec="");const s={sdp:t.sdp,type:"offer"};this.peerConnectionController.receiveOffer(s,this.config),this.handlePostWebrtcNegotiation()}handleWebRtcSFUPeerDatachannels(e){const t={ordered:!0,negotiated:!0,id:e.sendStreamId},s=e.sendStreamId!=e.recvStreamId;if(this.sendrecvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,s?"send-datachannel":"datachannel",t),s){const t={ordered:!0,negotiated:!0,id:e.recvStreamId};this.recvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,"recv-datachannel",t),this.recvDataChannelController.handleOnOpen=()=>this.webSocketController.sendSFURecvDataChannelReady(),this.recvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}else this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}handlePostWebrtcNegotiation(){this.afkController.startAfkWarningTimer(),this.pixelStreaming._onWebRtcSdp(),this.statsTimerHandle&&void 0!==this.statsTimerHandle&&window.clearInterval(this.statsTimerHandle),this.statsTimerHandle=window.setInterval((()=>this.getStats()),1e3),this.setMouseInputEnabled(this.config.isFlagEnabled(oe.MouseInput)),this.setKeyboardInputEnabled(this.config.isFlagEnabled(oe.KeyboardInput)),this.setGamePadInputEnabled(this.config.isFlagEnabled(oe.GamepadInput))}handleIceCandidate(t){e.Log(e.GetStackTrace(),"Web RTC Controller: onWebRtcIce",6);const s=new RTCIceCandidate(t);this.peerConnectionController.handleOnIce(s)}handleSendIceCandidate(t){e.Log(e.GetStackTrace(),"OnIceCandidate",6),t.candidate&&t.candidate.candidate&&this.webSocketController.sendIceCandidate(t.candidate)}handleDataChannel(t){e.Log(e.GetStackTrace(),"Data channel created for us by browser as we are a receiving peer.",6),this.sendrecvDataChannelController.dataChannel=t.channel,this.sendrecvDataChannelController.setupDataChannel(),this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}handleSendWebRTCOffer(t){e.Log(e.GetStackTrace(),"Sending the offer to the Server",6),this.webSocketController.sendWebRtcOffer(t)}handleSendWebRTCAnswer(t){e.Log(e.GetStackTrace(),"Sending the answer to the Server",6),this.webSocketController.sendWebRtcAnswer(t),this.isUsingSFU&&this.webSocketController.sendWebRtcDatachannelRequest()}setUpMouseAndFreezeFrame(){this.videoElementParentClientRect=this.videoPlayer.getVideoParentElement().getBoundingClientRect(),this.coordinateConverter.setupNormalizeAndQuantize(),this.freezeFrameController.freezeFrame.resize()}closeSignalingServer(){var e;this.shouldReconnect=!1,null===(e=this.webSocketController)||void 0===e||e.close()}closePeerConnection(){var e;null===(e=this.peerConnectionController)||void 0===e||e.close()}close(){this.closeSignalingServer(),this.closePeerConnection()}getStats(){this.peerConnectionController.generateStats()}sendLatencyTest(){this.latencyStartTime=Date.now(),this.sendDescriptorController.sendLatencyTest({StartTime:this.latencyStartTime})}sendEncoderMinQP(t){e.Log(e.GetStackTrace(),`MinQP=${t}\n`,6),null!=t&&this.sendDescriptorController.emitCommand({"Encoder.MinQP":t})}sendEncoderMaxQP(t){e.Log(e.GetStackTrace(),`MaxQP=${t}\n`,6),null!=t&&this.sendDescriptorController.emitCommand({"Encoder.MaxQP":t})}sendWebRTCMinBitrate(t){e.Log(e.GetStackTrace(),`WebRTC Min Bitrate=${t}`,6),null!=t&&this.sendDescriptorController.emitCommand({"WebRTC.MinBitrate":t})}sendWebRTCMaxBitrate(t){e.Log(e.GetStackTrace(),`WebRTC Max Bitrate=${t}`,6),null!=t&&this.sendDescriptorController.emitCommand({"WebRTC.MaxBitrate":t})}sendWebRTCFps(t){e.Log(e.GetStackTrace(),`WebRTC FPS=${t}`,6),null!=t&&(this.sendDescriptorController.emitCommand({"WebRTC.Fps":t}),this.sendDescriptorController.emitCommand({"WebRTC.MaxFps":t}))}sendShowFps(){e.Log(e.GetStackTrace(),"---- Sending show stat to UE ----",6),this.sendDescriptorController.emitCommand({"stat.fps":""})}sendIframeRequest(){e.Log(e.GetStackTrace(),"---- Sending Request for an IFrame ----",6),this.streamMessageController.toStreamerHandlers.get("IFrameRequest")()}emitUIInteraction(t){e.Log(e.GetStackTrace(),"---- Sending custom UIInteraction message ----",6),this.sendDescriptorController.emitUIInteraction(t)}emitCommand(t){e.Log(e.GetStackTrace(),"---- Sending custom Command message ----",6),this.sendDescriptorController.emitCommand(t)}emitConsoleCommand(t){e.Log(e.GetStackTrace(),"---- Sending custom Command:ConsoleCommand message ----",6),this.sendDescriptorController.emitCommand({ConsoleCommand:t})}sendRequestQualityControlOwnership(){e.Log(e.GetStackTrace(),"---- Sending Request to Control Quality ----",6),this.toStreamerMessagesController.SendRequestQualityControl()}handleLatencyTestResult(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.latencyTest",6);const s=new TextDecoder("utf-16").decode(t.slice(1)),n=new Ge;Object.assign(n,JSON.parse(s)),n.processFields(),n.testStartTimeMs=this.latencyStartTime,n.browserReceiptTimeMs=Date.now(),n.latencyExcludingDecode=~~(n.browserReceiptTimeMs-n.testStartTimeMs),n.testDuration=~~(n.TransmissionTimeMs-n.ReceiptTimeMs),n.networkLatency=~~(n.latencyExcludingDecode-n.testDuration),n.frameDisplayDeltaTimeMs&&n.browserReceiptTimeMs&&(n.endToEndLatency=(n.frameDisplayDeltaTimeMs,n.networkLatency,~~+n.CaptureToSendMs)),this.pixelStreaming._onLatencyTestResult(n)}handleInitialSettings(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.InitialSettings",6);const s=new TextDecoder("utf-16").decode(t.slice(1)),n=JSON.parse(s),r=new Fe;n.Encoder&&(r.EncoderSettings=n.Encoder),n.WebRTC&&(r.WebRTCSettings=n.WebRTC),n.PixelStreaming&&(r.PixelStreamingSettings=n.PixelStreaming),n.ConfigOptions&&void 0!==n.ConfigOptions.DefaultToHover&&this.config.setFlagEnabled(oe.HoveringMouseMode,!!n.ConfigOptions.DefaultToHover),r.ueCompatible(),e.Log(e.GetStackTrace(),s,6),this.pixelStreaming._onInitialSettings(r)}handleVideoEncoderAvgQP(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.VideoEncoderAvgQP",6);const s=Number(new TextDecoder("utf-16").decode(t.slice(1)));this.setVideoEncoderAvgQP(s)}handleVideoInitialized(){this.pixelStreaming._onVideoInitialized(),this.autoPlayVideoOrSetUpPlayOverlay(),this.resizePlayerStyle(),this.videoPlayer.updateVideoStreamSize()}onQualityControlOwnership(t){const s=new Uint8Array(t);e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.QualityControlOwnership",6),this.isQualityController=new Boolean(s[1]).valueOf(),e.Log(e.GetStackTrace(),`Received quality controller message, will control quality: ${this.isQualityController}`),this.pixelStreaming._onQualityControlOwnership(this.isQualityController)}handleVideoStats(e){this.pixelStreaming._onVideoStats(e)}resizePlayerStyle(){this.videoPlayer.resizePlayerStyle()}getDisconnectMessageOverride(){return this.disconnectMessageOverride}setDisconnectMessageOverride(e){this.disconnectMessageOverride=e}setPreferredCodec(e){this.preferredCodec=e,this.peerConnectionController&&(this.peerConnectionController.preferredCodec=e,this.peerConnectionController.updateCodecSelection=!1)}setVideoEncoderAvgQP(e){this.videoAvgQp=e,this.pixelStreaming._onVideoEncoderAvgQP(this.videoAvgQp)}setKeyboardInputEnabled(e){var t;null===(t=this.keyboardController)||void 0===t||t.unregisterKeyBoardEvents(),e&&(this.keyboardController=this.inputClassesFactory.registerKeyBoard(this.config))}setMouseInputEnabled(e){var t;if(null===(t=this.mouseController)||void 0===t||t.unregisterMouseEvents(),e){const e=this.config.isFlagEnabled(oe.HoveringMouseMode)?pe.HoveringMouse:pe.LockedMouse;this.mouseController=this.inputClassesFactory.registerMouse(e)}}setTouchInputEnabled(e){var t;null===(t=this.touchController)||void 0===t||t.unregisterTouchEvents(),e&&(this.touchController=this.inputClassesFactory.registerTouch(this.config.isFlagEnabled(oe.FakeMouseWithTouches),this.videoElementParentClientRect))}setGamePadInputEnabled(e){var t;null===(t=this.gamePadController)||void 0===t||t.unregisterGamePadEvents(),e&&(this.gamePadController=this.inputClassesFactory.registerGamePad(),this.gamePadController.onGamepadConnected=()=>{this.streamMessageController.toStreamerHandlers.get("GamepadConnected")()},this.gamePadController.onGamepadDisconnected=e=>{this.streamMessageController.toStreamerHandlers.get("GamepadDisconnected")([e])})}registerDataChannelEventEmitters(e){e.onOpen=(e,t)=>this.pixelStreaming.dispatchEvent(new z({label:e,event:t})),e.onClose=(e,t)=>this.pixelStreaming.dispatchEvent(new B({label:e,event:t})),e.onError=(e,t)=>this.pixelStreaming.dispatchEvent(new _({label:e,event:t}))}}class gt{static vertexShader(){return"\n\t\tattribute vec2 a_position;\n\t\tattribute vec2 a_texCoord;\n\n\t\t// input\n\t\tuniform vec2 u_resolution;\n\t\tuniform vec4 u_offset;\n\n\t\t//\n\t\tvarying vec2 v_texCoord;\n\n\t\tvoid main() {\n\t\t // convert the rectangle from pixels to 0.0 to 1.0\n\t\t vec2 zeroToOne = a_position / u_resolution;\n\n\t\t // convert from 0->1 to 0->2\n\t\t vec2 zeroToTwo = zeroToOne * 2.0;\n\n\t\t // convert from 0->2 to -1->+1 (clipspace)\n\t\t vec2 clipSpace = zeroToTwo - 1.0;\n\n\t\t gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n\t\t // pass the texCoord to the fragment shader\n\t\t // The GPU will interpolate this value between points.\n\t\t v_texCoord = (a_texCoord * u_offset.xy) + u_offset.zw;\n\t\t}\n\t\t"}static fragmentShader(){return"\n\t\tprecision mediump float;\n\n\t\t// our texture\n\t\tuniform sampler2D u_image;\n\n\t\t// the texCoords passed in from the vertex shader.\n\t\tvarying vec2 v_texCoord;\n\n\t\tvoid main() {\n\t\t gl_FragColor = texture2D(u_image, v_texCoord);\n\t\t}\n\t\t"}}class ut{static deepCopyGamepad(e){return JSON.parse(JSON.stringify({buttons:e.buttons.map((e=>JSON.parse(JSON.stringify({pressed:e.pressed,touched:e.touched})))),axes:e.axes}))}}class mt{constructor(e){this.toStreamerMessagesProvider=e,this.controllers=[]}updateStatus(e,t,s){if(e.gamepad){const n=t.getPose(e.gripSpace,s);if(!n)return;let r=0;e.profiles.includes("htc-vive")?r=1:e.profiles.includes("oculus-touch")&&(r=2),this.toStreamerMessagesProvider.toStreamerHandlers.get("XRSystem")([r]);let i=2;switch(e.handedness){case"left":i=0;break;case"right":i=1}const o=n.transform.matrix,a=[];for(let e=0;e<16;e++)a[e]=new Float32Array([o[e]])[0];this.toStreamerMessagesProvider.toStreamerHandlers.get("XRControllerTransform")([a[0],a[4],a[8],a[12],a[1],a[5],a[9],a[13],a[2],a[6],a[10],a[14],a[3],a[7],a[11],a[15],i]),void 0===this.controllers[i]&&(this.controllers[i]={prevState:void 0,currentState:void 0,id:void 0},this.controllers[i].prevState=ut.deepCopyGamepad(e.gamepad)),this.controllers[i].currentState=ut.deepCopyGamepad(e.gamepad);const d=this.controllers[i],l=d.currentState,c=d.prevState;for(let e=0;e<l.buttons.length;e++){const t=l.buttons[e],s=c.buttons[e];t.pressed?this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonPressed")([i,e,s.pressed?1:0]):!t.pressed&&s.pressed&&this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonReleased")([i,e,0]),t.touched&&!t.pressed?this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonPressed")([i,3,s.touched?1:0]):!t.touched&&s.touched&&this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonReleased")([i,3,0])}for(let e=0;e<l.axes.length;e++)this.toStreamerMessagesProvider.toStreamerHandlers.get("XRAnalog")([i,e,l.axes[e]]);this.controllers[i].prevState=l}}}class pt{constructor(e){this.xrSession=null,this.webRtcController=e,this.xrControllers=[],this.xrGamepadController=new mt(this.webRtcController.streamMessageController),this.onSessionEnded=new EventTarget,this.onSessionStarted=new EventTarget,this.onFrame=new EventTarget}xrClicked(){this.xrSession?this.xrSession.end():navigator.xr.requestSession("immersive-vr").then((e=>{this.onXrSessionStarted(e)}))}onXrSessionEnded(){e.Log(e.GetStackTrace(),"XR Session ended"),this.xrSession=null,this.onSessionEnded.dispatchEvent(new Event("xrSessionEnded"))}onXrSessionStarted(t){e.Log(e.GetStackTrace(),"XR Session started"),this.xrSession=t,this.xrSession.addEventListener("end",(()=>{this.onXrSessionEnded()}));const s=document.createElement("canvas");this.gl=s.getContext("webgl2",{xrCompatible:!0}),this.xrSession.updateRenderState({baseLayer:new XRWebGLLayer(this.xrSession,this.gl)});const n=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(n,gt.vertexShader()),this.gl.compileShader(n);const r=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(r,gt.fragmentShader()),this.gl.compileShader(r);const i=this.gl.createProgram();this.gl.attachShader(i,n),this.gl.attachShader(i,r),this.gl.linkProgram(i),this.gl.useProgram(i),this.positionLocation=this.gl.getAttribLocation(i,"a_position"),this.texcoordLocation=this.gl.getAttribLocation(i,"a_texCoord"),this.positionBuffer=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.enableVertexAttribArray(this.positionLocation);const o=this.gl.createTexture();this.gl.bindTexture(this.gl.TEXTURE_2D,o),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.NEAREST),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.NEAREST),this.texcoordBuffer=this.gl.createBuffer(),this.resolutionLocation=this.gl.getUniformLocation(i,"u_resolution"),this.offsetLocation=this.gl.getUniformLocation(i,"u_offset"),t.requestReferenceSpace("local").then((e=>{this.xrRefSpace=e,this.xrSession.requestAnimationFrame(((e,t)=>this.onXrFrame(e,t)))})),this.onSessionStarted.dispatchEvent(new Event("xrSessionStarted"))}onXrFrame(e,t){const s=t.getViewerPose(this.xrRefSpace);if(s){const e=s.transform.matrix,t=[];for(let s=0;s<16;s++)t[s]=new Float32Array([e[s]])[0];this.webRtcController.streamMessageController.toStreamerHandlers.get("XRHMDTransform")([t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15]]);const n=this.xrSession.renderState.baseLayer;this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,n.framebuffer),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,this.webRtcController.videoPlayer.getVideoElement()),this.render(this.webRtcController.videoPlayer.getVideoElement())}this.webRtcController.config.isFlagEnabled(oe.XRControllerInput)&&this.xrSession.inputSources.forEach(((e,s,n)=>{this.xrGamepadController.updateStatus(e,t,this.xrRefSpace)}),this),this.xrSession.requestAnimationFrame(((e,t)=>this.onXrFrame(e,t))),this.onFrame.dispatchEvent(new re({time:e,frame:t}))}render(e){if(!this.gl)return;const t=this.xrSession.renderState.baseLayer;let s,n,r,i,o;this.gl.viewport(0,0,t.framebufferWidth,t.framebufferHeight),this.gl.uniform4f(this.offsetLocation,1,1,0,0),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array([0,0,e.videoWidth,0,0,e.videoHeight,0,e.videoHeight,e.videoWidth,0,e.videoWidth,e.videoHeight]),this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.texcoordBuffer),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1]),this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),s=2,n=this.gl.FLOAT,r=!1,i=0,o=0,this.gl.vertexAttribPointer(this.positionLocation,s,n,r,i,o),this.gl.enableVertexAttribArray(this.texcoordLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.texcoordBuffer),s=2,n=this.gl.FLOAT,r=!1,i=0,o=0,this.gl.vertexAttribPointer(this.texcoordLocation,s,n,r,i,o),this.gl.uniform2f(this.resolutionLocation,e.videoWidth,e.videoHeight);const a=this.gl.TRIANGLES;o=0,this.gl.drawArrays(a,o,6)}static isSessionSupported(e){return navigator.xr?navigator.xr.isSessionSupported(e):new Promise((()=>!1))}}class St{constructor(e){this.editTextButton=null,this.hiddenInput=null,"ontouchstart"in document.documentElement&&this.createOnScreenKeyboardHelpers(e)}unquantizeAndDenormalizeUnsigned(e,t){return null}createOnScreenKeyboardHelpers(e){this.hiddenInput||(this.hiddenInput=document.createElement("input"),this.hiddenInput.id="hiddenInput",this.hiddenInput.maxLength=0,e.appendChild(this.hiddenInput)),this.editTextButton||(this.editTextButton=document.createElement("button"),this.editTextButton.id="editTextButton",this.editTextButton.innerHTML="edit text",e.appendChild(this.editTextButton),this.editTextButton.classList.add("hiddenState"),this.editTextButton.addEventListener("touchend",(e=>{this.hiddenInput.focus(),e.preventDefault()})))}showOnScreenKeyboard(e){if(e.showOnScreenKeyboard){this.editTextButton.classList.remove("hiddenState");const t=this.unquantizeAndDenormalizeUnsigned(e.x,e.y);this.editTextButton.style.top=t.y.toString()+"px",this.editTextButton.style.left=(t.x-40).toString()+"px"}else this.editTextButton.classList.add("hiddenState"),this.hiddenInput.blur()}}class vt{constructor(e,t){this._showActionOrErrorOnDisconnect=!0,this.allowConsoleCommands=!1,this.config=e,(null==t?void 0:t.videoElementParent)&&(this._videoElementParent=t.videoElementParent),this._eventEmitter=new ie,this.configureSettings(),this.setWebRtcPlayerController(new ht(this.config,this)),this.onScreenKeyboardHelper=new St(this.videoElementParent),this.onScreenKeyboardHelper.unquantizeAndDenormalizeUnsigned=(e,t)=>this._webRtcController.requestUnquantizedAndDenormalizeUnsigned(e,t),this._activateOnScreenKeyboard=e=>this.onScreenKeyboardHelper.showOnScreenKeyboard(e),this._webXrController=new pt(this._webRtcController)}get videoElementParent(){return this._videoElementParent||(this._videoElementParent=document.createElement("div"),this._videoElementParent.id="videoElementParent"),this._videoElementParent}configureSettings(){this.config._addOnSettingChangedListener(oe.IsQualityController,(e=>{!0!==e||this._webRtcController.isQualityController||this._webRtcController.sendRequestQualityControlOwnership()})),this.config._addOnSettingChangedListener(oe.AFKDetection,(e=>{this._webRtcController.setAfkEnabled(e)})),this.config._addOnSettingChangedListener(oe.MatchViewportResolution,(()=>{this._webRtcController.videoPlayer.updateVideoStreamSize()})),this.config._addOnSettingChangedListener(oe.HoveringMouseMode,(e=>{this.config.setFlagLabel(oe.HoveringMouseMode,`Control Scheme: ${e?"Hovering":"Locked"} Mouse`),this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(oe.MouseInput))})),this.config._addOnSettingChangedListener(oe.KeyboardInput,(e=>{this._webRtcController.setKeyboardInputEnabled(e)})),this.config._addOnSettingChangedListener(oe.MouseInput,(e=>{this._webRtcController.setMouseInputEnabled(e)})),this.config._addOnSettingChangedListener(oe.TouchInput,(e=>{this._webRtcController.setTouchInputEnabled(e)})),this.config._addOnSettingChangedListener(oe.GamepadInput,(e=>{this._webRtcController.setGamePadInputEnabled(e)})),this.config._addOnNumericSettingChangedListener(de.MinQP,(t=>{e.Log(e.GetStackTrace(),"-------- Sending MinQP --------",7),this._webRtcController.sendEncoderMinQP(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.MaxQP,(t=>{e.Log(e.GetStackTrace(),"-------- Sending encoder settings --------",7),this._webRtcController.sendEncoderMaxQP(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCMinBitrate,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCMinBitrate(1e3*t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCMaxBitrate,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCMaxBitrate(1e3*t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCFPS,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCFps(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnOptionSettingChangedListener(ge.PreferredCodec,(e=>{this._webRtcController&&this._webRtcController.setPreferredCodec(e)})),this.config._registerOnChangeEvents(this._eventEmitter)}_activateOnScreenKeyboard(e){throw new Error("Method not implemented.")}_onInputControlOwnership(e){this._inputController=e}setWebRtcPlayerController(e){this._webRtcController=e,this._webRtcController.setPreferredCodec(this.config.getSettingOption(ge.PreferredCodec).selected),this._webRtcController.resizePlayerStyle(),this.checkForAutoConnect()}connect(){this._eventEmitter.dispatchEvent(new V),this._webRtcController.connectToSignallingServer()}reconnect(){this._eventEmitter.dispatchEvent(new K),this._webRtcController.restartStreamAutomatically()}disconnect(){this._eventEmitter.dispatchEvent(new N),this._webRtcController.close()}play(){this._onStreamLoading(),this._webRtcController.playStream()}checkForAutoConnect(){this.config.isFlagEnabled(oe.AutoConnect)&&(this._onWebRtcAutoConnect(),this._webRtcController.connectToSignallingServer())}_onWebRtcAutoConnect(){this._eventEmitter.dispatchEvent(new D),this._showActionOrErrorOnDisconnect=!0}_onWebRtcSdp(){this._eventEmitter.dispatchEvent(new F)}_onStreamLoading(){this._eventEmitter.dispatchEvent(new H)}_onDisconnect(e){""!=this._webRtcController.getDisconnectMessageOverride()&&void 0!==this._webRtcController.getDisconnectMessageOverride()&&null!=this._webRtcController.getDisconnectMessageOverride()&&(e=this._webRtcController.getDisconnectMessageOverride(),this._webRtcController.setDisconnectMessageOverride("")),this._eventEmitter.dispatchEvent(new I({eventString:e,showActionOrErrorOnDisconnect:this._showActionOrErrorOnDisconnect})),0==this._showActionOrErrorOnDisconnect&&(this._showActionOrErrorOnDisconnect=!0)}_onWebRtcConnecting(){this._eventEmitter.dispatchEvent(new O)}_onWebRtcConnected(){this._eventEmitter.dispatchEvent(new U)}_onWebRtcFailed(){this._eventEmitter.dispatchEvent(new G)}_onVideoInitialized(){this._eventEmitter.dispatchEvent(new W),this._videoStartTime=Date.now()}_onLatencyTestResult(e){this._eventEmitter.dispatchEvent(new Z({latencyTimings:e}))}_onVideoStats(e){this._videoStartTime&&void 0!==this._videoStartTime||(this._videoStartTime=Date.now()),e.handleSessionStatistics(this._videoStartTime,this._inputController,this._webRtcController.videoAvgQp),this._eventEmitter.dispatchEvent(new J({aggregatedStats:e}))}_onVideoEncoderAvgQP(e){this._eventEmitter.dispatchEvent(new A({avgQP:e}))}_onInitialSettings(t){var s;this._eventEmitter.dispatchEvent(new ee({settings:t})),t.PixelStreamingSettings&&(this.allowConsoleCommands=null!==(s=t.PixelStreamingSettings.AllowPixelStreamingCommands)&&void 0!==s&&s,!1===this.allowConsoleCommands&&e.Info(e.GetStackTrace(),"-AllowPixelStreamingCommands=false, sending arbitrary console commands from browser to UE is disabled."));const n=this.config.useUrlParams,r=new URLSearchParams(window.location.search);t.EncoderSettings&&(this.config.setNumericSetting(de.MinQP,n&&r.has(de.MinQP)?Number.parseInt(r.get(de.MinQP)):t.EncoderSettings.MinQP),this.config.setNumericSetting(de.MaxQP,n&&r.has(de.MaxQP)?Number.parseInt(r.get(de.MaxQP)):t.EncoderSettings.MaxQP)),t.WebRTCSettings&&(this.config.setNumericSetting(de.WebRTCMinBitrate,n&&r.has(de.WebRTCMinBitrate)?Number.parseInt(r.get(de.WebRTCMinBitrate))/1e3:t.WebRTCSettings.MinBitrate/1e3),this.config.setNumericSetting(de.WebRTCMaxBitrate,n&&r.has(de.WebRTCMaxBitrate)?Number.parseInt(r.get(de.WebRTCMaxBitrate))/1e3:t.WebRTCSettings.MaxBitrate/1e3),this.config.setNumericSetting(de.WebRTCFPS,n&&r.has(de.WebRTCFPS)?Number.parseInt(r.get(de.WebRTCFPS)):t.WebRTCSettings.FPS))}_onQualityControlOwnership(e){this.config.setFlagEnabled(oe.IsQualityController,e)}requestLatencyTest(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendLatencyTest(),!0)}requestShowFps(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendShowFps(),!0)}requestIframe(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendIframeRequest(),!0)}emitUIInteraction(e){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.emitUIInteraction(e),!0)}emitCommand(e){return!(!this._webRtcController.videoPlayer.isVideoReady()||!this.allowConsoleCommands&&"ConsoleCommand"in e||(this._webRtcController.emitCommand(e),0))}emitConsoleCommand(e){return!(!this.allowConsoleCommands||!this._webRtcController.videoPlayer.isVideoReady()||(this._webRtcController.emitConsoleCommand(e),0))}addResponseEventListener(e,t){this._webRtcController.responseController.addResponseEventListener(e,t)}removeResponseEventListener(e){this._webRtcController.responseController.removeResponseEventListener(e)}dispatchEvent(e){return this._eventEmitter.dispatchEvent(e)}addEventListener(e,t){this._eventEmitter.addEventListener(e,t)}removeEventListener(e,t){this._eventEmitter.removeEventListener(e,t)}toggleXR(){this.webXrController.xrClicked()}setSignallingUrlBuilder(e){this._webRtcController.signallingUrlBuilder=e}get webSocketController(){return this._webRtcController.webSocketController}get webXrController(){return this._webXrController}}})(),r})()));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("sdp")):"function"==typeof define&&define.amd?define(["sdp"],t):"object"==typeof exports?exports["lib-pixelstreamingfrontend"]=t(require("sdp")):e["lib-pixelstreamingfrontend"]=t(e.sdp)}(this,(e=>(()=>{"use strict";var t={366:t=>{t.exports=e}},s={};function n(e){var r=s[e];if(void 0!==r)return r.exports;var i=s[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.d=(e,t)=>{for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{n.r(r),n.d(r,{AfkLogic:()=>Te,AfkTimedOutEvent:()=>A,AfkWarningActivateEvent:()=>k,AfkWarningDeactivateEvent:()=>x,AfkWarningUpdateEvent:()=>L,AggregatedStats:()=>xe,CandidatePairStats:()=>Re,CandidateStat:()=>be,Config:()=>Ce,ControlSchemeType:()=>fe,DataChannelCloseEvent:()=>_,DataChannelErrorEvent:()=>H,DataChannelLatencyTestResponseEvent:()=>te,DataChannelLatencyTestResultEvent:()=>se,DataChannelOpenEvent:()=>B,DataChannelStats:()=>we,EncoderSettings:()=>Be,EventEmitter:()=>de,Flags:()=>ce,HideFreezeFrameEvent:()=>J,InboundAudioStats:()=>ye,InboundVideoStats:()=>Me,InitialSettings:()=>Ue,InitialSettingsEvent:()=>ne,LatencyTestResultEvent:()=>ee,LatencyTestResults:()=>He,LoadFreezeFrameEvent:()=>j,Logger:()=>e,MessageDirection:()=>Oe,MessageRecv:()=>p,MessageSend:()=>i,MessageStreamerList:()=>v,NumericParameters:()=>ge,OptionParameters:()=>pe,OutBoundVideoStats:()=>Pe,PixelStreaming:()=>yt,PlayStreamErrorEvent:()=>q,PlayStreamEvent:()=>$,PlayStreamRejectedEvent:()=>X,PlayerCountEvent:()=>le,SettingBase:()=>M,SettingFlag:()=>w,SettingNumber:()=>b,SettingOption:()=>P,SettingText:()=>R,SettingsChangedEvent:()=>re,SignallingProtocol:()=>C,StatsReceivedEvent:()=>Y,StreamLoadingEvent:()=>V,StreamPreConnectEvent:()=>N,StreamPreDisconnectEvent:()=>K,StreamReconnectEvent:()=>Q,StreamerListMessageEvent:()=>Z,TextParameters:()=>me,UnquantizedAndDenormalizeUnsigned:()=>gt,VideoEncoderAvgQPEvent:()=>F,VideoInitializedEvent:()=>W,WebRTCSettings:()=>_e,WebRtcAutoConnectEvent:()=>O,WebRtcConnectedEvent:()=>G,WebRtcConnectingEvent:()=>I,WebRtcDisconnectedEvent:()=>z,WebRtcFailedEvent:()=>U,WebRtcPlayerController:()=>mt,WebRtcSdpEvent:()=>D,WebSocketController:()=>f,WebXRController:()=>Ct,XrFrameEvent:()=>ae,XrSessionEndedEvent:()=>oe,XrSessionStartedEvent:()=>ie});class e{static GetStackTrace(){const e=new Error;let t="No Stack Available for this browser";return e.stack&&(t=e.stack.toString().replace(/Error/g,"")),t}static SetLoggerVerbosity(e){null!=this.verboseLogLevel&&(this.verboseLogLevel=e)}static Log(e,t,s){if(s>this.verboseLogLevel)return;const n=`Level: Log\nMsg: ${t}\nCaller: ${e}`;console.log(n)}static Info(e,t,s){if(s>this.verboseLogLevel)return;const n=`Level: Info\nMsg: ${t}`;console.info(n)}static Error(e,t){const s=`Level: Error\nMsg: ${t}\nCaller: ${e}`;console.error(s)}static Warning(e,t){const s=`Level: Warning\nCaller: ${e}\nMsg: ${t}`;console.warn(s)}}var t,s;e.verboseLogLevel=5,function(e){e.LIST_STREAMERS="listStreamers",e.SUBSCRIBE="subscribe",e.UNSUBSCRIBE="unsubscribe",e.ICE_CANDIDATE="iceCandidate",e.OFFER="offer",e.ANSWER="answer",e.DATACHANNELREQUEST="dataChannelRequest",e.SFURECVDATACHANNELREADY="peerDataChannelsReady",e.PONG="pong"}(t||(t={}));class i{payload(){return e.Log(e.GetStackTrace(),"Sending => \n"+JSON.stringify(this,void 0,4),6),JSON.stringify(this)}}class o extends i{constructor(){super(),this.type=t.LIST_STREAMERS}}class a extends i{constructor(e){super(),this.type=t.LIST_STREAMERS,this.streamerName=e}}class l extends i{constructor(e){super(),this.type=t.SUBSCRIBE,this.streamerId=e}}class d extends i{constructor(){super(),this.type=t.UNSUBSCRIBE}}class c extends i{constructor(e){super(),this.type=t.PONG,this.time=e}}class h extends i{constructor(e){super(),this.type=t.OFFER,e&&(this.type=e.type,this.sdp=e.sdp)}}class g extends i{constructor(e){super(),this.type=t.ANSWER,e&&(this.type=e.type,this.sdp=e.sdp)}}class u extends i{constructor(){super(),this.type=t.DATACHANNELREQUEST}}class m extends i{constructor(){super(),this.type=t.SFURECVDATACHANNELREADY}}class S{constructor(e){this.type=t.ICE_CANDIDATE,this.candidate=e}payload(){return e.Log(e.GetStackTrace(),"Sending => \n"+JSON.stringify(this,void 0,4),6),JSON.stringify(this)}}!function(e){e.CONFIG="config",e.STREAMER_LIST="streamerList",e.PLAYER_COUNT="playerCount",e.OFFER="offer",e.ANSWER="answer",e.ICE_CANDIDATE="iceCandidate",e.PEER_DATA_CHANNELS="peerDataChannels",e.PING="ping",e.WARNING="warning"}(s||(s={}));class p{}class v extends p{}class C{constructor(){this.FromUEMessageHandlers=new Map}addMessageHandler(e,t){this.FromUEMessageHandlers.set(e,t)}handleMessage(t,s){this.FromUEMessageHandlers.has(t)?this.FromUEMessageHandlers.get(t)(s):e.Error(e.GetStackTrace(),`Message type of ${t} does not have a message handler registered on the frontend - ignoring message.`)}static setupDefaultHandlers(t){t.signallingProtocol.addMessageHandler(s.PING,(n=>{const r=new c((new Date).getTime()).payload();e.Log(e.GetStackTrace(),s.PING+": "+n,6),t.webSocket.send(r)})),t.signallingProtocol.addMessageHandler(s.CONFIG,(n=>{e.Log(e.GetStackTrace(),s.CONFIG,6);const r=JSON.parse(n);t.onConfig(r)})),t.signallingProtocol.addMessageHandler(s.STREAMER_LIST,(n=>{e.Log(e.GetStackTrace(),s.STREAMER_LIST,6);const r=JSON.parse(n);t.onStreamerList(r)})),t.signallingProtocol.addMessageHandler(s.PLAYER_COUNT,(n=>{e.Log(e.GetStackTrace(),s.PLAYER_COUNT,6);const r=JSON.parse(n);e.Log(e.GetStackTrace(),"Player Count: "+r.count,6),t.onPlayerCount(r)})),t.signallingProtocol.addMessageHandler(s.ANSWER,(n=>{e.Log(e.GetStackTrace(),s.ANSWER,6);const r=JSON.parse(n);t.onWebRtcAnswer(r)})),t.signallingProtocol.addMessageHandler(s.OFFER,(n=>{e.Log(e.GetStackTrace(),s.OFFER,6);const r=JSON.parse(n);t.onWebRtcOffer(r)})),t.signallingProtocol.addMessageHandler(s.ICE_CANDIDATE,(n=>{e.Log(e.GetStackTrace(),s.ICE_CANDIDATE,6);const r=JSON.parse(n);t.onIceCandidate(r.candidate)})),t.signallingProtocol.addMessageHandler(s.WARNING,(t=>{e.Warning(e.GetStackTrace(),`Warning received: ${t}`)})),t.signallingProtocol.addMessageHandler(s.PEER_DATA_CHANNELS,(n=>{e.Log(e.GetStackTrace(),s.PEER_DATA_CHANNELS,6);const r=JSON.parse(n);t.onWebRtcPeerDataChannels(r)}))}}class f{constructor(){this.WS_OPEN_STATE=1,this.onOpen=new EventTarget,this.onClose=new EventTarget,this.signallingProtocol=new C,C.setupDefaultHandlers(this)}connect(t){e.Log(e.GetStackTrace(),t,6);try{return this.webSocket=new WebSocket(t),this.webSocket.onopen=e=>this.handleOnOpen(e),this.webSocket.onerror=()=>this.handleOnError(),this.webSocket.onclose=e=>this.handleOnClose(e),this.webSocket.onmessage=e=>this.handleOnMessage(e),this.webSocket.onmessagebinary=e=>this.handleOnMessageBinary(e),!0}catch(t){return e.Error(t,t),!1}}handleOnMessageBinary(t){t&&t.data&&t.data.text().then((e=>{const t=new MessageEvent("messageFromBinary",{data:e});this.handleOnMessage(t)})).catch((t=>{e.Error(e.GetStackTrace(),`从websocket解析二进制blob失败,原因: ${t}`)}))}handleOnMessage(t){if(t.data&&t.data instanceof Blob)return void this.handleOnMessageBinary(t);const s=JSON.parse(t.data);e.Log(e.GetStackTrace(),"received => \n"+JSON.stringify(JSON.parse(t.data),void 0,4),6),this.signallingProtocol.handleMessage(s.type,t.data)}handleOnOpen(t){e.Log(e.GetStackTrace(),"通过WebSocket连接到信令服务器",6),this.onOpen.dispatchEvent(new Event("open"))}handleOnError(){e.Error(e.GetStackTrace(),"WebSocket error")}handleOnClose(t){console.log(t),e.Log(e.GetStackTrace(),"通过WebSocket与信令服务器断开连接: "+JSON.stringify(t.code)+" - "+t.reason),4004==t.code&&(this.onOpen.dispatchEvent(new Event("close",t)),this.onClose.dispatchEvent(new CustomEvent("close",{detail:t})))}requestStreamerList(){const e=new o;this.webSocket.send(e.payload())}requestStreamerObject(e){const t=new a(e);this.webSocket.send(t.payload())}sendSubscribe(e){const t=new l(e);this.webSocket.send(t.payload())}sendUnsubscribe(){const e=new d;this.webSocket.send(e.payload())}sendWebRtcOffer(e){const t=new h(e);this.webSocket.send(t.payload())}sendWebRtcAnswer(e){const t=new g(e);this.webSocket.send(t.payload())}sendWebRtcDatachannelRequest(){const e=new u;this.webSocket.send(e.payload())}sendSFURecvDataChannelReady(){const e=new m;this.webSocket.send(e.payload())}sendIceCandidate(t){if(e.Log(e.GetStackTrace(),"Sending Ice Candidate(发送Ice候选人)"),this.webSocket&&this.webSocket.readyState===this.WS_OPEN_STATE){const e=new S(t);this.webSocket.send(e.payload())}}close(){var e;null===(e=this.webSocket)||void 0===e||e.close()}onConfig(e){}onStreamerList(e){}onIceCandidate(e){}onWebRtcAnswer(e){}onWebRtcOffer(e){}onWebRtcPeerDataChannels(e){}onPlayerCount(e){}}class T{constructor(e){this.videoElementProvider=e,this.audioElement=document.createElement("Audio"),this.videoElementProvider.setAudioElement(this.audioElement)}handleOnTrack(t){e.Log(e.GetStackTrace(),"handleOnTrack "+JSON.stringify(t.streams),6);const s=this.videoElementProvider.getVideoElement();if(t.track&&e.Log(e.GetStackTrace(),"Got track - "+t.track.kind+" id="+t.track.id+" readyState="+t.track.readyState,6),"audio"!=t.track.kind)return"video"==t.track.kind&&s.srcObject!==t.streams[0]?(s.srcObject=t.streams[0],void e.Log(e.GetStackTrace(),"Set video source from video track ontrack.")):void 0;this.CreateAudioTrack(t.streams[0])}CreateAudioTrack(t){const s=this.videoElementProvider.getVideoElement();s.srcObject!=t&&s.srcObject&&s.srcObject!==t&&(this.audioElement.srcObject=t,e.Log(e.GetStackTrace(),"Created new audio element to play separate audio stream."))}}class E{constructor(e){this.freezeFrameHeight=0,this.freezeFrameWidth=0,this.rootDiv=e,this.rootElement=document.createElement("div"),this.rootElement.id="freezeFrame",this.rootElement.style.display="none",this.rootElement.style.pointerEvents="none",this.rootElement.style.position="absolute",this.rootElement.style.zIndex="20",this.imageElement=document.createElement("img"),this.imageElement.style.position="absolute",this.rootElement.appendChild(this.imageElement),this.rootDiv.appendChild(this.rootElement)}setElementForShow(){this.rootElement.style.display="block"}setElementForHide(){this.rootElement.style.display="none"}updateImageElementSource(e){const t=btoa(e.reduce(((e,t)=>e+String.fromCharCode(t)),""));this.imageElement.src="data:image/jpeg;base64,"+t}setDimensionsFromElementAndResize(){this.freezeFrameHeight=this.imageElement.naturalHeight,this.freezeFrameWidth=this.imageElement.naturalWidth,this.resize()}resize(){if(0!==this.freezeFrameWidth&&0!==this.freezeFrameHeight){let e=0,t=0,s=0,n=0;const r=this.rootDiv.clientWidth/this.rootDiv.clientHeight,i=this.freezeFrameWidth/this.freezeFrameHeight;r<i?(e=this.rootDiv.clientWidth,t=Math.floor(this.rootDiv.clientWidth/i),s=Math.floor(.5*(this.rootDiv.clientHeight-t)),n=0):(e=Math.floor(this.rootDiv.clientHeight*i),t=this.rootDiv.clientHeight,s=0,n=Math.floor(.5*(this.rootDiv.clientWidth-e))),this.rootElement.style.width=this.rootDiv.offsetWidth+"px",this.rootElement.style.height=this.rootDiv.offsetHeight+"px",this.rootElement.style.left="0px",this.rootElement.style.top="0px",this.imageElement.style.width=e+"px",this.imageElement.style.height=t+"px",this.imageElement.style.left=n+"px",this.imageElement.style.top=s+"px"}}}class y{constructor(e){this.receiving=!1,this.size=0,this.jpeg=void 0,this.valid=!1,this.freezeFrameDelay=50,this.freezeFrame=new E(e)}showFreezeFrame(){this.valid&&this.freezeFrame.setElementForShow()}hideFreezeFrame(){this.valid=!1,this.freezeFrame.setElementForHide()}updateFreezeFrameAndShow(e,t){this.freezeFrame.updateImageElementSource(e),this.freezeFrame.imageElement.onload=()=>{this.freezeFrame.setDimensionsFromElementAndResize(),t()}}processFreezeFrameMessage(t,s){this.receiving||(this.receiving=!0,this.valid=!1,this.size=0,this.jpeg=void 0),this.size=new DataView(t.slice(1,5).buffer).getInt32(0,!0);const n=t.slice(5);if(this.jpeg){const e=new Uint8Array(this.jpeg.length+n.length);e.set(this.jpeg,0),e.set(n,this.jpeg.length),this.jpeg=e}else this.jpeg=n,this.receiving=!0,e.Log(e.GetStackTrace(),`received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`,6);this.jpeg.length===this.size?(this.receiving=!1,this.valid=!0,e.Log(e.GetStackTrace(),`received complete freeze frame ${this.size}`,6),this.updateFreezeFrameAndShow(this.jpeg,s)):this.jpeg.length>this.size&&(e.Error(e.GetStackTrace(),`received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`),this.jpeg=void 0,this.receiving=!1)}}class M{constructor(e,t,s,n,r=(()=>{})){this.onChange=r,this.onChangeEmit=()=>{},this.id=e,this.description=s,this.label=t,this.value=n}set label(e){this._label=e,this.onChangeEmit(this._value)}get label(){return this._label}get value(){return this._value}set value(e){this._value=e,this.onChange(this._value,this),this.onChangeEmit(this._value)}}class w extends M{constructor(e,t,s,n,r,i=(()=>{})){super(e,t,s,n,i);const o=new URLSearchParams(window.location.search);if(r&&o.has(this.id)){const e=this.getUrlParamFlag();this.flag=e}else this.flag=n;this.useUrlParams=r}getUrlParamFlag(){const e=new URLSearchParams(window.location.search);return!!e.has(this.id)&&"false"!==e.get(this.id)&&"False"!==e.get(this.id)}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);!0===this.flag?e.set(this.id,"true"):e.set(this.id,"false"),window.history.replaceState({},"",""!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}enable(){this.flag=!0}get flag(){return!!this.value}set flag(e){this.value=e}}class b extends M{constructor(e,t,s,n,r,i,o,a=(()=>{})){super(e,t,s,i,a),this._min=n,this._max=r;const l=new URLSearchParams(window.location.search);if(o&&l.has(this.id)){const e=Number.parseInt(l.get(this.id));this.number=Number.isNaN(e)?i:e}else this.number=i;this.useUrlParams=o}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.number.toString()),window.history.replaceState({},"",""!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}set number(e){this.value=this.clamp(e)}get number(){return this.value}clamp(e){return Math.max(Math.min(this._max,e),this._min)}get min(){return this._min}get max(){return this._max}addOnChangedListener(e){this.onChange=e}}class R extends M{constructor(e,t,s,n,r,i=(()=>{})){super(e,t,s,n,i);const o=new URLSearchParams(window.location.search);if(r&&o.has(this.id)){const e=this.getUrlParamText();this.text=e}else this.text=n;this.useUrlParams=r}getUrlParamText(){var e;const t=new URLSearchParams(window.location.search);return t.has(this.id)&&null!==(e=t.get(this.id))&&void 0!==e?e:""}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.text),window.history.replaceState({},"",""!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}get text(){return this.value}set text(e){this.value=e}}class P extends M{constructor(e,t,s,n,r,i,o=(()=>{})){super(e,t,s,[n,n],o),this.options=r;const a=new URLSearchParams(window.location.search),l=i&&a.has(this.id)?this.getUrlParamText():n;this.selected=l,this.useUrlParams=i}getUrlParamText(){var e;const t=new URLSearchParams(window.location.search);return t.has(this.id)&&null!==(e=t.get(this.id))&&void 0!==e?e:""}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.selected),window.history.replaceState({},"",""!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}addOnChangedListener(e){this.onChange=e}get options(){return this._options}set options(e){this._options=e,this.onChangeEmit(this.selected)}get selected(){return this.value}set selected(e){let t=this.options.filter((t=>-1!==t.indexOf(e)));t.length?this.value=t[0]:(t=this.options.filter((t=>-1!==t.indexOf(e.split(" ")[0]))),t.length&&(this.value=t[0]))}}class k extends Event{constructor(e){super("afkWarningActivate"),this.data=e}}class L extends Event{constructor(e){super("afkWarningUpdate"),this.data=e}}class x extends Event{constructor(){super("afkWarningDeactivate")}}class A extends Event{constructor(){super("afkTimedOut")}}class F extends Event{constructor(e){super("videoEncoderAvgQP"),this.data=e}}class D extends Event{constructor(){super("webRtcSdp")}}class O extends Event{constructor(){super("webRtcAutoConnect")}}class I extends Event{constructor(){super("webRtcConnecting")}}class G extends Event{constructor(){super("webRtcConnected")}}class U extends Event{constructor(){super("webRtcFailed")}}class z extends Event{constructor(e){super("webRtcDisconnected"),this.data=e}}class B extends Event{constructor(e){super("dataChannelOpen"),this.data=e}}class _ extends Event{constructor(e){super("dataChannelClose"),this.data=e}}class H extends Event{constructor(e){super("dataChannelError"),this.data=e}}class W extends Event{constructor(){super("videoInitialized")}}class V extends Event{constructor(){super("streamLoading")}}class N extends Event{constructor(){super("streamConnect")}}class K extends Event{constructor(){super("streamDisconnect")}}class Q extends Event{constructor(){super("streamReconnect")}}class q extends Event{constructor(e){super("playStreamError"),this.data=e}}class $ extends Event{constructor(){super("playStream")}}class X extends Event{constructor(e){super("playStreamRejected"),this.data=e}}class j extends Event{constructor(e){super("loadFreezeFrame"),this.data=e}}class J extends Event{constructor(){super("hideFreezeFrame")}}class Y extends Event{constructor(e){super("statsReceived"),this.data=e}}class Z extends Event{constructor(e){super("streamerListMessage"),this.data=e}}class ee extends Event{constructor(e){super("latencyTestResult"),this.data=e}}class te extends Event{constructor(e){super("dataChannelLatencyTestResponse"),this.data=e}}class se extends Event{constructor(e){super("dataChannelLatencyTestResult"),this.data=e}}class ne extends Event{constructor(e){super("initialSettings"),this.data=e}}class re extends Event{constructor(e){super("settingsChanged"),this.data=e}}class ie extends Event{constructor(){super("xrSessionStarted")}}class oe extends Event{constructor(){super("xrSessionEnded")}}class ae extends Event{constructor(e){super("xrFrame"),this.data=e}}class le extends Event{constructor(e){super("playerCount"),this.data=e}}class de extends EventTarget{dispatchEvent(e){return super.dispatchEvent(e)}addEventListener(e,t){super.addEventListener(e,t)}removeEventListener(e,t){super.removeEventListener(e,t)}}class ce{}ce.AutoConnect="AutoConnect",ce.AutoPlayVideo="AutoPlayVideo",ce.AFKDetection="TimeoutIfIdle",ce.BrowserSendOffer="OfferToReceive",ce.HoveringMouseMode="HoveringMouse",ce.ForceMonoAudio="ForceMonoAudio",ce.ForceTURN="ForceTURN",ce.FakeMouseWithTouches="FakeMouseWithTouches",ce.IsQualityController="ControlsQuality",ce.MatchViewportResolution="MatchViewportRes",ce.StartVideoMuted="StartVideoMuted",ce.SuppressBrowserKeys="SuppressBrowserKeys",ce.UseMic="UseMic",ce.KeyboardInput="KeyboardInput",ce.MouseInput="MouseInput",ce.TouchInput="TouchInput",ce.GamepadInput="GamepadInput",ce.XRControllerInput="XRControllerInput",ce.WaitForStreamer="WaitForStreamer";const he=e=>Object.getOwnPropertyNames(ce).some((t=>ce[t]===e));class ge{}ge.AFKTimeoutSecs="AFKTimeout",ge.MinQP="MinQP",ge.MaxQP="MaxQP",ge.WebRTCFPS="WebRTCFPS",ge.WebRTCMinBitrate="WebRTCMinBitrate",ge.WebRTCMaxBitrate="WebRTCMaxBitrate",ge.MaxReconnectAttempts="MaxReconnectAttempts",ge.StreamerAutoJoinInterval="StreamerAutoJoinInterval";const ue=e=>Object.getOwnPropertyNames(ge).some((t=>ge[t]===e));class me{}me.SignallingServerUrl="ss";const Se=e=>Object.getOwnPropertyNames(me).some((t=>me[t]===e));class pe{}pe.PreferredCodec="PreferredCodec",pe.StreamerId="StreamerId";const ve=e=>Object.getOwnPropertyNames(pe).some((t=>pe[t]===e));class Ce{constructor(e={}){this.flags=new Map,this.numericParameters=new Map,this.textParameters=new Map,this.optionParameters=new Map;const{initialSettings:t,useUrlParams:s}=e;this._useUrlParams=!!s,this.populateDefaultSettings(this._useUrlParams),t&&this.setSettings(t)}get useUrlParams(){return this._useUrlParams}populateDefaultSettings(e){this.textParameters.set(me.SignallingServerUrl,new R(me.SignallingServerUrl,"Signalling url","Url of the signalling server",("https:"===location.protocol?"wss://":"ws://")+window.location.hostname+("80"===window.location.port||""===window.location.port?"":`:${window.location.port}`),e)),this.optionParameters.set(pe.StreamerId,new P(pe.StreamerId,"Streamer ID","The ID of the streamer to stream.","",[],e)),this.optionParameters.set(pe.PreferredCodec,new P(pe.PreferredCodec,"Preferred Codec","The preferred codec to be used during codec negotiation","H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f",function(){const e=[];if(!RTCRtpReceiver.getCapabilities)return e.push("Only available on Chrome"),e;const t=/(VP\d|H26\d|AV1).*/;return RTCRtpReceiver.getCapabilities("video").codecs.forEach((s=>{const n=s.mimeType.split("/")[1]+" "+(s.sdpFmtpLine||"");null!==t.exec(n)&&e.push(n)})),e}(),e)),this.flags.set(ce.AutoConnect,new w(ce.AutoConnect,"Auto connect to stream","Whether we should attempt to auto connect to the signalling server or show a click to start prompt.",!1,e)),this.flags.set(ce.AutoPlayVideo,new w(ce.AutoPlayVideo,"Auto play video","When video is ready automatically start playing it as opposed to showing a play button.",!0,e)),this.flags.set(ce.BrowserSendOffer,new w(ce.BrowserSendOffer,"Browser send offer","Browser will initiate the WebRTC handshake by sending the offer to the streamer",!1,e)),this.flags.set(ce.UseMic,new w(ce.UseMic,"Use microphone","Make browser request microphone access and open an input audio track.",!1,e)),this.flags.set(ce.StartVideoMuted,new w(ce.StartVideoMuted,"Start video muted","Video will start muted if true.",!1,e)),this.flags.set(ce.SuppressBrowserKeys,new w(ce.SuppressBrowserKeys,"Suppress browser keys","Suppress certain browser keys that we use in UE, for example F5 to show shader complexity instead of refresh the page.",!0,e)),this.flags.set(ce.IsQualityController,new w(ce.IsQualityController,"Is quality controller?","True if this peer controls stream quality",!0,e)),this.flags.set(ce.ForceMonoAudio,new w(ce.ForceMonoAudio,"Force mono audio","Force browser to request mono audio in the SDP",!1,e)),this.flags.set(ce.ForceTURN,new w(ce.ForceTURN,"Force TURN","Only generate TURN/Relayed ICE candidates.",!1,e)),this.flags.set(ce.AFKDetection,new w(ce.AFKDetection,"AFK if idle","Timeout the experience if user is AFK for a period.",!1,e)),this.flags.set(ce.MatchViewportResolution,new w(ce.MatchViewportResolution,"Match viewport resolution","Pixel Streaming will be instructed to dynamically resize the video stream to match the size of the video element.",!1,e)),this.flags.set(ce.HoveringMouseMode,new w(ce.HoveringMouseMode,"Control Scheme: Locked Mouse","Either locked mouse, where the pointer is consumed by the video and locked to it, or hovering mouse, where the mouse is not consumed.",!1,e,((e,t)=>{t.label=`Control Scheme: ${e?"Hovering":"Locked"} Mouse`}))),this.flags.set(ce.FakeMouseWithTouches,new w(ce.FakeMouseWithTouches,"Fake mouse with touches","A single finger touch is converted into a mouse event. This allows a non-touch application to be controlled partially via a touch device.",!1,e)),this.flags.set(ce.KeyboardInput,new w(ce.KeyboardInput,"Keyboard input","If enabled, send keyboard events to streamer",!0,e)),this.flags.set(ce.MouseInput,new w(ce.MouseInput,"Mouse input","If enabled, send mouse events to streamer",!0,e)),this.flags.set(ce.TouchInput,new w(ce.TouchInput,"Touch input","If enabled, send touch events to streamer",!0,e)),this.flags.set(ce.GamepadInput,new w(ce.GamepadInput,"Gamepad input","If enabled, send gamepad events to streamer",!0,e)),this.flags.set(ce.XRControllerInput,new w(ce.XRControllerInput,"XR controller input","If enabled, send XR controller events to streamer",!0,e)),this.flags.set(ce.WaitForStreamer,new w(ce.WaitForStreamer,"等待拖缆","将继续尝试连接到第一个可用的流媒体.",!0,e)),this.numericParameters.set(ge.AFKTimeoutSecs,new b(ge.AFKTimeoutSecs,"AFK timeout","The time (in seconds) it takes for the application to time out if AFK timeout is enabled.",0,600,120,e)),this.numericParameters.set(ge.MaxReconnectAttempts,new b(ge.MaxReconnectAttempts,"Max Reconnects","Maximum number of reconnects the application will attempt when a streamer disconnects.",0,999,3,e)),this.numericParameters.set(ge.MinQP,new b(ge.MinQP,"Min QP","The lower bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.",0,51,0,e)),this.numericParameters.set(ge.MaxQP,new b(ge.MaxQP,"Max QP","The upper bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.",0,51,51,e)),this.numericParameters.set(ge.WebRTCFPS,new b(ge.WebRTCFPS,"Max FPS","The maximum FPS that WebRTC will try to transmit frames at.",1,999,60,e)),this.numericParameters.set(ge.WebRTCMinBitrate,new b(ge.WebRTCMinBitrate,"Min Bitrate (kbps)","The minimum bitrate that WebRTC should use.",0,5e5,0,e)),this.numericParameters.set(ge.WebRTCMaxBitrate,new b(ge.WebRTCMaxBitrate,"Max Bitrate (kbps)","The maximum bitrate that WebRTC should use.",0,5e5,0,e)),this.numericParameters.set(ge.StreamerAutoJoinInterval,new b(ge.StreamerAutoJoinInterval,"Streamer Auto Join Interval (ms)","Delay between retries when waiting for an available streamer.",500,9e5,3e3,e))}_addOnNumericSettingChangedListener(e,t){this.numericParameters.has(e)&&this.numericParameters.get(e).addOnChangedListener(t)}_addOnOptionSettingChangedListener(e,t){this.optionParameters.has(e)&&this.optionParameters.get(e).addOnChangedListener(t)}getNumericSettingValue(e){if(this.numericParameters.has(e))return this.numericParameters.get(e).number;throw new Error(`There is no numeric setting with the id of ${e}`)}getTextSettingValue(e){if(this.textParameters.has(e))return this.textParameters.get(e).value;throw new Error(`There is no numeric setting with the id of ${e}`)}setNumericSetting(e,t){if(!this.numericParameters.has(e))throw new Error(`There is no numeric setting with the id of ${e}`);this.numericParameters.get(e).number=t}_addOnSettingChangedListener(e,t){this.flags.has(e)&&(this.flags.get(e).onChange=t)}_addOnTextSettingChangedListener(e,t){this.textParameters.has(e)&&(this.textParameters.get(e).onChange=t)}getSettingOption(e){return this.optionParameters.get(e)}isFlagEnabled(e){return this.flags.get(e).flag}setFlagEnabled(t,s){this.flags.has(t)?this.flags.get(t).flag=s:e.Warning(e.GetStackTrace(),`Cannot toggle flag called ${t} - it does not exist in the Config.flags map.`)}setTextSetting(t,s){this.textParameters.has(t)?this.textParameters.get(t).text=s:e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.textParameters map.`)}setOptionSettingOptions(t,s){this.optionParameters.has(t)?(console.log(s),this.optionParameters.get(t).options=s):e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.optionParameters map.`)}setOptionSettingValue(t,s){this.optionParameters.has(t)?this.optionParameters.get(t).selected=s:e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.enumParameters map.`)}setFlagLabel(t,s){this.flags.has(t)?this.flags.get(t).label=s:e.Warning(e.GetStackTrace(),`Cannot set label for flag called ${t} - it does not exist in the Config.flags map.`)}setSettings(e){for(const t of Object.keys(e))he(t)?this.setFlagEnabled(t,e[t]):ue(t)?this.setNumericSetting(t,e[t]):Se(t)?this.setTextSetting(t,e[t]):ve(t)&&this.setOptionSettingValue(t,e[t])}getSettings(){const e={};for(const[t,s]of this.flags.entries())e[t]=s.flag;for(const[t,s]of this.numericParameters.entries())e[t]=s.number;for(const[t,s]of this.textParameters.entries())e[t]=s.text;for(const[t,s]of this.optionParameters.entries())e[t]=s.selected;return e}getFlags(){return Array.from(this.flags.values())}getTextSettings(){return Array.from(this.textParameters.values())}getNumericSettings(){return Array.from(this.numericParameters.values())}getOptionSettings(){return Array.from(this.optionParameters.values())}_registerOnChangeEvents(e){for(const t of this.flags.keys()){const s=this.flags.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new re({id:s.id,type:"flag",value:t,target:s})))}for(const t of this.numericParameters.keys()){const s=this.numericParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new re({id:s.id,type:"number",value:t,target:s})))}for(const t of this.textParameters.keys()){const s=this.textParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new re({id:s.id,type:"text",value:t,target:s})))}for(const t of this.optionParameters.keys()){const s=this.optionParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new re({id:s.id,type:"option",value:t,target:s})))}}}var fe;!function(e){e[e.LockedMouse=0]="LockedMouse",e[e.HoveringMouse=1]="HoveringMouse"}(fe||(fe={}));class Te{constructor(e,t,s){this.closeTimeout=10,this.active=!1,this.countdownActive=!1,this.warnTimer=void 0,this.countDown=0,this.countDownTimer=void 0,this.config=e,this.pixelStreaming=t,this.onDismissAfk=s,this.onAFKTimedOutCallback=()=>{console.log("AFK timed out, did you want to override this callback?")}}onAfkClick(){clearInterval(this.countDownTimer),(this.active||this.countdownActive)&&(this.startAfkWarningTimer(),this.pixelStreaming.dispatchEvent(new x))}startAfkWarningTimer(){this.config.getNumericSettingValue(ge.AFKTimeoutSecs)>0&&this.config.isFlagEnabled(ce.AFKDetection)?this.active=!0:this.active=!1,this.resetAfkWarningTimer()}stopAfkWarningTimer(){this.active=!1,this.countdownActive=!1,clearTimeout(this.warnTimer),clearInterval(this.countDownTimer)}pauseAfkWarningTimer(){this.active=!1}resetAfkWarningTimer(){this.active&&this.config.isFlagEnabled(ce.AFKDetection)&&(clearTimeout(this.warnTimer),this.warnTimer=setTimeout((()=>this.activateAfkEvent()),1e3*this.config.getNumericSettingValue(ge.AFKTimeoutSecs)))}activateAfkEvent(){this.pauseAfkWarningTimer(),this.pixelStreaming.dispatchEvent(new k({countDown:this.countDown,dismissAfk:this.onDismissAfk})),this.countDown=this.closeTimeout,this.countdownActive=!0,this.pixelStreaming.dispatchEvent(new L({countDown:this.countDown})),this.config.isFlagEnabled(ce.HoveringMouseMode)||document.exitPointerLock&&document.exitPointerLock(),this.countDownTimer=setInterval((()=>{this.countDown--,0==this.countDown?(this.pixelStreaming.dispatchEvent(new A),this.onAFKTimedOutCallback(),e.Log(e.GetStackTrace(),"You have been disconnected due to inactivity"),this.stopAfkWarningTimer()):this.pixelStreaming.dispatchEvent(new L({countDown:this.countDown}))}),1e3)}}class Ee{constructor(){this.isReceivingFreezeFrame=!1}getDataChannelInstance(){return this}createDataChannel(e,t,s){this.peerConnection=e,this.label=t,this.datachannelOptions=s,null==s&&(this.datachannelOptions={},this.datachannelOptions.ordered=!0),this.dataChannel=this.peerConnection.createDataChannel(this.label,this.datachannelOptions),this.setupDataChannel()}setupDataChannel(){this.dataChannel.binaryType="arraybuffer",this.dataChannel.onopen=e=>this.handleOnOpen(e),this.dataChannel.onclose=e=>this.handleOnClose(e),this.dataChannel.onmessage=e=>this.handleOnMessage(e),this.dataChannel.onerror=e=>this.handleOnError(e)}handleOnOpen(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) opened.`,7),this.onOpen(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}handleOnClose(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) closed.`,7),this.onClose(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}handleOnMessage(t){e.Log(e.GetStackTrace(),`Data Channel (${this.label}) message: ${t}`,8)}handleOnError(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) error: ${t}`,7),this.onError(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}onOpen(e,t){}onClose(e,t){}onError(e,t){}}class ye{}class Me{}class we{}class be{}class Re{}class Pe{}class ke{}class Le{}class xe{constructor(){this.inboundVideoStats=new Me,this.inboundAudioStats=new ye,this.candidatePair=new Re,this.DataChannelStats=new we,this.outBoundVideoStats=new Pe,this.sessionStats=new ke,this.streamStats=new Le,this.codecs=new Map}processStats(t){this.localCandidates=new Array,this.remoteCandidates=new Array,t.forEach((t=>{switch(t.type){case"candidate-pair":this.handleCandidatePair(t);break;case"certificate":case"media-source":case"media-playout":case"outbound-rtp":case"peer-connection":case"remote-inbound-rtp":case"transport":break;case"codec":this.handleCodec(t);break;case"data-channel":this.handleDataChannel(t);break;case"inbound-rtp":this.handleInBoundRTP(t);break;case"local-candidate":this.handleLocalCandidate(t);break;case"remote-candidate":this.handleRemoteCandidate(t);break;case"remote-outbound-rtp":this.handleRemoteOutBound(t);break;case"track":this.handleTrack(t);break;case"stream":this.handleStream(t);break;default:e.Error(e.GetStackTrace(),"unhandled Stat Type"),e.Log(e.GetStackTrace(),t)}}))}handleStream(e){this.streamStats=e}handleCandidatePair(e){this.candidatePair.bytesReceived=e.bytesReceived,this.candidatePair.bytesSent=e.bytesSent,this.candidatePair.localCandidateId=e.localCandidateId,this.candidatePair.remoteCandidateId=e.remoteCandidateId,this.candidatePair.nominated=e.nominated,this.candidatePair.readable=e.readable,this.candidatePair.selected=e.selected,this.candidatePair.writable=e.writable,this.candidatePair.state=e.state,this.candidatePair.currentRoundTripTime=e.currentRoundTripTime}handleDataChannel(e){this.DataChannelStats.bytesReceived=e.bytesReceived,this.DataChannelStats.bytesSent=e.bytesSent,this.DataChannelStats.dataChannelIdentifier=e.dataChannelIdentifier,this.DataChannelStats.id=e.id,this.DataChannelStats.label=e.label,this.DataChannelStats.messagesReceived=e.messagesReceived,this.DataChannelStats.messagesSent=e.messagesSent,this.DataChannelStats.protocol=e.protocol,this.DataChannelStats.state=e.state,this.DataChannelStats.timestamp=e.timestamp}handleLocalCandidate(e){const t=new be;t.label="local-candidate",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.candidateType=e.candidateType,t.id=e.id,this.localCandidates.push(t)}handleRemoteCandidate(e){const t=new be;t.label="local-candidate",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.id=e.id,t.candidateType=e.candidateType,this.remoteCandidates.push(t)}handleInBoundRTP(t){switch(t.kind){case"video":this.inboundVideoStats=t,null!=this.lastVideoStats&&(this.inboundVideoStats.bitrate=8*(this.inboundVideoStats.bytesReceived-this.lastVideoStats.bytesReceived)/(this.inboundVideoStats.timestamp-this.lastVideoStats.timestamp),this.inboundVideoStats.bitrate=Math.floor(this.inboundVideoStats.bitrate)),this.lastVideoStats=Object.assign({},this.inboundVideoStats);break;case"audio":this.inboundAudioStats=t,null!=this.lastAudioStats&&(this.inboundAudioStats.bitrate=8*(this.inboundAudioStats.bytesReceived-this.lastAudioStats.bytesReceived)/(this.inboundAudioStats.timestamp-this.lastAudioStats.timestamp),this.inboundAudioStats.bitrate=Math.floor(this.inboundAudioStats.bitrate)),this.lastAudioStats=Object.assign({},this.inboundAudioStats);break;default:e.Log(e.GetStackTrace(),"Kind is not handled")}}handleRemoteOutBound(e){"video"===e.kind&&(this.outBoundVideoStats.bytesSent=e.bytesSent,this.outBoundVideoStats.id=e.id,this.outBoundVideoStats.localId=e.localId,this.outBoundVideoStats.packetsSent=e.packetsSent,this.outBoundVideoStats.remoteTimestamp=e.remoteTimestamp,this.outBoundVideoStats.timestamp=e.timestamp)}handleTrack(e){"track"!==e.type||"video_label"!==e.trackIdentifier&&"video"!==e.kind||(this.inboundVideoStats.framesDropped=e.framesDropped,this.inboundVideoStats.framesReceived=e.framesReceived,this.inboundVideoStats.frameHeight=e.frameHeight,this.inboundVideoStats.frameWidth=e.frameWidth)}handleCodec(e){const t=e.id,s=`${e.mimeType.replace("video/","").replace("audio/","")}${e.sdpFmtpLine?` ${e.sdpFmtpLine}`:""}`;this.codecs.set(t,s)}handleSessionStatistics(e,t,s){const n=Date.now()-e;this.sessionStats.runTime=new Date(n).toISOString().substr(11,8).toString();const r=null===t?"Not sent yet":t?"true":"false";this.sessionStats.controlsStreamInput=r,this.sessionStats.videoEncoderAvgQP=s}isNumber(e){return"number"==typeof e&&isFinite(e)}}var Ae=n(366);class Fe{static isVideoTransciever(e){return this.canTransceiverReceiveVideo(e)||this.canTransceiverSendVideo(e)}static canTransceiverReceiveVideo(e){return!!e&&("sendrecv"===e.direction||"recvonly"===e.direction)&&e.receiver&&e.receiver.track&&"video"===e.receiver.track.kind}static canTransceiverSendVideo(e){return!!e&&("sendrecv"===e.direction||"sendonly"===e.direction)&&e.sender&&e.sender.track&&"video"===e.sender.track.kind}static isAudioTransciever(e){return this.canTransceiverReceiveAudio(e)||this.canTransceiverSendAudio(e)}static canTransceiverReceiveAudio(e){return!!e&&("sendrecv"===e.direction||"recvonly"===e.direction)&&e.receiver&&e.receiver.track&&"audio"===e.receiver.track.kind}static canTransceiverSendAudio(e){return!!e&&("sendrecv"===e.direction||"sendonly"===e.direction)&&e.sender&&e.sender.track&&"audio"===e.sender.track.kind}}var De,Oe,Ie=function(e,t,s,n){return new(s||(s=Promise))((function(r,i){function o(e){try{l(n.next(e))}catch(e){i(e)}}function a(e){try{l(n.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}l((n=n.apply(e,t||[])).next())}))};class Ge{constructor(e,t,s){this.config=t,this.createPeerConnection(e,s)}createPeerConnection(t,s){this.config.isFlagEnabled(ce.ForceTURN)&&(t.iceTransportPolicy="relay",e.Log(e.GetStackTrace(),"Forcing TURN usage by setting ICE Transport Policy in peer connection config.")),this.peerConnection=new RTCPeerConnection(t),this.peerConnection.onsignalingstatechange=e=>this.handleSignalStateChange(e),this.peerConnection.oniceconnectionstatechange=e=>this.handleIceConnectionStateChange(e),this.peerConnection.onicegatheringstatechange=e=>this.handleIceGatheringStateChange(e),this.peerConnection.ontrack=e=>this.handleOnTrack(e),this.peerConnection.onicecandidate=e=>this.handleIceCandidate(e),this.peerConnection.ondatachannel=e=>this.handleDataChannel(e),this.aggregatedStats=new xe,this.preferredCodec=s,this.updateCodecSelection=!0}createOffer(t,s){return Ie(this,void 0,void 0,(function*(){e.Log(e.GetStackTrace(),"Create Offer",6);const n="localhost"===location.hostname||"127.0.0.1"===location.hostname,r="https:"===location.protocol;let i=s.isFlagEnabled(ce.UseMic);!i||n||r||(i=!1,e.Error(e.GetStackTrace(),"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access."),e.Error(e.GetStackTrace(),"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'")),this.setupTransceiversAsync(i).finally((()=>{var e;null===(e=this.peerConnection)||void 0===e||e.createOffer(t).then((e=>{var t;this.showTextOverlayConnecting(),e.sdp=this.mungeSDP(e.sdp,i),null===(t=this.peerConnection)||void 0===t||t.setLocalDescription(e),this.onSendWebRTCOffer(e)})).catch((()=>{this.showTextOverlaySetupFailure()}))}))}))}receiveOffer(t,s){var n;return Ie(this,void 0,void 0,(function*(){e.Log(e.GetStackTrace(),"Receive Offer",6),null===(n=this.peerConnection)||void 0===n||n.setRemoteDescription(t).then((()=>{const t="localhost"===location.hostname||"127.0.0.1"===location.hostname,n="https:"===location.protocol;let r=s.isFlagEnabled(ce.UseMic);!r||t||n||(r=!1,e.Error(e.GetStackTrace(),"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access."),e.Error(e.GetStackTrace(),"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'")),this.setupTransceiversAsync(r).finally((()=>{var t;null===(t=this.peerConnection)||void 0===t||t.createAnswer().then((e=>{var t;return e.sdp=this.mungeSDP(e.sdp,r),null===(t=this.peerConnection)||void 0===t?void 0:t.setLocalDescription(e)})).then((()=>{var e;this.onSendWebRTCAnswer(null===(e=this.peerConnection)||void 0===e?void 0:e.currentLocalDescription)})).catch((()=>{e.Error(e.GetStackTrace(),"createAnswer() failed")}))}))})),this.config.setOptionSettingOptions(pe.PreferredCodec,this.parseAvailableCodecs(t).filter((e=>this.config.getSettingOption(pe.PreferredCodec).options.includes(e))))}))}receiveAnswer(e){var t;null===(t=this.peerConnection)||void 0===t||t.setRemoteDescription(e),this.config.setOptionSettingOptions(pe.PreferredCodec,this.parseAvailableCodecs(e).filter((e=>this.config.getSettingOption(pe.PreferredCodec).options.includes(e))))}generateStats(){var e;null===(e=this.peerConnection)||void 0===e||e.getStats(null).then((e=>{this.aggregatedStats.processStats(e),this.onVideoStats(this.aggregatedStats),this.updateCodecSelection&&this.config.setOptionSettingValue(pe.PreferredCodec,this.aggregatedStats.codecs.get(this.aggregatedStats.inboundVideoStats.codecId))}))}close(){this.peerConnection&&(this.peerConnection.close(),this.peerConnection=null)}mungeSDP(e,t){let s=e.replace(/(a=fmtp:\d+ .*level-asymmetry-allowed=.*)\r\n/gm,"$1;x-google-start-bitrate=10000;x-google-max-bitrate=100000\r\n"),n="maxaveragebitrate=510000;";return t&&(n+="sprop-maxcapturerate=48000;"),n+=this.config.isFlagEnabled(ce.ForceMonoAudio)?"stereo=0;":"stereo=1;",n+="useinbandfec=1",s=s.replace("useinbandfec=1",n),s}handleOnIce(t){var s;e.Log(e.GetStackTrace(),"peerconnection handleOnIce",6),this.config.isFlagEnabled(ce.ForceTURN)&&t.candidate.indexOf("relay")<0?e.Info(e.GetStackTrace(),`Dropping candidate because it was not TURN relay. | Type= ${t.type} | Protocol= ${t.protocol} | Address=${t.address} | Port=${t.port} |`,6):null===(s=this.peerConnection)||void 0===s||s.addIceCandidate(t)}handleSignalStateChange(t){e.Log(e.GetStackTrace(),"signaling state change: "+t,6)}handleIceConnectionStateChange(t){e.Log(e.GetStackTrace(),"ice connection state change: "+t,6),this.onIceConnectionStateChange(t)}handleIceGatheringStateChange(t){e.Log(e.GetStackTrace(),"ice gathering state change: "+JSON.stringify(t),6)}handleOnTrack(e){this.onTrack(e)}handleIceCandidate(e){this.onPeerIceCandidate(e)}handleDataChannel(e){this.onDataChannel(e)}onTrack(e){}onIceConnectionStateChange(e){}onPeerIceCandidate(e){}onDataChannel(e){}setupTransceiversAsync(e){var t,s,n,r,i,o,a,l,d;return Ie(this,void 0,void 0,(function*(){const c=(null===(t=this.peerConnection)||void 0===t?void 0:t.getTransceivers().length)>0;if(null===(s=this.peerConnection)||void 0===s||s.addTransceiver("video",{direction:"recvonly"}),RTCRtpReceiver.getCapabilities&&""!=this.preferredCodec)for(const e of null!==(r=null===(n=this.peerConnection)||void 0===n?void 0:n.getTransceivers())&&void 0!==r?r:[])if(e&&e.receiver&&e.receiver.track&&"video"===e.receiver.track.kind&&e.setCodecPreferences){const t=this.preferredCodec.split(" "),s=[{mimeType:"video/"+t[0],clockRate:9e4,sdpFmtpLine:t[1]?t[1]:""}];this.config.getSettingOption(pe.PreferredCodec).options.filter((e=>e!=this.preferredCodec)).forEach((e=>{const t=e.split(" ");s.push({mimeType:"video/"+t[0],clockRate:9e4,sdpFmtpLine:t[1]?t[1]:""})}));for(const e of s)""===e.sdpFmtpLine&&delete e.sdpFmtpLine;e.setCodecPreferences(s)}if(e){const e={video:!1,audio:{autoGainControl:!1,channelCount:1,echoCancellation:!1,latency:0,noiseSuppression:!1,sampleRate:48e3,sampleSize:16,volume:1}},t=yield navigator.mediaDevices.getUserMedia(e);if(t)if(c){for(const e of null!==(a=null===(o=this.peerConnection)||void 0===o?void 0:o.getTransceivers())&&void 0!==a?a:[])if(Fe.canTransceiverReceiveAudio(e))for(const s of t.getTracks())s.kind&&"audio"==s.kind&&(e.sender.replaceTrack(s),e.direction="sendrecv")}else for(const e of t.getTracks())e.kind&&"audio"==e.kind&&(null===(l=this.peerConnection)||void 0===l||l.addTransceiver(e,{direction:"sendrecv"}));else null===(d=this.peerConnection)||void 0===d||d.addTransceiver("audio",{direction:"recvonly"})}else null===(i=this.peerConnection)||void 0===i||i.addTransceiver("audio",{direction:"recvonly"})}))}onVideoStats(e){}onSendWebRTCOffer(e){}onSendWebRTCAnswer(e){}showTextOverlayConnecting(){}showTextOverlaySetupFailure(){}parseAvailableCodecs(e){if(!RTCRtpReceiver.getCapabilities)return["Only available on Chrome"];const t=[],s=(0,Ae.splitSections)(e.sdp);return s.shift(),s.forEach((e=>{const{codecs:s}=(0,Ae.parseRtpParameters)(e),n=/(VP\d|H26\d|AV1).*/;s.forEach((e=>{const s=e.name+" "+Object.keys(e.parameters||{}).map((t=>t+"="+e.parameters[t])).join(";");if(null!==n.exec(s)){"VP9"==e.name&&(e.parameters={"profile-id":"0"});const s=e.name+" "+Object.keys(e.parameters||{}).map((t=>t+"="+e.parameters[t])).join(";");t.push(s)}}))})),t}}class Ue{constructor(){this.PixelStreamingSettings=new ze,this.EncoderSettings=new Be,this.WebRTCSettings=new _e}ueCompatible(){null!=this.WebRTCSettings.MaxFPS&&(this.WebRTCSettings.FPS=this.WebRTCSettings.MaxFPS)}}class ze{}class Be{}class _e{}class He{constructor(){this.ReceiptTimeMs=null,this.TransmissionTimeMs=null,this.PreCaptureTimeMs=null,this.PostCaptureTimeMs=null,this.PreEncodeTimeMs=null,this.PostEncodeTimeMs=null,this.EncodeMs=null,this.CaptureToSendMs=null,this.testStartTimeMs=0,this.browserReceiptTimeMs=0,this.latencyExcludingDecode=0,this.testDuration=0,this.networkLatency=0,this.browserSendLatency=0,this.frameDisplayDeltaTimeMs=0,this.endToEndLatency=0,this.encodeLatency=0}setFrameDisplayDeltaTime(e){0==this.frameDisplayDeltaTimeMs&&(this.frameDisplayDeltaTimeMs=Math.round(e))}processFields(){null!=this.EncodeMs||null==this.PreEncodeTimeMs&&null==this.PostEncodeTimeMs||(e.Log(e.GetStackTrace(),`Setting Encode Ms \n ${this.PostEncodeTimeMs} \n ${this.PreEncodeTimeMs}`,6),this.EncodeMs=this.PostEncodeTimeMs-this.PreEncodeTimeMs),null!=this.CaptureToSendMs||null==this.PreCaptureTimeMs&&null==this.PostCaptureTimeMs||(e.Log(e.GetStackTrace(),`Setting CaptureToSendMs Ms \n ${this.PostCaptureTimeMs} \n ${this.PreCaptureTimeMs}`,6),this.CaptureToSendMs=this.PostCaptureTimeMs-this.PreCaptureTimeMs)}}class We{static setExtensionFromBytes(t,s){s.receiving||(s.mimetype="",s.extension="",s.receiving=!0,s.valid=!1,s.size=0,s.data=[],s.timestampStart=(new Date).getTime(),e.Log(e.GetStackTrace(),"Received first chunk of file",6));const n=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),n,6),s.extension=n}static setMimeTypeFromBytes(t,s){s.receiving||(s.mimetype="",s.extension="",s.receiving=!0,s.valid=!1,s.size=0,s.data=[],s.timestampStart=(new Date).getTime(),e.Log(e.GetStackTrace(),"Received first chunk of file",6));const n=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),n,6),s.mimetype=n}static setContentsFromBytes(t,s){if(!s.receiving)return;s.size=Math.ceil(new DataView(t.slice(1,5).buffer).getInt32(0,!0)/16379);const n=t.slice(5);if(s.data.push(n),e.Log(e.GetStackTrace(),`Received file chunk: ${s.data.length}/${s.size}`,6),s.data.length===s.size){s.receiving=!1,s.valid=!0,e.Log(e.GetStackTrace(),"Received complete file",6);const t=(new Date).getTime()-s.timestampStart,n=Math.round(16*s.size*1024/t);e.Log(e.GetStackTrace(),`Average transfer bitrate: ${n}kb/s over ${t/1e3} seconds`,6);const r=new Blob(s.data,{type:s.mimetype}),i=document.createElement("a");i.setAttribute("href",URL.createObjectURL(r)),i.setAttribute("download",`transfer.${s.extension}`),document.body.append(i),i.remove()}else s.data.length>s.size&&(s.receiving=!1,e.Error(e.GetStackTrace(),`Received bigger file than advertised: ${s.data.length}/${s.size}`))}}class Ve{constructor(){this.mimetype="",this.extension="",this.receiving=!1,this.size=0,this.data=[],this.valid=!1}}class Ne{}Ne.mainButton=0,Ne.auxiliaryButton=1,Ne.secondaryButton=2,Ne.fourthButton=3,Ne.fifthButton=4;class Ke{}Ke.primaryButton=1,Ke.secondaryButton=2,Ke.auxiliaryButton=4,Ke.fourthButton=8,Ke.fifthButton=16;class Qe{constructor(){this.unregisterCallbacks=[]}addUnregisterCallback(e){this.unregisterCallbacks.push(e)}unregisterAll(){for(const e of this.unregisterCallbacks)e();this.unregisterCallbacks=[]}}class qe{constructor(e,t,s){this.touchEventListenerTracker=new Qe,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s;const n=e=>this.onTouchStart(e),r=e=>this.onTouchEnd(e),i=e=>this.onTouchMove(e);document.addEventListener("touchstart",n,{passive:!1}),document.addEventListener("touchend",r,{passive:!1}),document.addEventListener("touchmove",i,{passive:!1}),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchstart",n))),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchend",r))),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchmove",i)))}unregisterTouchEvents(){this.touchEventListenerTracker.unregisterAll()}setVideoElementParentClientRect(e){this.videoElementParentClientRect=e}onTouchStart(e){if(this.videoElementProvider.isVideoReady()){if(null==this.fakeTouchFinger){const t=e.changedTouches[0];this.fakeTouchFinger=new $e(t.identifier,t.clientX-this.videoElementParentClientRect.left,t.clientY-this.videoElementParentClientRect.top);const s=this.videoElementProvider.getVideoParentElement(),n=new MouseEvent("mouseenter",t);s.dispatchEvent(n);const r=this.coordinateConverter.normalizeAndQuantizeUnsigned(this.fakeTouchFinger.x,this.fakeTouchFinger.y);this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([Ne.mainButton,r.x,r.y])}e.preventDefault()}}onTouchEnd(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.videoElementProvider.getVideoParentElement(),s=this.toStreamerMessagesProvider.toStreamerHandlers;for(let n=0;n<e.changedTouches.length;n++){const r=e.changedTouches[n];if(r.identifier===this.fakeTouchFinger.id){const e=r.clientX-this.videoElementParentClientRect.left,n=r.clientY-this.videoElementParentClientRect.top,i=this.coordinateConverter.normalizeAndQuantizeUnsigned(e,n);s.get("MouseUp")([Ne.mainButton,i.x,i.y]);const o=new MouseEvent("mouseleave",r);t.dispatchEvent(o),this.fakeTouchFinger=null;break}}e.preventDefault()}onTouchMove(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.toStreamerMessagesProvider.toStreamerHandlers;for(let s=0;s<e.touches.length;s++){const n=e.touches[s];if(n.identifier===this.fakeTouchFinger.id){const e=n.clientX-this.videoElementParentClientRect.left,s=n.clientY-this.videoElementParentClientRect.top,r=this.coordinateConverter.normalizeAndQuantizeUnsigned(e,s),i=this.coordinateConverter.normalizeAndQuantizeSigned(e-this.fakeTouchFinger.x,s-this.fakeTouchFinger.y);t.get("MouseMove")([r.x,r.y,i.x,i.y]),this.fakeTouchFinger.x=e,this.fakeTouchFinger.y=s;break}}e.preventDefault()}}class $e{constructor(e,t,s){this.id=e,this.x=t,this.y=s}}class Xe{}Xe.backSpace=8,Xe.shift=16,Xe.control=17,Xe.alt=18,Xe.rightShift=253,Xe.rightControl=254,Xe.rightAlt=255;class je{constructor(e,t,s){this.keyboardEventListenerTracker=new Qe,this.CodeToKeyCode={Escape:27,Digit0:48,Digit1:49,Digit2:50,Digit3:51,Digit4:52,Digit5:53,Digit6:54,Digit7:55,Digit8:56,Digit9:57,Minus:173,Equal:187,Backspace:8,Tab:9,KeyQ:81,KeyW:87,KeyE:69,KeyR:82,KeyT:84,KeyY:89,KeyU:85,KeyI:73,KeyO:79,KeyP:80,BracketLeft:219,BracketRight:221,Enter:13,ControlLeft:17,KeyA:65,KeyS:83,KeyD:68,KeyF:70,KeyG:71,KeyH:72,KeyJ:74,KeyK:75,KeyL:76,Semicolon:186,Quote:222,Backquote:192,ShiftLeft:16,Backslash:220,KeyZ:90,KeyX:88,KeyC:67,KeyV:86,KeyB:66,KeyN:78,KeyM:77,Comma:188,Period:190,Slash:191,ShiftRight:253,AltLeft:18,Space:32,CapsLock:20,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,Pause:19,ScrollLock:145,NumpadDivide:111,NumpadMultiply:106,NumpadSubtract:109,NumpadAdd:107,NumpadDecimal:110,Numpad9:105,Numpad8:104,Numpad7:103,Numpad6:102,Numpad5:101,Numpad4:100,Numpad3:99,Numpad2:98,Numpad1:97,Numpad0:96,NumLock:144,ControlRight:254,AltRight:255,Home:36,End:35,ArrowUp:38,ArrowLeft:37,ArrowRight:39,ArrowDown:40,PageUp:33,PageDown:34,Insert:45,Delete:46,ContextMenu:93},this.toStreamerMessagesProvider=e,this.config=t,this.activeKeysProvider=s}registerKeyBoardEvents(){const e=e=>this.handleOnKeyDown(e),t=e=>this.handleOnKeyUp(e),s=e=>this.handleOnKeyPress(e);document.addEventListener("keydown",e),document.addEventListener("keyup",t),document.addEventListener("keypress",s),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keydown",e))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keyup",t))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keypress",s)))}unregisterKeyBoardEvents(){this.keyboardEventListenerTracker.unregisterAll()}handleOnKeyDown(t){const s=this.getKeycode(t);s&&(e.Log(e.GetStackTrace(),`key down ${s}, repeat = ${t.repeat}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyDown")([this.getKeycode(t),t.repeat?1:0]),this.activeKeysProvider.getActiveKeys().push(s),s===Xe.backSpace&&document.dispatchEvent(new KeyboardEvent("keypress",{charCode:Xe.backSpace})),this.config.isFlagEnabled(ce.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(s)&&t.preventDefault())}handleOnKeyUp(t){const s=this.getKeycode(t);s&&(e.Log(e.GetStackTrace(),`key up ${s}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyUp")([s]),this.config.isFlagEnabled(ce.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(s)&&t.preventDefault())}handleOnKeyPress(t){if(!("charCode"in t))return void e.Warning(e.GetStackTrace(),"KeyboardEvent.charCode is deprecated in this browser, cannot send key press.");const s=t.charCode;e.Log(e.GetStackTrace(),`key press ${s}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyPress")([s])}getKeycode(t){if(!("keyCode"in t)){const s=t;return s.code in this.CodeToKeyCode?this.CodeToKeyCode[s.code]:(e.Warning(e.GetStackTrace(),`Keyboard code of ${s.code} is not supported in our mapping, ignoring this key.`),null)}return t.keyCode===Xe.shift&&"ShiftRight"===t.code?Xe.rightShift:t.keyCode===Xe.control&&"ControlRight"===t.code?Xe.rightControl:t.keyCode===Xe.alt&&"AltRight"===t.code?Xe.rightAlt:t.keyCode}isKeyCodeBrowserKey(e){return e>=112&&e<=123||9===e}}class Je{constructor(e,t,s){this.x=0,this.y=0,this.updateMouseMovePositionEvent=e=>{this.updateMouseMovePosition(e)},this.mouseEventListenerTracker=new Qe,this.videoElementProvider=e,this.mouseController=t,this.activeKeysProvider=s;const n=this.videoElementProvider.getVideoParentElement();this.x=n.getBoundingClientRect().width/2,this.y=n.getBoundingClientRect().height/2,this.coord=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(this.x,this.y)}unregisterMouseEvents(){this.mouseEventListenerTracker.unregisterAll()}lockStateChange(){const t=this.videoElementProvider.getVideoParentElement(),s=this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;if(document.pointerLockElement===t||document.mozPointerLockElement===t)e.Log(e.GetStackTrace(),"Pointer locked",6),document.addEventListener("mousemove",this.updateMouseMovePositionEvent,!1),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("mousemove",this.updateMouseMovePositionEvent,!1)));else{e.Log(e.GetStackTrace(),"The pointer lock status is now unlocked",6),document.removeEventListener("mousemove",this.updateMouseMovePositionEvent,!1);let t=this.activeKeysProvider.getActiveKeys();const n=new Set(t),r=[];n.forEach((e=>{r[e]})),r.forEach((e=>{s.get("KeyUp")([e])})),t=[]}}updateMouseMovePosition(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.mouseController.toStreamerMessagesProvider.toStreamerHandlers,s=this.videoElementProvider.getVideoParentElement().clientWidth,n=this.videoElementProvider.getVideoParentElement().clientHeight;this.x+=e.movementX,this.y+=e.movementY,this.x>s&&(this.x-=s),this.y>n&&(this.y-=n),this.x<0&&(this.x=s+this.x),this.y<0&&(this.y=n-this.y),this.coord=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(this.x,this.y);const r=this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(e.movementX,e.movementY);t.get("MouseMove")([this.coord.x,this.coord.y,r.x,r.y])}handleMouseDown(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([e.button,this.coord.x,this.coord.y])}handleMouseUp(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([e.button,this.coord.x,this.coord.y])}handleMouseWheel(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseWheel")([e.wheelDelta,this.coord.x,this.coord.y])}handleMouseDouble(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDouble")([e.button,this.coord.x,this.coord.y])}handlePressMouseButtons(e){this.videoElementProvider.isVideoReady()&&this.mouseController.pressMouseButtons(e.buttons,this.x,this.y)}handleReleaseMouseButtons(e){this.videoElementProvider.isVideoReady()&&this.mouseController.releaseMouseButtons(e.buttons,this.x,this.y)}}class Ye{constructor(e){this.mouseController=e}unregisterMouseEvents(){}updateMouseMovePosition(t){if(!this.mouseController.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),"MouseMove",6);const s=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(t.offsetX,t.offsetY),n=this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(t.movementX,t.movementY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseMove")([s.x,s.y,n.x,n.y]),t.preventDefault()}handleMouseDown(t){if(!this.mouseController.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),"onMouse Down",6);const s=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(t.offsetX,t.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([t.button,s.x,s.y]),t.preventDefault()}handleMouseUp(t){if(!this.mouseController.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),"onMouse Up",6);const s=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(t.offsetX,t.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([t.button,s.x,s.y]),t.preventDefault()}handleContextMenu(e){this.mouseController.videoElementProvider.isVideoReady()&&e.preventDefault()}handleMouseWheel(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseWheel")([e.wheelDelta,t.x,t.y]),e.preventDefault()}handleMouseDouble(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDouble")([e.button,t.x,t.y])}handlePressMouseButtons(t){this.mouseController.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"onMouse press",6),this.mouseController.pressMouseButtons(t.buttons,t.offsetX,t.offsetY))}handleReleaseMouseButtons(t){this.mouseController.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"onMouse release",6),this.mouseController.releaseMouseButtons(t.buttons,t.offsetX,t.offsetY))}}class Ze{constructor(e,t,s,n){this.mouseEventListenerTracker=new Qe,this.toStreamerMessagesProvider=e,this.coordinateConverter=s,this.videoElementProvider=t,this.activeKeysProvider=n,this.registerMouseEnterAndLeaveEvents()}unregisterMouseEvents(){this.mouseEventListenerTracker.unregisterAll()}registerLockedMouseEvents(e){const t=this.videoElementProvider.getVideoParentElement(),s=new Je(this.videoElementProvider,e,this.activeKeysProvider);if(t.requestPointerLock=t.requestPointerLock||t.mozRequestPointerLock,document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock,t.requestPointerLock){const e=()=>{t.requestPointerLock()};t.addEventListener("click",e),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("click",e)))}const n=()=>s.lockStateChange();document.addEventListener("pointerlockchange",n,!1),document.addEventListener("mozpointerlockchange",n,!1),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("pointerlockchange",n,!1))),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("mozpointerlockchange",n,!1)));const r=e=>s.handleMouseDown(e),i=e=>s.handleMouseUp(e),o=e=>s.handleMouseWheel(e),a=e=>s.handleMouseDouble(e);t.addEventListener("mousedown",r),t.addEventListener("mouseup",i),t.addEventListener("wheel",o),t.addEventListener("dblclick",a),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mousedown",r))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseup",i))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("wheel",o))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("dblclick",a))),this.mouseEventListenerTracker.addUnregisterCallback((()=>s.unregisterMouseEvents())),this.mouseEventListenerTracker.addUnregisterCallback((()=>{!document.exitPointerLock||document.pointerLockElement!==t&&document.mozPointerLockElement!==t||document.exitPointerLock()}))}registerHoveringMouseEvents(e){const t=this.videoElementProvider.getVideoParentElement(),s=new Ye(e),n=e=>s.updateMouseMovePosition(e),r=e=>s.handleMouseDown(e),i=e=>s.handleMouseUp(e),o=e=>s.handleContextMenu(e),a=e=>s.handleMouseWheel(e),l=e=>s.handleMouseDouble(e);t.addEventListener("mousemove",n),t.addEventListener("mousedown",r),t.addEventListener("mouseup",i),t.addEventListener("contextmenu",o),t.addEventListener("wheel",a),t.addEventListener("dblclick",l),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mousemove",n))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mousedown",r))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseup",i))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("contextmenu",o))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("wheel",a))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("dblclick",l))),this.mouseEventListenerTracker.addUnregisterCallback((()=>s.unregisterMouseEvents()))}registerMouseEnterAndLeaveEvents(){const t=this.videoElementProvider.getVideoParentElement(),s=t=>{this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"Mouse Entered",6),this.sendMouseEnter(),this.pressMouseButtons(t.buttons,t.x,t.y))},n=t=>{this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"Mouse Left",6),this.sendMouseLeave(),this.releaseMouseButtons(t.buttons,t.x,t.y))};t.addEventListener("mouseenter",s),t.addEventListener("mouseleave",n),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseenter",s))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseleave",n)))}releaseMouseButtons(e,t,s){const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&Ke.primaryButton&&this.sendMouseUp(Ne.mainButton,n.x,n.y),e&Ke.secondaryButton&&this.sendMouseUp(Ne.secondaryButton,n.x,n.y),e&Ke.auxiliaryButton&&this.sendMouseUp(Ne.auxiliaryButton,n.x,n.y),e&Ke.fourthButton&&this.sendMouseUp(Ne.fourthButton,n.x,n.y),e&Ke.fifthButton&&this.sendMouseUp(Ne.fifthButton,n.x,n.y)}pressMouseButtons(e,t,s){if(!this.videoElementProvider.isVideoReady())return;const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&Ke.primaryButton&&this.sendMouseDown(Ne.mainButton,n.x,n.y),e&Ke.secondaryButton&&this.sendMouseDown(Ne.secondaryButton,n.x,n.y),e&Ke.auxiliaryButton&&this.sendMouseDown(Ne.auxiliaryButton,n.x,n.y),e&Ke.fourthButton&&this.sendMouseDown(Ne.fourthButton,n.x,n.y),e&Ke.fifthButton&&this.sendMouseDown(Ne.fifthButton,n.x,n.y)}sendMouseEnter(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseEnter")()}sendMouseLeave(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseLeave")()}sendMouseDown(t,s,n){this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),`mouse button ${t} down at (${s}, ${n})`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([t,s,n]))}sendMouseUp(t,s,n){if(!this.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),`mouse button ${t} up at (${s}, ${n})`,6);const r=this.coordinateConverter.normalizeAndQuantizeUnsigned(s,n);this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([t,r.x,r.y])}}class et{constructor(t,s,n){this.fingers=[9,8,7,6,5,4,3,2,1,0],this.fingerIds=new Map,this.maxByteValue=255,this.touchEventListenerTracker=new Qe,this.toStreamerMessagesProvider=t,this.videoElementProvider=s,this.coordinateConverter=n,this.videoElementParent=s.getVideoElement();const r=e=>this.onTouchStart(e),i=e=>this.onTouchEnd(e),o=e=>this.onTouchMove(e);this.videoElementParent.addEventListener("touchstart",r),this.videoElementParent.addEventListener("touchend",i),this.videoElementParent.addEventListener("touchmove",o),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchstart",r))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchend",i))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchmove",o))),e.Log(e.GetStackTrace(),"Touch Events Registered",6);const a=e=>{e.preventDefault()};document.addEventListener("touchmove",a),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchmove",a)))}unregisterTouchEvents(){this.touchEventListenerTracker.unregisterAll()}rememberTouch(t){const s=this.fingers.pop();void 0===s&&e.Log(e.GetStackTrace(),"exhausted touch identifiers",6),this.fingerIds.set(t.identifier,s)}forgetTouch(e){this.fingers.push(this.fingerIds.get(e.identifier)),this.fingers.sort((function(e,t){return t-e})),this.fingerIds.delete(e.identifier)}onTouchStart(t){if(this.videoElementProvider.isVideoReady()){for(let e=0;e<t.changedTouches.length;e++)this.rememberTouch(t.changedTouches[e]);e.Log(e.GetStackTrace(),"touch start",6),this.emitTouchData("TouchStart",t.changedTouches),t.preventDefault()}}onTouchEnd(t){if(this.videoElementProvider.isVideoReady()){e.Log(e.GetStackTrace(),"touch end",6),this.emitTouchData("TouchEnd",t.changedTouches);for(let e=0;e<t.changedTouches.length;e++)this.forgetTouch(t.changedTouches[e]);t.preventDefault()}}onTouchMove(t){this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"touch move",6),this.emitTouchData("TouchMove",t.touches),t.preventDefault())}emitTouchData(t,s){let n=document.querySelector(".screen"),r=Math.floor(n.getBoundingClientRect().width*window.devicePixelRatio),i=Math.floor(n.getBoundingClientRect().height*window.devicePixelRatio),o=Math.floor(window.screen.width*window.devicePixelRatio),a=Math.floor(window.screen.height*window.devicePixelRatio),l=(Math.floor(document.documentElement.clientWidth*window.devicePixelRatio),a-Math.floor(document.documentElement.clientHeight*window.devicePixelRatio)),d=document.querySelector(".screen").clientWidth/i,c=document.querySelector(".screen").clientHeight/r;if(!this.videoElementProvider.isVideoReady())return;this.videoElementProvider.getVideoParentElement().getBoundingClientRect();const h=this.toStreamerMessagesProvider.toStreamerHandlers;for(let n=0;n<s.length;n++){const g=1,u=s[n];let m,S;m=c*(Math.floor(u.clientY*window.devicePixelRatio)-Math.floor((a-l-i)/2)),S=d*(r-(Math.floor(u.clientX*window.devicePixelRatio)-Math.floor((o-r)/2))),e.Log(e.GetStackTrace(),`F${this.fingerIds.get(u.identifier)}=(${m}, ${S})`,6);const p=this.coordinateConverter.normalizeAndQuantizeUnsigned(m,S);switch(t){case"TouchStart":h.get("TouchStart")([g,p.x,p.y,this.fingerIds.get(u.identifier),this.maxByteValue*u.force,p.inRange?1:0]);break;case"TouchEnd":h.get("TouchEnd")([g,p.x,p.y,this.fingerIds.get(u.identifier),this.maxByteValue*u.force,p.inRange?1:0]);break;case"TouchMove":h.get("TouchMove")([g,p.x,p.y,this.fingerIds.get(u.identifier),this.maxByteValue*u.force,p.inRange?1:0])}}}}class tt{constructor(e){this.gamePadEventListenerTracker=new Qe,this.toStreamerMessagesProvider=e,this.requestAnimationFrame=(window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.requestAnimationFrame).bind(window);const t=window;if("GamepadEvent"in t){const e=e=>this.gamePadConnectHandler(e),t=e=>this.gamePadDisconnectHandler(e);window.addEventListener("gamepadconnected",e),window.addEventListener("gamepaddisconnected",t),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener("gamepadconnected",e))),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener("gamepaddisconnected",t)))}else if("WebKitGamepadEvent"in t){const e=e=>this.gamePadConnectHandler(e),t=e=>this.gamePadDisconnectHandler(e);window.addEventListener("webkitgamepadconnected",e),window.addEventListener("webkitgamepaddisconnected",t),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener("webkitgamepadconnected",e))),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener("webkitgamepaddisconnected",t)))}if(this.controllers=[],navigator.getGamepads)for(const e of navigator.getGamepads())e&&this.gamePadConnectHandler(new GamepadEvent("gamepadconnected",{gamepad:e}))}unregisterGamePadEvents(){this.gamePadEventListenerTracker.unregisterAll();for(const e of this.controllers)void 0!==e.id&&this.onGamepadDisconnected(e.id);this.controllers=[],this.onGamepadConnected=()=>{},this.onGamepadDisconnected=()=>{}}gamePadConnectHandler(t){e.Log(e.GetStackTrace(),"Gamepad connect handler",6);const s=t.gamepad,n={currentState:s,prevState:s,id:void 0};this.controllers.push(n),this.controllers[s.index].currentState=s,this.controllers[s.index].prevState=s,e.Log(e.GetStackTrace(),"gamepad: "+s.id+" connected",6),window.requestAnimationFrame((()=>this.updateStatus())),this.onGamepadConnected()}gamePadDisconnectHandler(t){e.Log(e.GetStackTrace(),"Gamepad disconnect handler",6),e.Log(e.GetStackTrace(),"gamepad: "+t.gamepad.id+" disconnected",6);const s=this.controllers[t.gamepad.index];delete this.controllers[t.gamepad.index],this.controllers=this.controllers.filter((e=>void 0!==e)),this.onGamepadDisconnected(s.id)}scanGamePads(){const e=navigator.getGamepads?navigator.getGamepads():navigator.webkitGetGamepads?navigator.webkitGetGamepads():[];for(let t=0;t<e.length;t++)e[t]&&e[t].index in this.controllers&&(this.controllers[e[t].index].currentState=e[t])}updateStatus(){this.scanGamePads();const e=this.toStreamerMessagesProvider.toStreamerHandlers;for(const t of this.controllers){const s=void 0===t.id?this.controllers.indexOf(t):t.id,n=t.currentState;for(let n=0;n<t.currentState.buttons.length;n++){const r=t.currentState.buttons[n],i=t.prevState.buttons[n];r.pressed?n==De.LeftTrigger?e.get("GamepadAnalog")([s,5,r.value]):n==De.RightTrigger?e.get("GamepadAnalog")([s,6,r.value]):e.get("GamepadButtonPressed")([s,n,i.pressed?1:0]):!r.pressed&&i.pressed&&(n==De.LeftTrigger?e.get("GamepadAnalog")([s,5,0]):n==De.RightTrigger?e.get("GamepadAnalog")([s,6,0]):e.get("GamepadButtonReleased")([s,n]))}for(let t=0;t<n.axes.length;t+=2){const r=parseFloat(n.axes[t].toFixed(4)),i=-parseFloat(n.axes[t+1].toFixed(4));e.get("GamepadAnalog")([s,t+1,r]),e.get("GamepadAnalog")([s,t+2,i])}this.controllers[s].prevState=n}this.controllers.length>0&&this.requestAnimationFrame((()=>this.updateStatus()))}onGamepadResponseReceived(e){for(const t of this.controllers)if(void 0===t.id){t.id=e;break}}onGamepadConnected(){}onGamepadDisconnected(e){}}!function(e){e[e.RightClusterBottomButton=0]="RightClusterBottomButton",e[e.RightClusterRightButton=1]="RightClusterRightButton",e[e.RightClusterLeftButton=2]="RightClusterLeftButton",e[e.RightClusterTopButton=3]="RightClusterTopButton",e[e.LeftShoulder=4]="LeftShoulder",e[e.RightShoulder=5]="RightShoulder",e[e.LeftTrigger=6]="LeftTrigger",e[e.RightTrigger=7]="RightTrigger",e[e.SelectOrBack=8]="SelectOrBack",e[e.StartOrForward=9]="StartOrForward",e[e.LeftAnalogPress=10]="LeftAnalogPress",e[e.RightAnalogPress=11]="RightAnalogPress",e[e.LeftClusterTopButton=12]="LeftClusterTopButton",e[e.LeftClusterBottomButton=13]="LeftClusterBottomButton",e[e.LeftClusterLeftButton=14]="LeftClusterLeftButton",e[e.LeftClusterRightButton=15]="LeftClusterRightButton",e[e.CentreButton=16]="CentreButton",e[e.LeftStickHorizontal=0]="LeftStickHorizontal",e[e.LeftStickVertical=1]="LeftStickVertical",e[e.RightStickHorizontal=2]="RightStickHorizontal",e[e.RightStickVertical=3]="RightStickVertical"}(De||(De={}));class st{constructor(e,t,s){this.activeKeys=new nt,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s}registerKeyBoard(t){e.Log(e.GetStackTrace(),"Register Keyboard Events",7);const s=new je(this.toStreamerMessagesProvider,t,this.activeKeys);return s.registerKeyBoardEvents(),s}registerMouse(t){e.Log(e.GetStackTrace(),"Register Mouse Events",7);const s=new Ze(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter,this.activeKeys);switch(t){case fe.LockedMouse:s.registerLockedMouseEvents(s);break;case fe.HoveringMouse:s.registerHoveringMouseEvents(s);break;default:e.Info(e.GetStackTrace(),"unknown Control Scheme Type Defaulting to Locked Mouse Events"),s.registerLockedMouseEvents(s)}return s}registerTouch(t,s){if(e.Log(e.GetStackTrace(),"Registering Touch",6),t){const e=new qe(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter);return e.setVideoElementParentClientRect(s),e}return new et(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter)}registerGamePad(){return e.Log(e.GetStackTrace(),"Register Game Pad",7),new tt(this.toStreamerMessagesProvider)}}class nt{constructor(){this.activeKeys=[],this.activeKeys=[]}getActiveKeys(){return this.activeKeys}}class rt{constructor(e,t){this.lastTimeResized=(new Date).getTime(),this.videoElement=document.createElement("video"),this.config=t,this.videoElement.id="streamingVideo",this.videoElement.disablePictureInPicture=!0,this.videoElement.playsInline=!0,this.videoElement.style.width="100%",this.videoElement.style.height="100%",this.videoElement.style.position="absolute",this.videoElement.style.pointerEvents="all",e.appendChild(this.videoElement),this.onResizePlayerCallback=()=>{console.log("Resolution changed, restyling player, did you forget to override this function?")},this.onMatchViewportResolutionCallback=()=>{console.log("Resolution changed and match viewport resolution is turned on, did you forget to override this function?")},this.videoElement.onclick=()=>{null!=this.audioElement&&this.audioElement.paused&&this.audioElement.play(),this.videoElement.paused&&this.videoElement.play()},this.videoElement.onloadedmetadata=()=>{this.onVideoInitialized()},window.addEventListener("resize",(()=>this.resizePlayerStyle()),!0),window.addEventListener("orientationchange",(()=>this.onOrientationChange()))}setAudioElement(e){this.audioElement=e}play(){return this.videoElement.muted=this.config.isFlagEnabled(ce.StartVideoMuted),this.videoElement.autoplay=this.config.isFlagEnabled(ce.AutoPlayVideo),this.videoElement.play()}isPaused(){return this.videoElement.paused}isVideoReady(){return void 0!==this.videoElement.readyState&&this.videoElement.readyState>0}hasVideoSource(){return void 0!==this.videoElement.srcObject&&null!==this.videoElement.srcObject}getVideoElement(){return this.videoElement}getVideoParentElement(){return this.videoElement.parentElement}setVideoEnabled(e){this.videoElement.srcObject.getTracks().forEach((t=>t.enabled=e))}onVideoInitialized(){}onOrientationChange(){clearTimeout(this.orientationChangeTimeout),this.orientationChangeTimeout=window.setTimeout((()=>{this.resizePlayerStyle()}),500)}resizePlayerStyle(){const e=this.getVideoParentElement();e&&(this.updateVideoStreamSize(),e.classList.contains("fixed-size")||this.resizePlayerStyleToFillParentElement(),this.onResizePlayerCallback())}resizePlayerStyleToFillParentElement(){this.getVideoParentElement().setAttribute("style","top: 0px; left: 0px; width: 100%; height: 100%; cursor: default;")}updateVideoStreamSize(){if(this.config.isFlagEnabled(ce.MatchViewportResolution))if((new Date).getTime()-this.lastTimeResized>300){const e=this.getVideoParentElement();if(!e)return;this.onMatchViewportResolutionCallback(e.clientWidth,e.clientHeight),this.lastTimeResized=(new Date).getTime()}else e.Log(e.GetStackTrace(),"Resizing too often - skipping",6),clearTimeout(this.resizeTimeoutHandle),this.resizeTimeoutHandle=window.setTimeout((()=>this.updateVideoStreamSize()),100)}}class it{constructor(){this.toStreamerHandlers=new Map,this.fromStreamerHandlers=new Map,this.toStreamerMessages=new Map,this.fromStreamerMessages=new Map}populateDefaultProtocol(){this.toStreamerMessages.set("IFrameRequest",{id:0,structure:[]}),this.toStreamerMessages.set("RequestQualityControl",{id:1,structure:[]}),this.toStreamerMessages.set("FpsRequest",{id:2,structure:[]}),this.toStreamerMessages.set("AverageBitrateRequest",{id:3,structure:[]}),this.toStreamerMessages.set("StartStreaming",{id:4,structure:[]}),this.toStreamerMessages.set("StopStreaming",{id:5,structure:[]}),this.toStreamerMessages.set("LatencyTest",{id:6,structure:["string"]}),this.toStreamerMessages.set("RequestInitialSettings",{id:7,structure:[]}),this.toStreamerMessages.set("TestEcho",{id:8,structure:[]}),this.toStreamerMessages.set("DataChannelLatencyTest",{id:9,structure:[]}),this.toStreamerMessages.set("UIInteraction",{id:50,structure:["string"]}),this.toStreamerMessages.set("Command",{id:51,structure:["string"]}),this.toStreamerMessages.set("KeyDown",{id:60,structure:["uint8","uint8"]}),this.toStreamerMessages.set("KeyUp",{id:61,structure:["uint8"]}),this.toStreamerMessages.set("KeyPress",{id:62,structure:["uint16"]}),this.toStreamerMessages.set("MouseEnter",{id:70,structure:[]}),this.toStreamerMessages.set("MouseLeave",{id:71,structure:[]}),this.toStreamerMessages.set("MouseDown",{id:72,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.set("MouseUp",{id:73,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.set("MouseMove",{id:74,structure:["uint16","uint16","int16","int16"]}),this.toStreamerMessages.set("MouseWheel",{id:75,structure:["int16","uint16","uint16"]}),this.toStreamerMessages.set("MouseDouble",{id:76,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.set("TouchStart",{id:80,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.set("TouchEnd",{id:81,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.set("TouchMove",{id:82,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.set("GamepadConnected",{id:93,structure:[]}),this.toStreamerMessages.set("GamepadButtonPressed",{id:90,structure:["uint8","uint8","uint8"]}),this.toStreamerMessages.set("GamepadButtonReleased",{id:91,structure:["uint8","uint8","uint8"]}),this.toStreamerMessages.set("GamepadAnalog",{id:92,structure:["uint8","uint8","double"]}),this.toStreamerMessages.set("GamepadDisconnected",{id:94,structure:["uint8"]}),this.fromStreamerMessages.set(0,"QualityControlOwnership"),this.fromStreamerMessages.set(1,"Response"),this.fromStreamerMessages.set(2,"Command"),this.fromStreamerMessages.set(3,"FreezeFrame"),this.fromStreamerMessages.set(4,"UnfreezeFrame"),this.fromStreamerMessages.set(5,"VideoEncoderAvgQP"),this.fromStreamerMessages.set(6,"LatencyTest"),this.fromStreamerMessages.set(7,"InitialSettings"),this.fromStreamerMessages.set(8,"FileExtension"),this.fromStreamerMessages.set(9,"FileMimeType"),this.fromStreamerMessages.set(10,"FileContents"),this.fromStreamerMessages.set(11,"TestEcho"),this.fromStreamerMessages.set(12,"InputControlOwnership"),this.fromStreamerMessages.set(13,"GamepadResponse"),this.fromStreamerMessages.set(14,"DataChannelLatencyTest"),this.fromStreamerMessages.set(255,"Protocol")}registerMessageHandler(t,s,n){switch(t){case Oe.ToStreamer:this.toStreamerHandlers.set(s,n);break;case Oe.FromStreamer:this.fromStreamerHandlers.set(s,n);break;default:e.Log(e.GetStackTrace(),`Unknown message direction ${t}`)}}}!function(e){e[e.ToStreamer=0]="ToStreamer",e[e.FromStreamer=1]="FromStreamer"}(Oe||(Oe={}));class ot{constructor(){this.responseEventListeners=new Map}addResponseEventListener(e,t){this.responseEventListeners.set(e,t)}removeResponseEventListener(e){this.responseEventListeners.delete(e)}onResponse(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.Response",6);const s=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),s,6),this.responseEventListeners.forEach((e=>{e(s)}))}}class at{constructor(e,t){this.dataChannelSender=e,this.toStreamerMessagesMapProvider=t}sendMessageToStreamer(t,s){void 0===s&&(s=[]);const n=this.toStreamerMessagesMapProvider.toStreamerMessages.get(t);if(void 0===n)return void e.Error(e.GetStackTrace(),`Attempted to send a message to the streamer with message type: ${t}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`);if(n.structure&&s&&n.structure.length!==s.length)return void e.Error(e.GetStackTrace(),`Provided message data doesn't match expected layout. Expected [ ${n.structure.map((e=>{switch(e){case"uint8":case"uint16":case"int16":case"float":case"double":return"number";case"string":return"string"}})).toString()} ] but received [ ${s.map((e=>typeof e)).toString()} ]`);let r=0;const i=new TextEncoder;s.forEach(((e,t)=>{switch(n.structure[t]){case"uint8":r+=1;break;case"uint16":case"int16":r+=2;break;case"float":r+=4;break;case"double":r+=8;break;case"string":r+=2,r+=2*i.encode(e).length}}));const o=new DataView(new ArrayBuffer(r+1));o.setUint8(0,n.id);let a=1;s.forEach(((e,t)=>{switch(n.structure[t]){case"uint8":o.setUint8(a,e),a+=1;break;case"uint16":o.setUint16(a,e,!0),a+=2;break;case"int16":o.setInt16(a,e,!0),a+=2;break;case"float":o.setFloat32(a,e,!0),a+=4;break;case"double":o.setFloat64(a,e,!0),a+=8;break;case"string":o.setUint16(a,e.length,!0),a+=2;for(let t=0;t<e.length;t++)o.setUint16(a,e.charCodeAt(t),!0),a+=2}})),this.dataChannelSender.canSend()?this.dataChannelSender.sendData(o.buffer):e.Info(e.GetStackTrace(),`Data channel cannot send yet, skipping sending message: ${t} - ${new Uint8Array(o.buffer)}`)}}class lt{constructor(e){this.sendMessageController=e}SendRequestQualityControl(){this.sendMessageController.sendMessageToStreamer("RequestQualityControl")}SendMaxFpsRequest(){this.sendMessageController.sendMessageToStreamer("FpsRequest")}SendAverageBitrateRequest(){this.sendMessageController.sendMessageToStreamer("AverageBitrateRequest")}SendStartStreaming(){this.sendMessageController.sendMessageToStreamer("StartStreaming")}SendStopStreaming(){this.sendMessageController.sendMessageToStreamer("StopStreaming")}SendRequestInitialSettings(){this.sendMessageController.sendMessageToStreamer("RequestInitialSettings")}}class dt{constructor(e){this.dataChannelProvider=e}canSend(){return void 0!==this.dataChannelProvider.getDataChannelInstance().dataChannel&&"open"==this.dataChannelProvider.getDataChannelInstance().dataChannel.readyState}sendData(t){const s=this.dataChannelProvider.getDataChannelInstance();"open"==s.dataChannel.readyState?(s.dataChannel.send(t),e.Log(e.GetStackTrace(),`Message Sent: ${new Uint8Array(t)}`,6),this.resetAfkWarningTimerOnDataSend()):e.Error(e.GetStackTrace(),`Message Failed: ${new Uint8Array(t)}`)}resetAfkWarningTimerOnDataSend(){}}class ct{constructor(e){this.videoElementProvider=e,this.normalizeAndQuantizeUnsignedFunc=()=>{throw new Error("Normalize and quantize unsigned, method not implemented.")},this.normalizeAndQuantizeSignedFunc=()=>{throw new Error("Normalize and unquantize signed, method not implemented.")},this.denormalizeAndUnquantizeUnsignedFunc=()=>{throw new Error("Denormalize and unquantize unsigned, method not implemented.")}}normalizeAndQuantizeUnsigned(e,t){return this.normalizeAndQuantizeUnsignedFunc(e,t)}unquantizeAndDenormalizeUnsigned(e,t){return this.denormalizeAndUnquantizeUnsignedFunc(e,t)}normalizeAndQuantizeSigned(e,t){return this.normalizeAndQuantizeSignedFunc(e,t)}setupNormalizeAndQuantize(){if(this.videoElementParent=this.videoElementProvider.getVideoParentElement(),this.videoElement=this.videoElementProvider.getVideoElement(),this.videoElementParent&&this.videoElement){const t=this.videoElementParent.clientHeight/this.videoElementParent.clientWidth,s=this.videoElement.videoHeight/this.videoElement.videoWidth;t>s?(e.Log(e.GetStackTrace(),"Setup Normalize and Quantize for playerAspectRatio > videoAspectRatio",6),this.ratio=t/s,this.normalizeAndQuantizeUnsignedFunc=(e,t)=>this.normalizeAndQuantizeUnsignedPlayerBigger(e,t),this.normalizeAndQuantizeSignedFunc=(e,t)=>this.normalizeAndQuantizeSignedPlayerBigger(e,t),this.denormalizeAndUnquantizeUnsignedFunc=(e,t)=>this.denormalizeAndUnquantizeUnsignedPlayerBigger(e,t)):(e.Log(e.GetStackTrace(),"Setup Normalize and Quantize for playerAspectRatio <= videoAspectRatio",6),this.ratio=s/t,this.normalizeAndQuantizeUnsignedFunc=(e,t)=>this.normalizeAndQuantizeUnsignedPlayerSmaller(e,t),this.normalizeAndQuantizeSignedFunc=(e,t)=>this.normalizeAndQuantizeSignedPlayerSmaller(e,t),this.denormalizeAndUnquantizeUnsignedFunc=(e,t)=>this.denormalizeAndUnquantizeUnsignedPlayerSmaller(e,t))}}normalizeAndQuantizeUnsignedPlayerBigger(e,t){const s=e/this.videoElementParent.clientWidth,n=this.ratio*(t/this.videoElementParent.clientHeight-.5)+.5;return s<0||s>1||n<0||n>1?new ht(!1,65535,65535):new ht(!0,65536*s,65536*n)}denormalizeAndUnquantizeUnsignedPlayerBigger(e,t){const s=e/65536,n=(t/65536-.5)/this.ratio+.5;return new gt(s*this.videoElementParent.clientWidth,n*this.videoElementParent.clientHeight)}normalizeAndQuantizeSignedPlayerBigger(e,t){const s=e/(.5*this.videoElementParent.clientWidth),n=this.ratio*t/(.5*this.videoElementParent.clientHeight);return new ut(32767*s,32767*n)}normalizeAndQuantizeUnsignedPlayerSmaller(e,t){const s=this.ratio*(e/this.videoElementParent.clientWidth-.5)+.5,n=t/this.videoElementParent.clientHeight;return s<0||s>1||n<0||n>1?new ht(!1,65535,65535):new ht(!0,65536*s,65536*n)}denormalizeAndUnquantizeUnsignedPlayerSmaller(e,t){const s=(e/65536-.5)/this.ratio+.5,n=t/65536;return new gt(s*this.videoElementParent.clientWidth,n*this.videoElementParent.clientHeight)}normalizeAndQuantizeSignedPlayerSmaller(e,t){const s=this.ratio*e/(.5*this.videoElementParent.clientWidth),n=t/(.5*this.videoElementParent.clientHeight);return new ut(32767*s,32767*n)}}class ht{constructor(e,t,s){this.inRange=e,this.x=t,this.y=s}}class gt{constructor(e,t){this.x=e,this.y=t}}class ut{constructor(e,t){this.x=e,this.y=t}}class mt{constructor(e,t){this.shouldShowPlayOverlay=!0,this.autoJoinTimer=void 0,this.config=e,this.pixelStreaming=t,this.responseController=new ot,this.file=new Ve,this.sdpConstraints={offerToReceiveAudio:!0,offerToReceiveVideo:!0},this.afkController=new Te(this.config,this.pixelStreaming,this.onAfkTriggered.bind(this)),this.afkController.onAFKTimedOutCallback=()=>{this.closeSignalingServer("You have been disconnected due to inactivity")},this.freezeFrameController=new y(this.pixelStreaming.videoElementParent),this.videoPlayer=new rt(this.pixelStreaming.videoElementParent,this.config),this.videoPlayer.onVideoInitialized=()=>this.handleVideoInitialized(),this.videoPlayer.onMatchViewportResolutionCallback=(e,t)=>{const s={"Resolution.Width":e,"Resolution.Height":t};this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify(s)])},this.videoPlayer.onResizePlayerCallback=()=>{this.setUpMouseAndFreezeFrame()},this.streamController=new T(this.videoPlayer),this.coordinateConverter=new ct(this.videoPlayer),this.sendrecvDataChannelController=new Ee,this.recvDataChannelController=new Ee,this.registerDataChannelEventEmitters(this.sendrecvDataChannelController),this.registerDataChannelEventEmitters(this.recvDataChannelController),this.dataChannelSender=new dt(this.sendrecvDataChannelController),this.dataChannelSender.resetAfkWarningTimerOnDataSend=()=>this.afkController.resetAfkWarningTimer(),this.streamMessageController=new it,this.webSocketController=new f,this.webSocketController.onConfig=e=>this.handleOnConfigMessage(e),this.webSocketController.onStreamerList=e=>this.handleStreamerListMessage(e),this.webSocketController.onPlayerCount=e=>{this.pixelStreaming._onPlayerCount(e.count)},this.webSocketController.onOpen.addEventListener("open",(()=>{this.config.isFlagEnabled(ce.BrowserSendOffer)||this.webSocketController.requestStreamerObject(sessionStorage.getItem("streamerName"))})),this.webSocketController.onClose.addEventListener("close",(e=>{const t=this.shouldReconnect&&1001!=e.detail.code&&this.config.getNumericSettingValue(ge.MaxReconnectAttempts)>0,s=this.disconnectMessage?this.disconnectMessage:e.detail.reason;this.pixelStreaming._onDisconnect(s,!t&&!this.isReconnecting),this.afkController.stopAfkWarningTimer(),this.statsTimerHandle&&void 0!==this.statsTimerHandle&&window.clearInterval(this.statsTimerHandle),this.setVideoEncoderAvgQP(0),this.setTouchInputEnabled(!1),this.setMouseInputEnabled(!1),this.setKeyboardInputEnabled(!1),this.setGamePadInputEnabled(!1),t&&setTimeout((()=>{this.isReconnecting=!0,this.reconnectAttempt++,this.tryReconnect(e.detail.reason)}),2e3)})),this.sendMessageController=new at(this.dataChannelSender,this.streamMessageController),this.toStreamerMessagesController=new lt(this.sendMessageController),this.registerMessageHandlers(),this.streamMessageController.populateDefaultProtocol(),this.inputClassesFactory=new st(this.streamMessageController,this.videoPlayer,this.coordinateConverter),this.isUsingSFU=!1,this.isQualityController=!1,this.preferredCodec="",this.shouldReconnect=!0,this.isReconnecting=!1,this.reconnectAttempt=0,this.config._addOnOptionSettingChangedListener(pe.StreamerId,(e=>{""!==e&&(this.peerConnectionController.peerConnection.close(),this.peerConnectionController.createPeerConnection(this.peerConfig,this.preferredCodec),this.subscribedStream=e,this.webSocketController.sendSubscribe(e))})),this.setVideoEncoderAvgQP(-1),this.signallingUrlBuilder=()=>{let e=this.config.getTextSettingValue(me.SignallingServerUrl);return this.config.isFlagEnabled(ce.BrowserSendOffer)&&(e+="?"+ce.BrowserSendOffer+"=true"),e}}requestUnquantizedAndDenormalizeUnsigned(e,t){return this.coordinateConverter.unquantizeAndDenormalizeUnsigned(e,t)}handleOnMessage(t){const s=new Uint8Array(t.data);e.Log(e.GetStackTrace(),"Message incoming:"+s,6);const n=this.streamMessageController.fromStreamerMessages.get(s[0]);this.streamMessageController.fromStreamerHandlers.get(n)(t.data)}registerMessageHandlers(){this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"QualityControlOwnership",(e=>this.onQualityControlOwnership(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"Response",(e=>this.responseController.onResponse(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"Command",(e=>{this.onCommand(e)})),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"FreezeFrame",(e=>this.onFreezeFrameMessage(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"UnfreezeFrame",(()=>this.invalidateFreezeFrameAndEnableVideo())),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"VideoEncoderAvgQP",(e=>this.handleVideoEncoderAvgQP(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"LatencyTest",(e=>this.handleLatencyTestResult(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"DataChannelLatencyTest",(e=>this.handleDataChannelLatencyTestResponse(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"InitialSettings",(e=>this.handleInitialSettings(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"FileExtension",(e=>this.onFileExtension(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"FileMimeType",(e=>this.onFileMimeType(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"FileContents",(e=>this.onFileContents(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"TestEcho",(()=>{})),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"InputControlOwnership",(e=>this.onInputControlOwnership(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"GamepadResponse",(e=>this.onGamepadResponse(e))),this.streamMessageController.registerMessageHandler(Oe.FromStreamer,"Protocol",(e=>this.onProtocolMessage(e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"IFrameRequest",(()=>this.sendMessageController.sendMessageToStreamer("IFrameRequest"))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"RequestQualityControl",(()=>this.sendMessageController.sendMessageToStreamer("RequestQualityControl"))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"FpsRequest",(()=>this.sendMessageController.sendMessageToStreamer("FpsRequest"))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"AverageBitrateRequest",(()=>this.sendMessageController.sendMessageToStreamer("AverageBitrateRequest"))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"StartStreaming",(()=>this.sendMessageController.sendMessageToStreamer("StartStreaming"))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"StopStreaming",(()=>this.sendMessageController.sendMessageToStreamer("StopStreaming"))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"LatencyTest",(e=>this.sendMessageController.sendMessageToStreamer("LatencyTest",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"RequestInitialSettings",(()=>this.sendMessageController.sendMessageToStreamer("RequestInitialSettings"))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"TestEcho",(()=>{})),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"UIInteraction",(e=>this.sendMessageController.sendMessageToStreamer("UIInteraction",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"Command",(e=>this.sendMessageController.sendMessageToStreamer("Command",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"TextboxEntry",(e=>this.sendMessageController.sendMessageToStreamer("TextboxEntry",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"KeyDown",(e=>this.sendMessageController.sendMessageToStreamer("KeyDown",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"KeyUp",(e=>this.sendMessageController.sendMessageToStreamer("KeyUp",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"KeyPress",(e=>this.sendMessageController.sendMessageToStreamer("KeyPress",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"MouseEnter",(e=>this.sendMessageController.sendMessageToStreamer("MouseEnter",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"MouseLeave",(e=>this.sendMessageController.sendMessageToStreamer("MouseLeave",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"MouseDown",(e=>this.sendMessageController.sendMessageToStreamer("MouseDown",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"MouseUp",(e=>this.sendMessageController.sendMessageToStreamer("MouseUp",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"MouseMove",(e=>this.sendMessageController.sendMessageToStreamer("MouseMove",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"MouseWheel",(e=>this.sendMessageController.sendMessageToStreamer("MouseWheel",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"MouseDouble",(e=>this.sendMessageController.sendMessageToStreamer("MouseDouble",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"TouchStart",(e=>this.sendMessageController.sendMessageToStreamer("TouchStart",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"TouchEnd",(e=>this.sendMessageController.sendMessageToStreamer("TouchEnd",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"TouchMove",(e=>this.sendMessageController.sendMessageToStreamer("TouchMove",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"GamepadConnected",(()=>this.sendMessageController.sendMessageToStreamer("GamepadConnected"))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"GamepadButtonPressed",(e=>this.sendMessageController.sendMessageToStreamer("GamepadButtonPressed",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"GamepadButtonReleased",(e=>this.sendMessageController.sendMessageToStreamer("GamepadButtonReleased",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"GamepadAnalog",(e=>this.sendMessageController.sendMessageToStreamer("GamepadAnalog",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"GamepadDisconnected",(e=>this.sendMessageController.sendMessageToStreamer("GamepadDisconnected",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"XRHMDTransform",(e=>this.sendMessageController.sendMessageToStreamer("XRHMDTransform",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"XRControllerTransform",(e=>this.sendMessageController.sendMessageToStreamer("XRControllerTransform",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"XRSystem",(e=>this.sendMessageController.sendMessageToStreamer("XRSystem",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"XRButtonTouched",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonTouched",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"XRButtonPressed",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonPressed",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"XRButtonReleased",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonReleased",e))),this.streamMessageController.registerMessageHandler(Oe.ToStreamer,"XRAnalog",(e=>this.sendMessageController.sendMessageToStreamer("XRAnalog",e)))}onCommand(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.Command",6);const s=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),"Data Channel Command: "+s,6);const n=JSON.parse(s);"onScreenKeyboard"===n.command&&this.pixelStreaming._activateOnScreenKeyboard(n)}onProtocolMessage(t){try{const s=new TextDecoder("utf-16").decode(t.slice(1)),n=JSON.parse(s);Object.prototype.hasOwnProperty.call(n,"Direction")||e.Error(e.GetStackTrace(),"Malformed protocol received. Ensure the protocol message contains a direction");const r=n.Direction;delete n.Direction,e.Log(e.GetStackTrace(),`Received new ${r==Oe.FromStreamer?"FromStreamer":"ToStreamer"} protocol. Updating existing protocol...(更新现有协议)`),Object.keys(n).forEach((t=>{const s=n[t];switch(r){case Oe.ToStreamer:if(!Object.prototype.hasOwnProperty.call(s,"id"))return void e.Error(e.GetStackTrace(),`ToStreamer->${t} protocol definition was malformed as it didn't contain at least an id\n\n Definition was: ${JSON.stringify(s,null,2)}`);if("UIInteraction"===t||"Command"===t||"LatencyTest"===t)return;this.streamMessageController.toStreamerHandlers.get(t)?this.streamMessageController.toStreamerMessages.set(t,s):e.Error(e.GetStackTrace(),`There was no registered handler for "${t}" - try adding one using registerMessageHandler(MessageDirection.ToStreamer, "${t}", myHandler)`);break;case Oe.FromStreamer:if(!Object.prototype.hasOwnProperty.call(s,"id"))return void e.Error(e.GetStackTrace(),`FromStreamer->${t} protocol definition was malformed as it didn't contain at least an id\n\n Definition was: ${JSON.stringify(s,null,2)}`);this.streamMessageController.fromStreamerHandlers.get(t)?this.streamMessageController.fromStreamerMessages.set(s.id,t):e.Error(e.GetStackTrace(),`There was no registered handler for "${s}" - try adding one using registerMessageHandler(MessageDirection.FromStreamer, "${t}", myHandler)`);break;default:e.Error(e.GetStackTrace(),`Unknown direction: ${r}`)}})),this.toStreamerMessagesController.SendRequestInitialSettings(),this.toStreamerMessagesController.SendRequestQualityControl()}catch(t){e.Log(e.GetStackTrace(),t)}}onInputControlOwnership(t){const s=new Uint8Array(t);e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.InputControlOwnership",6);const n=new Boolean(s[1]).valueOf();e.Log(e.GetStackTrace(),`Received input controller message - will your input control the stream: ${n}`),this.pixelStreaming._onInputControlOwnership(n)}onGamepadResponse(e){const t=new TextDecoder("utf-16").decode(e.slice(1)),s=JSON.parse(t);this.gamePadController.onGamepadResponseReceived(s.controllerId)}onAfkTriggered(){this.afkController.onAfkClick(),this.videoPlayer.isPaused()&&this.videoPlayer.hasVideoSource()&&this.playStream()}setAfkEnabled(e){e?this.onAfkTriggered():this.afkController.stopAfkWarningTimer()}tryReconnect(t){this.webSocketController?(this.isReconnecting=!0,this.webSocketController.webSocket&&this.webSocketController.webSocket.readyState!=WebSocket.CLOSED?(this.closeSignalingServer(`${t} Restarting stream...`),setTimeout((()=>{this.tryReconnect(t)}),3e3)):(this.pixelStreaming._onWebRtcAutoConnect(),this.connectToSignallingServer())):e.Log(e.GetStackTrace(),"The Web Socket Controller does not exist so this will not work right now.")}loadFreezeFrameOrShowPlayOverlay(){this.pixelStreaming.dispatchEvent(new j({shouldShowPlayOverlay:this.shouldShowPlayOverlay,isValid:this.freezeFrameController.valid,jpegData:this.freezeFrameController.jpeg})),!0===this.shouldShowPlayOverlay?(e.Log(e.GetStackTrace(),"showing play overlay"),this.resizePlayerStyle()):(e.Log(e.GetStackTrace(),"showing freeze frame"),this.freezeFrameController.showFreezeFrame()),setTimeout((()=>{this.videoPlayer.setVideoEnabled(!1)}),this.freezeFrameController.freezeFrameDelay)}onFreezeFrameMessage(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.FreezeFrame",6);const s=new Uint8Array(t);this.freezeFrameController.processFreezeFrameMessage(s,(()=>this.loadFreezeFrameOrShowPlayOverlay()))}invalidateFreezeFrameAndEnableVideo(){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.FreezeFrame",6),setTimeout((()=>{this.pixelStreaming.dispatchEvent(new J),this.freezeFrameController.hideFreezeFrame()}),this.freezeFrameController.freezeFrameDelay),this.videoPlayer.getVideoElement()&&this.videoPlayer.setVideoEnabled(!0)}onFileExtension(e){const t=new Uint8Array(e);We.setExtensionFromBytes(t,this.file)}onFileMimeType(e){const t=new Uint8Array(e);We.setMimeTypeFromBytes(t,this.file)}onFileContents(e){const t=new Uint8Array(e);We.setContentsFromBytes(t,this.file)}playStream(){if(!this.videoPlayer.getVideoElement()){const t="Could not play video stream because the video player was not initialized correctly.";return this.pixelStreaming.dispatchEvent(new q({message:t})),e.Error(e.GetStackTrace(),t),void this.closeSignalingServer("Stream not initialized correctly")}if(this.videoPlayer.hasVideoSource()){if(this.setTouchInputEnabled(this.config.isFlagEnabled(ce.TouchInput)),this.pixelStreaming.dispatchEvent(new $),this.streamController.audioElement.srcObject){const t=this.config.isFlagEnabled(ce.StartVideoMuted);this.streamController.audioElement.muted=t,t?this.playVideo():this.streamController.audioElement.play().then((()=>{this.playVideo()})).catch((t=>{e.Log(e.GetStackTrace(),t),e.Log(e.GetStackTrace(),"Browser does not support autoplaying video without interaction - to resolve this we are going to show the play button overlay."),this.pixelStreaming.dispatchEvent(new X({reason:t}))}))}else this.playVideo();this.shouldShowPlayOverlay=!1,this.freezeFrameController.showFreezeFrame()}else e.Warning(e.GetStackTrace(),"Cannot play stream, the video element has no srcObject to play.")}playVideo(){this.videoPlayer.play().catch((t=>{this.streamController.audioElement.srcObject&&this.streamController.audioElement.pause(),e.Log(e.GetStackTrace(),t),e.Log(e.GetStackTrace(),"Browser does not support autoplaying video without interaction - to resolve this we are going to show the play button overlay."),this.pixelStreaming.dispatchEvent(new X({reason:t}))}))}autoPlayVideoOrSetUpPlayOverlay(){this.config.isFlagEnabled(ce.AutoPlayVideo)&&this.playStream(),this.resizePlayerStyle()}connectToSignallingServer(){this.locallyClosed=!1,this.shouldReconnect=!0,this.disconnectMessage=null;const e=this.signallingUrlBuilder();this.webSocketController.connect(e)}startSession(t){if(this.peerConfig=t,this.config.isFlagEnabled(ce.ForceTURN)&&!this.checkTurnServerAvailability(t))return e.Info(e.GetStackTrace(),"No turn server was found in the Peer Connection Options. TURN cannot be forced, closing connection. Please use STUN instead"),void this.closeSignalingServer("TURN cannot be forced, closing connection. Please use STUN instead.");this.peerConnectionController=new Ge(this.peerConfig,this.config,this.preferredCodec),this.peerConnectionController.onVideoStats=e=>this.handleVideoStats(e),this.peerConnectionController.onSendWebRTCOffer=e=>this.handleSendWebRTCOffer(e),this.peerConnectionController.onSendWebRTCAnswer=e=>this.handleSendWebRTCAnswer(e),this.peerConnectionController.onPeerIceCandidate=e=>this.handleSendIceCandidate(e),this.peerConnectionController.onDataChannel=e=>this.handleDataChannel(e),this.peerConnectionController.showTextOverlayConnecting=()=>this.pixelStreaming._onWebRtcConnecting(),this.peerConnectionController.showTextOverlaySetupFailure=()=>this.pixelStreaming._onWebRtcFailed();let s=!1;this.peerConnectionController.onIceConnectionStateChange=()=>{!s&&["connected","completed"].includes(this.peerConnectionController.peerConnection.iceConnectionState)&&(this.pixelStreaming._onWebRtcConnected(),s=!0)},this.peerConnectionController.onTrack=e=>this.streamController.handleOnTrack(e),this.config.isFlagEnabled(ce.BrowserSendOffer)&&(this.sendrecvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,"cirrus",this.datachannelOptions),this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e),this.peerConnectionController.createOffer(this.sdpConstraints,this.config))}checkTurnServerAvailability(t){if(!t.iceServers)return e.Info(e.GetStackTrace(),"A turn sever was not found"),!1;for(const s of t.iceServers)for(const t of s.urls)if(t.includes("turn"))return e.Log(e.GetStackTrace(),`A turn sever was found at ${t}`),!0;return e.Info(e.GetStackTrace(),"A turn sever was not found"),!1}handleOnConfigMessage(e){this.resizePlayerStyle(),this.startSession(e.peerConnectionOptions),this.webSocketController.onWebRtcAnswer=e=>this.handleWebRtcAnswer(e),this.webSocketController.onWebRtcOffer=e=>this.handleWebRtcOffer(e),this.webSocketController.onWebRtcPeerDataChannels=e=>this.handleWebRtcSFUPeerDatachannels(e),this.webSocketController.onIceCandidate=e=>this.handleIceCandidate(e)}handleStreamerListMessage(t){var s;console.log(t,"====="),e.Log(e.GetStackTrace(),`Got streamer list ${t.ids}`,6);const n=null!==(s=t.streamerBusyList)&&void 0!==s?s:[];if(n.length>0){if(console.log(window.location.href,"======"),-1!==window.location.href.indexOf("home"))return;window.confirm("监测到当前窗口有人在使用,是否强制进入?")&&this.webSocketController.sendSubscribe(n[0].streamerId)}const r=[...t.ids];console.log(r),this.config.setOptionSettingOptions(pe.StreamerId,r);let i=null,o=null;const a=this.config.isFlagEnabled(ce.WaitForStreamer),l=this.config.getNumericSettingValue(ge.MaxReconnectAttempts),d=this.config.getNumericSettingValue(ge.StreamerAutoJoinInterval),c=new URLSearchParams(window.location.search);c.has(pe.StreamerId)?i=c.get(pe.StreamerId):this.subscribedStream&&(i=this.subscribedStream),i&&t.ids.includes(i)?o=i:i&&a||1!=t.ids.length||(o=t.ids[0]),o?(this.isReconnecting=!1,this.reconnectAttempt=0,this.config.setOptionSettingValue(pe.StreamerId,o)):a&&(this.reconnectAttempt<l?(this.isReconnecting=!0,this.reconnectAttempt++,setTimeout((()=>{this.webSocketController.requestStreamerList()}),d)):(this.reconnectAttempt=0,this.isReconnecting=!1,this.shouldReconnect=!1)),this.pixelStreaming.dispatchEvent(new Z({messageStreamerList:t,autoSelectedStreamerId:o,wantedStreamerId:i}))}handleWebRtcAnswer(t){e.Log(e.GetStackTrace(),`Got answer sdp ${t.sdp}`,6);const s={sdp:t.sdp,type:"answer"};this.peerConnectionController.receiveAnswer(s),this.handlePostWebrtcNegotiation()}handleWebRtcOffer(t){e.Log(e.GetStackTrace(),`Got offer sdp ${t.sdp}`,6),this.isUsingSFU=!!t.sfu&&t.sfu,this.isUsingSFU&&(this.peerConnectionController.preferredCodec="");const s={sdp:t.sdp,type:"offer"};this.peerConnectionController.receiveOffer(s,this.config),this.handlePostWebrtcNegotiation()}handleWebRtcSFUPeerDatachannels(e){const t={ordered:!0,negotiated:!0,id:e.sendStreamId},s=e.sendStreamId!=e.recvStreamId;if(this.sendrecvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,s?"send-datachannel":"datachannel",t),s){const t={ordered:!0,negotiated:!0,id:e.recvStreamId};this.recvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,"recv-datachannel",t),this.recvDataChannelController.handleOnOpen=()=>this.webSocketController.sendSFURecvDataChannelReady(),this.recvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}else this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}handlePostWebrtcNegotiation(){this.afkController.startAfkWarningTimer(),this.pixelStreaming._onWebRtcSdp(),this.statsTimerHandle&&void 0!==this.statsTimerHandle&&window.clearInterval(this.statsTimerHandle),this.statsTimerHandle=window.setInterval((()=>this.getStats()),1e3),this.setMouseInputEnabled(this.config.isFlagEnabled(ce.MouseInput)),this.setKeyboardInputEnabled(this.config.isFlagEnabled(ce.KeyboardInput)),this.setGamePadInputEnabled(this.config.isFlagEnabled(ce.GamepadInput))}handleIceCandidate(t){e.Log(e.GetStackTrace(),"Web RTC Controller: onWebRtcIce",6);const s=new RTCIceCandidate(t);this.peerConnectionController.handleOnIce(s)}handleSendIceCandidate(t){e.Log(e.GetStackTrace(),"OnIceCandidate",6),t.candidate&&t.candidate.candidate&&this.webSocketController.sendIceCandidate(t.candidate)}handleDataChannel(t){e.Log(e.GetStackTrace(),"Data channel created for us by browser as we are a receiving peer.",6),this.sendrecvDataChannelController.dataChannel=t.channel,this.sendrecvDataChannelController.setupDataChannel(),this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}handleSendWebRTCOffer(t){e.Log(e.GetStackTrace(),"Sending the offer to the Server",6),this.webSocketController.sendWebRtcOffer(t)}handleSendWebRTCAnswer(t){e.Log(e.GetStackTrace(),"Sending the answer to the Server",6),this.webSocketController.sendWebRtcAnswer(t),this.isUsingSFU&&this.webSocketController.sendWebRtcDatachannelRequest()}setUpMouseAndFreezeFrame(){this.videoElementParentClientRect=this.videoPlayer.getVideoParentElement().getBoundingClientRect(),this.coordinateConverter.setupNormalizeAndQuantize(),this.freezeFrameController.freezeFrame.resize()}closeSignalingServer(e){var t;this.locallyClosed=!0,this.shouldReconnect=!1,this.disconnectMessage=e,null===(t=this.webSocketController)||void 0===t||t.close()}closePeerConnection(){var e;null===(e=this.peerConnectionController)||void 0===e||e.close()}close(){this.closeSignalingServer(""),this.closePeerConnection()}getStats(){this.peerConnectionController.generateStats()}sendLatencyTest(){this.latencyStartTime=Date.now(),this.streamMessageController.toStreamerHandlers.get("LatencyTest")([JSON.stringify({StartTime:this.latencyStartTime})])}sendDataChannelLatencyTest(e){this.streamMessageController.toStreamerHandlers.get("DataChannelLatencyTest")([JSON.stringify(e)])}sendEncoderMinQP(t){e.Log(e.GetStackTrace(),`MinQP=${t}\n`,6),null!=t&&this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify({"Encoder.MinQP":t})])}sendEncoderMaxQP(t){e.Log(e.GetStackTrace(),`MaxQP=${t}\n`,6),null!=t&&this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify({"Encoder.MaxQP":t})])}sendWebRTCMinBitrate(t){e.Log(e.GetStackTrace(),`WebRTC Min Bitrate=${t}`,6),null!=t&&this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify({"WebRTC.MinBitrate":t})])}sendWebRTCMaxBitrate(t){e.Log(e.GetStackTrace(),`WebRTC Max Bitrate=${t}`,6),null!=t&&this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify({"WebRTC.MaxBitrate":t})])}sendWebRTCFps(t){e.Log(e.GetStackTrace(),`WebRTC FPS=${t}`,6),null!=t&&(this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify({"WebRTC.Fps":t})]),this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify({"WebRTC.MaxFps":t})]))}sendShowFps(){e.Log(e.GetStackTrace(),"---- Sending show stat to UE ----",6),this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify({"stat.fps":""})])}sendIframeRequest(){e.Log(e.GetStackTrace(),"---- Sending Request for an IFrame ----",6),this.streamMessageController.toStreamerHandlers.get("IFrameRequest")()}emitUIInteraction(t){e.Log(e.GetStackTrace(),"---- Sending custom UIInteraction message ----",6),this.streamMessageController.toStreamerHandlers.get("UIInteraction")([JSON.stringify(t)])}emitCommand(t){e.Log(e.GetStackTrace(),"---- Sending custom Command message ----",6),this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify(t)])}emitConsoleCommand(t){e.Log(e.GetStackTrace(),"---- Sending custom Command:ConsoleCommand message ----",6),this.streamMessageController.toStreamerHandlers.get("Command")([JSON.stringify({ConsoleCommand:t})])}sendRequestQualityControlOwnership(){e.Log(e.GetStackTrace(),"---- Sending Request to Control Quality ----",6),this.toStreamerMessagesController.SendRequestQualityControl()}handleLatencyTestResult(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.latencyTest",6);const s=new TextDecoder("utf-16").decode(t.slice(1)),n=new He;Object.assign(n,JSON.parse(s)),n.processFields(),n.testStartTimeMs=this.latencyStartTime,n.browserReceiptTimeMs=Date.now(),n.latencyExcludingDecode=~~(n.browserReceiptTimeMs-n.testStartTimeMs),n.testDuration=~~(n.TransmissionTimeMs-n.ReceiptTimeMs),n.networkLatency=~~(n.latencyExcludingDecode-n.testDuration),n.frameDisplayDeltaTimeMs&&n.browserReceiptTimeMs&&(n.endToEndLatency=(n.frameDisplayDeltaTimeMs,n.networkLatency,~~+n.CaptureToSendMs)),this.pixelStreaming._onLatencyTestResult(n)}handleDataChannelLatencyTestResponse(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.dataChannelLatencyResponse",6);const s=new TextDecoder("utf-16").decode(t.slice(1)),n=JSON.parse(s);this.pixelStreaming._onDataChannelLatencyTestResponse(n)}handleInitialSettings(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.InitialSettings",6);const s=new TextDecoder("utf-16").decode(t.slice(1)),n=JSON.parse(s),r=new Ue;n.Encoder&&(r.EncoderSettings=n.Encoder),n.WebRTC&&(r.WebRTCSettings=n.WebRTC),n.PixelStreaming&&(r.PixelStreamingSettings=n.PixelStreaming),n.ConfigOptions&&void 0!==n.ConfigOptions.DefaultToHover&&this.config.setFlagEnabled(ce.HoveringMouseMode,!!n.ConfigOptions.DefaultToHover),r.ueCompatible(),e.Log(e.GetStackTrace(),s,6),this.pixelStreaming._onInitialSettings(r)}handleVideoEncoderAvgQP(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.VideoEncoderAvgQP",6);const s=Number(new TextDecoder("utf-16").decode(t.slice(1)));this.setVideoEncoderAvgQP(s)}handleVideoInitialized(){this.pixelStreaming._onVideoInitialized(),this.autoPlayVideoOrSetUpPlayOverlay(),this.resizePlayerStyle(),this.videoPlayer.updateVideoStreamSize()}onQualityControlOwnership(t){const s=new Uint8Array(t);e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.QualityControlOwnership",6),this.isQualityController=new Boolean(s[1]).valueOf(),e.Log(e.GetStackTrace(),`Received quality controller message, will control quality: ${this.isQualityController}`),this.pixelStreaming._onQualityControlOwnership(this.isQualityController)}handleVideoStats(e){this.pixelStreaming._onVideoStats(e)}resizePlayerStyle(){this.videoPlayer.resizePlayerStyle()}setPreferredCodec(e){this.preferredCodec=e,this.peerConnectionController&&(this.peerConnectionController.preferredCodec=e,this.peerConnectionController.updateCodecSelection=!1)}setVideoEncoderAvgQP(e){this.videoAvgQp=e,this.pixelStreaming._onVideoEncoderAvgQP(this.videoAvgQp)}setKeyboardInputEnabled(e){var t;null===(t=this.keyboardController)||void 0===t||t.unregisterKeyBoardEvents(),e&&(this.keyboardController=this.inputClassesFactory.registerKeyBoard(this.config))}setMouseInputEnabled(e){var t;if(null===(t=this.mouseController)||void 0===t||t.unregisterMouseEvents(),e){const e=this.config.isFlagEnabled(ce.HoveringMouseMode)?fe.HoveringMouse:fe.LockedMouse;this.mouseController=this.inputClassesFactory.registerMouse(e)}}setTouchInputEnabled(e){var t;null===(t=this.touchController)||void 0===t||t.unregisterTouchEvents(),e&&(this.touchController=this.inputClassesFactory.registerTouch(this.config.isFlagEnabled(ce.FakeMouseWithTouches),this.videoElementParentClientRect))}setGamePadInputEnabled(e){var t;null===(t=this.gamePadController)||void 0===t||t.unregisterGamePadEvents(),e&&(this.gamePadController=this.inputClassesFactory.registerGamePad(),this.gamePadController.onGamepadConnected=()=>{this.streamMessageController.toStreamerHandlers.get("GamepadConnected")()},this.gamePadController.onGamepadDisconnected=e=>{this.streamMessageController.toStreamerHandlers.get("GamepadDisconnected")([e])})}registerDataChannelEventEmitters(e){e.onOpen=(e,t)=>this.pixelStreaming.dispatchEvent(new B({label:e,event:t})),e.onClose=(e,t)=>this.pixelStreaming.dispatchEvent(new _({label:e,event:t})),e.onError=(e,t)=>this.pixelStreaming.dispatchEvent(new H({label:e,event:t}))}registerMessageHandler(t,s,n){s===Oe.FromStreamer&&void 0===n&&e.Warning(e.GetStackTrace(),`Unable to register handler for ${t} as no handler was passed`),this.streamMessageController.registerMessageHandler(s,t,(e=>void 0===n&&s===Oe.ToStreamer?this.sendMessageController.sendMessageToStreamer(t,e):n(e)))}}class St{static vertexShader(){return"\n\t\tattribute vec2 a_position;\n\t\tattribute vec2 a_texCoord;\n\n\t\t// input\n\t\tuniform vec2 u_resolution;\n\t\tuniform vec4 u_offset;\n\n\t\t//\n\t\tvarying vec2 v_texCoord;\n\n\t\tvoid main() {\n\t\t // convert the rectangle from pixels to 0.0 to 1.0\n\t\t vec2 zeroToOne = a_position / u_resolution;\n\n\t\t // convert from 0->1 to 0->2\n\t\t vec2 zeroToTwo = zeroToOne * 2.0;\n\n\t\t // convert from 0->2 to -1->+1 (clipspace)\n\t\t vec2 clipSpace = zeroToTwo - 1.0;\n\n\t\t gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n\t\t // pass the texCoord to the fragment shader\n\t\t // The GPU will interpolate this value between points.\n\t\t v_texCoord = (a_texCoord * u_offset.xy) + u_offset.zw;\n\t\t}\n\t\t"}static fragmentShader(){return"\n\t\tprecision mediump float;\n\n\t\t// our texture\n\t\tuniform sampler2D u_image;\n\n\t\t// the texCoords passed in from the vertex shader.\n\t\tvarying vec2 v_texCoord;\n\n\t\tvoid main() {\n\t\t gl_FragColor = texture2D(u_image, v_texCoord);\n\t\t}\n\t\t"}}class pt{static deepCopyGamepad(e){return JSON.parse(JSON.stringify({buttons:e.buttons.map((e=>JSON.parse(JSON.stringify({pressed:e.pressed,touched:e.touched})))),axes:e.axes}))}}class vt{constructor(e){this.toStreamerMessagesProvider=e,this.controllers=[]}updateStatus(e,t,s){if(e.gamepad){const n=t.getPose(e.gripSpace,s);if(!n)return;let r=0;e.profiles.includes("htc-vive")?r=1:e.profiles.includes("oculus-touch")&&(r=2),this.toStreamerMessagesProvider.toStreamerHandlers.get("XRSystem")([r]);let i=2;switch(e.handedness){case"left":i=0;break;case"right":i=1}const o=n.transform.matrix,a=[];for(let e=0;e<16;e++)a[e]=new Float32Array([o[e]])[0];this.toStreamerMessagesProvider.toStreamerHandlers.get("XRControllerTransform")([a[0],a[4],a[8],a[12],a[1],a[5],a[9],a[13],a[2],a[6],a[10],a[14],a[3],a[7],a[11],a[15],i]),void 0===this.controllers[i]&&(this.controllers[i]={prevState:void 0,currentState:void 0,id:void 0},this.controllers[i].prevState=pt.deepCopyGamepad(e.gamepad)),this.controllers[i].currentState=pt.deepCopyGamepad(e.gamepad);const l=this.controllers[i],d=l.currentState,c=l.prevState;for(let e=0;e<d.buttons.length;e++){const t=d.buttons[e],s=c.buttons[e];t.pressed?this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonPressed")([i,e,s.pressed?1:0]):!t.pressed&&s.pressed&&this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonReleased")([i,e,0]),t.touched&&!t.pressed?this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonPressed")([i,3,s.touched?1:0]):!t.touched&&s.touched&&this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonReleased")([i,3,0])}for(let e=0;e<d.axes.length;e++)this.toStreamerMessagesProvider.toStreamerHandlers.get("XRAnalog")([i,e,d.axes[e]]);this.controllers[i].prevState=d}}}class Ct{constructor(e){this.xrSession=null,this.webRtcController=e,this.xrControllers=[],this.xrGamepadController=new vt(this.webRtcController.streamMessageController),this.onSessionEnded=new EventTarget,this.onSessionStarted=new EventTarget,this.onFrame=new EventTarget}xrClicked(){this.xrSession?this.xrSession.end():navigator.xr.requestSession("immersive-vr").then((e=>{this.onXrSessionStarted(e)}))}onXrSessionEnded(){e.Log(e.GetStackTrace(),"XR Session ended"),this.xrSession=null,this.onSessionEnded.dispatchEvent(new Event("xrSessionEnded"))}onXrSessionStarted(t){e.Log(e.GetStackTrace(),"XR Session started"),this.xrSession=t,this.xrSession.addEventListener("end",(()=>{this.onXrSessionEnded()}));const s=document.createElement("canvas");this.gl=s.getContext("webgl2",{xrCompatible:!0}),this.xrSession.updateRenderState({baseLayer:new XRWebGLLayer(this.xrSession,this.gl)});const n=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(n,St.vertexShader()),this.gl.compileShader(n);const r=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(r,St.fragmentShader()),this.gl.compileShader(r);const i=this.gl.createProgram();this.gl.attachShader(i,n),this.gl.attachShader(i,r),this.gl.linkProgram(i),this.gl.useProgram(i),this.positionLocation=this.gl.getAttribLocation(i,"a_position"),this.texcoordLocation=this.gl.getAttribLocation(i,"a_texCoord"),this.positionBuffer=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.enableVertexAttribArray(this.positionLocation);const o=this.gl.createTexture();this.gl.bindTexture(this.gl.TEXTURE_2D,o),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.NEAREST),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.NEAREST),this.texcoordBuffer=this.gl.createBuffer(),this.resolutionLocation=this.gl.getUniformLocation(i,"u_resolution"),this.offsetLocation=this.gl.getUniformLocation(i,"u_offset"),t.requestReferenceSpace("local").then((e=>{this.xrRefSpace=e,this.xrSession.requestAnimationFrame(((e,t)=>this.onXrFrame(e,t)))})),this.onSessionStarted.dispatchEvent(new Event("xrSessionStarted"))}onXrFrame(e,t){const s=t.getViewerPose(this.xrRefSpace);if(s){const e=s.transform.matrix,t=[];for(let s=0;s<16;s++)t[s]=new Float32Array([e[s]])[0];this.webRtcController.streamMessageController.toStreamerHandlers.get("XRHMDTransform")([t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15]]);const n=this.xrSession.renderState.baseLayer;this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,n.framebuffer),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,this.webRtcController.videoPlayer.getVideoElement()),this.render(this.webRtcController.videoPlayer.getVideoElement())}this.webRtcController.config.isFlagEnabled(ce.XRControllerInput)&&this.xrSession.inputSources.forEach(((e,s,n)=>{this.xrGamepadController.updateStatus(e,t,this.xrRefSpace)}),this),this.xrSession.requestAnimationFrame(((e,t)=>this.onXrFrame(e,t))),this.onFrame.dispatchEvent(new ae({time:e,frame:t}))}render(e){if(!this.gl)return;const t=this.xrSession.renderState.baseLayer;let s,n,r,i,o;this.gl.viewport(0,0,t.framebufferWidth,t.framebufferHeight),this.gl.uniform4f(this.offsetLocation,1,1,0,0),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array([0,0,e.videoWidth,0,0,e.videoHeight,0,e.videoHeight,e.videoWidth,0,e.videoWidth,e.videoHeight]),this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.texcoordBuffer),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1]),this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),s=2,n=this.gl.FLOAT,r=!1,i=0,o=0,this.gl.vertexAttribPointer(this.positionLocation,s,n,r,i,o),this.gl.enableVertexAttribArray(this.texcoordLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.texcoordBuffer),s=2,n=this.gl.FLOAT,r=!1,i=0,o=0,this.gl.vertexAttribPointer(this.texcoordLocation,s,n,r,i,o),this.gl.uniform2f(this.resolutionLocation,e.videoWidth,e.videoHeight);const a=this.gl.TRIANGLES;o=0,this.gl.drawArrays(a,o,6)}static isSessionSupported(e){return navigator.xr?navigator.xr.isSessionSupported(e):new Promise((()=>!1))}}class ft{constructor(e){this.editTextButton=null,this.hiddenInput=null,"ontouchstart"in document.documentElement&&this.createOnScreenKeyboardHelpers(e)}unquantizeAndDenormalizeUnsigned(e,t){return null}createOnScreenKeyboardHelpers(e){this.hiddenInput||(this.hiddenInput=document.createElement("input"),this.hiddenInput.id="hiddenInput",this.hiddenInput.maxLength=0,e.appendChild(this.hiddenInput)),this.editTextButton||(this.editTextButton=document.createElement("button"),this.editTextButton.id="editTextButton",this.editTextButton.innerHTML="edit text",e.appendChild(this.editTextButton),this.editTextButton.classList.add("hiddenState"),this.editTextButton.addEventListener("touchend",(e=>{this.hiddenInput.focus(),e.preventDefault()})))}showOnScreenKeyboard(e){if(e.showOnScreenKeyboard){this.editTextButton.classList.remove("hiddenState");const t=this.unquantizeAndDenormalizeUnsigned(e.x,e.y);this.editTextButton.style.top=t.y.toString()+"px",this.editTextButton.style.left=(t.x-40).toString()+"px"}else this.editTextButton.classList.add("hiddenState"),this.hiddenInput.blur()}}class Tt{constructor(e){this.seq=e.Seq,this.playerSentTimestamp=Date.now(),this.requestFillerSize=e.Filler?e.Filler.length:0}update(e){this.playerReceivedTimestamp=Date.now(),this.streamerReceivedTimestamp=e.ReceivedTimestamp,this.streamerSentTimestamp=e.SentTimestamp,this.responseFillerSize=e.Filler?e.Filler.length:0}}class Et{constructor(e,t){this.sink=e,this.callback=t,this.records=new Map,this.seq=0}start(e){return!this.isRunning()&&(this.startTime=Date.now(),this.records.clear(),this.interval=setInterval((()=>{Date.now()-this.startTime>=e.duration?this.stop():this.sendRequest(e.requestSize,e.responseSize)}).bind(this),Math.floor(1e3/e.rps)),!0)}stop(){this.interval&&(clearInterval(this.interval),this.interval=void 0,this.callback(this.produceResult()))}produceResult(){const e=new Map(this.records);return{records:e,dataChannelRtt:Math.ceil(Array.from(this.records.values()).reduce(((e,t)=>e+(t.playerReceivedTimestamp-t.playerSentTimestamp)),0)/this.records.size),playerToStreamerTime:Math.ceil(Array.from(this.records.values()).reduce(((e,t)=>e+(t.streamerReceivedTimestamp-t.playerSentTimestamp)),0)/this.records.size),streamerToPlayerTime:Math.ceil(Array.from(this.records.values()).reduce(((e,t)=>e+(t.playerReceivedTimestamp-t.streamerSentTimestamp)),0)/this.records.size),exportLatencyAsCSV:()=>{let t="Timestamp;RTT;PlayerToStreamer;StreamerToPlayer;\n";return e.forEach((e=>{t+=e.playerSentTimestamp+";",t+=e.playerReceivedTimestamp-e.playerSentTimestamp+";",t+=e.streamerReceivedTimestamp-e.playerSentTimestamp+";",t+=e.playerReceivedTimestamp-e.streamerSentTimestamp+";",t+="\n"})),t}}}isRunning(){return!!this.interval}receive(t){if(!this.isRunning())return;if(!t)return void e.Error(e.GetStackTrace(),"Undefined response from server");let s=this.records.get(t.Seq);s&&s.update(t)}sendRequest(e,t){let s=this.createRequest(e,t),n=new Tt(s);this.records.set(n.seq,n),this.sink(s)}createRequest(e,t){return{Seq:this.seq++,FillResponseSize:t,Filler:e?"A".repeat(e):""}}}class yt{constructor(e,t){this.allowConsoleCommands=!1,this.config=e,(null==t?void 0:t.videoElementParent)&&(this._videoElementParent=t.videoElementParent),this._eventEmitter=new de,this.configureSettings(),this.setWebRtcPlayerController(new mt(this.config,this)),this.onScreenKeyboardHelper=new ft(this.videoElementParent),this.onScreenKeyboardHelper.unquantizeAndDenormalizeUnsigned=(e,t)=>this._webRtcController.requestUnquantizedAndDenormalizeUnsigned(e,t),this._activateOnScreenKeyboard=e=>this.onScreenKeyboardHelper.showOnScreenKeyboard(e),this._webXrController=new Ct(this._webRtcController)}get videoElementParent(){return this._videoElementParent||(this._videoElementParent=document.createElement("div"),this._videoElementParent.id="videoElementParent"),this._videoElementParent}configureSettings(){this.config._addOnSettingChangedListener(ce.IsQualityController,(e=>{!0!==e||this._webRtcController.isQualityController||this._webRtcController.sendRequestQualityControlOwnership()})),this.config._addOnSettingChangedListener(ce.AFKDetection,(e=>{this._webRtcController.setAfkEnabled(e)})),this.config._addOnSettingChangedListener(ce.MatchViewportResolution,(()=>{this._webRtcController.videoPlayer.updateVideoStreamSize()})),this.config._addOnSettingChangedListener(ce.HoveringMouseMode,(e=>{this.config.setFlagLabel(ce.HoveringMouseMode,`Control Scheme: ${e?"Hovering":"Locked"} Mouse`),this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(ce.MouseInput))})),this.config._addOnSettingChangedListener(ce.KeyboardInput,(e=>{this._webRtcController.setKeyboardInputEnabled(e)})),this.config._addOnSettingChangedListener(ce.MouseInput,(e=>{this._webRtcController.setMouseInputEnabled(e)})),this.config._addOnSettingChangedListener(ce.TouchInput,(e=>{this._webRtcController.setTouchInputEnabled(e)})),this.config._addOnSettingChangedListener(ce.GamepadInput,(e=>{this._webRtcController.setGamePadInputEnabled(e)})),this.config._addOnNumericSettingChangedListener(ge.MinQP,(t=>{e.Log(e.GetStackTrace(),"-------- Sending MinQP --------",7),this._webRtcController.sendEncoderMinQP(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(ge.MaxQP,(t=>{e.Log(e.GetStackTrace(),"-------- Sending encoder settings --------",7),this._webRtcController.sendEncoderMaxQP(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(ge.WebRTCMinBitrate,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCMinBitrate(1e3*t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(ge.WebRTCMaxBitrate,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCMaxBitrate(1e3*t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(ge.WebRTCFPS,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCFps(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnOptionSettingChangedListener(pe.PreferredCodec,(e=>{this._webRtcController&&this._webRtcController.setPreferredCodec(e)})),this.config._registerOnChangeEvents(this._eventEmitter)}_activateOnScreenKeyboard(e){throw new Error("Method not implemented.")}_onInputControlOwnership(e){this._inputController=e}setWebRtcPlayerController(e){this._webRtcController=e,this._webRtcController.setPreferredCodec(this.config.getSettingOption(pe.PreferredCodec).selected),this._webRtcController.resizePlayerStyle(),this.checkForAutoConnect()}connect(){this._eventEmitter.dispatchEvent(new N),this._webRtcController.connectToSignallingServer()}reconnect(){this._eventEmitter.dispatchEvent(new Q),this._webRtcController.tryReconnect("Reconnecting...")}disconnect(){this._eventEmitter.dispatchEvent(new K),this._webRtcController.close()}play(){this._onStreamLoading(),this._webRtcController.playStream()}checkForAutoConnect(){console.log(this.config.isFlagEnabled(ce.AutoConnect),"====ssss"),this.config.isFlagEnabled(ce.AutoConnect)&&(this._onWebRtcAutoConnect(),this._webRtcController.connectToSignallingServer())}unmuteMicrophone(t=!1){if(!this.config.isFlagEnabled("UseMic"))return t?(this.config.setFlagEnabled("UseMic",!0),void this.reconnect()):void e.Warning(e.GetStackTrace(),"Trying to unmute mic, but PixelStreaming was initialized with no microphone track. Call with forceEnable == true to re-connect with a mic track.");this.setMicrophoneMuted(!1)}muteMicrophone(){this.config.isFlagEnabled("UseMic")?this.setMicrophoneMuted(!0):e.Info(e.GetStackTrace(),"Trying to mute mic, but PixelStreaming has no microphone track, so sending sound is already disabled.")}setMicrophoneMuted(e){var t,s,n,r;for(const i of null!==(r=null===(n=null===(s=null===(t=this._webRtcController)||void 0===t?void 0:t.peerConnectionController)||void 0===s?void 0:s.peerConnection)||void 0===n?void 0:n.getTransceivers())&&void 0!==r?r:[])Fe.canTransceiverSendAudio(i)&&(i.sender.track.enabled=!e)}_onWebRtcAutoConnect(){this._eventEmitter.dispatchEvent(new O)}_onWebRtcSdp(){this._eventEmitter.dispatchEvent(new D)}_onStreamLoading(){this._eventEmitter.dispatchEvent(new V)}_onDisconnect(e,t){this._eventEmitter.dispatchEvent(new z({eventString:e,allowClickToReconnect:t}))}_onWebRtcConnecting(){this._eventEmitter.dispatchEvent(new I)}_onWebRtcConnected(){this._eventEmitter.dispatchEvent(new G)}_onWebRtcFailed(){this._eventEmitter.dispatchEvent(new U)}_onVideoInitialized(){this._eventEmitter.dispatchEvent(new W),this._videoStartTime=Date.now()}_onLatencyTestResult(e){this._eventEmitter.dispatchEvent(new ee({latencyTimings:e}))}_onDataChannelLatencyTestResponse(e){this._eventEmitter.dispatchEvent(new te({response:e}))}_onVideoStats(e){this._videoStartTime&&void 0!==this._videoStartTime||(this._videoStartTime=Date.now()),e.handleSessionStatistics(this._videoStartTime,this._inputController,this._webRtcController.videoAvgQp),this._eventEmitter.dispatchEvent(new Y({aggregatedStats:e}))}_onVideoEncoderAvgQP(e){this._eventEmitter.dispatchEvent(new F({avgQP:e}))}_onInitialSettings(t){var s;this._eventEmitter.dispatchEvent(new ne({settings:t})),t.PixelStreamingSettings&&(this.allowConsoleCommands=null!==(s=t.PixelStreamingSettings.AllowPixelStreamingCommands)&&void 0!==s&&s,!1===this.allowConsoleCommands&&e.Info(e.GetStackTrace(),"-AllowPixelStreamingCommands=false, sending arbitrary console commands from browser to UE is disabled."));const n=this.config.useUrlParams,r=new URLSearchParams(window.location.search);t.EncoderSettings&&(this.config.setNumericSetting(ge.MinQP,n&&r.has(ge.MinQP)?Number.parseInt(r.get(ge.MinQP)):t.EncoderSettings.MinQP),this.config.setNumericSetting(ge.MaxQP,n&&r.has(ge.MaxQP)?Number.parseInt(r.get(ge.MaxQP)):t.EncoderSettings.MaxQP)),t.WebRTCSettings&&(this.config.setNumericSetting(ge.WebRTCMinBitrate,n&&r.has(ge.WebRTCMinBitrate)?Number.parseInt(r.get(ge.WebRTCMinBitrate)):t.WebRTCSettings.MinBitrate/1e3),this.config.setNumericSetting(ge.WebRTCMaxBitrate,n&&r.has(ge.WebRTCMaxBitrate)?Number.parseInt(r.get(ge.WebRTCMaxBitrate)):t.WebRTCSettings.MaxBitrate/1e3),this.config.setNumericSetting(ge.WebRTCFPS,n&&r.has(ge.WebRTCFPS)?Number.parseInt(r.get(ge.WebRTCFPS)):t.WebRTCSettings.FPS))}_onQualityControlOwnership(e){this.config.setFlagEnabled(ce.IsQualityController,e)}_onPlayerCount(e){this._eventEmitter.dispatchEvent(new le({count:e}))}requestLatencyTest(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendLatencyTest(),!0)}requestDataChannelLatencyTest(e){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._dataChannelLatencyTestController||(this._dataChannelLatencyTestController=new Et(this._webRtcController.sendDataChannelLatencyTest.bind(this._webRtcController),(e=>{this._eventEmitter.dispatchEvent(new se({result:e}))})),this.addEventListener("dataChannelLatencyTestResponse",(({data:{response:e}})=>{this._dataChannelLatencyTestController.receive(e)}))),this._dataChannelLatencyTestController.start(e))}requestShowFps(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendShowFps(),!0)}requestIframe(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendIframeRequest(),!0)}emitUIInteraction(e){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.emitUIInteraction(e),!0)}emitCommand(e){return!(!this._webRtcController.videoPlayer.isVideoReady()||!this.allowConsoleCommands&&"ConsoleCommand"in e||(this._webRtcController.emitCommand(e),0))}emitConsoleCommand(e){return!(!this.allowConsoleCommands||!this._webRtcController.videoPlayer.isVideoReady()||(this._webRtcController.emitConsoleCommand(e),0))}addResponseEventListener(e,t){this._webRtcController.responseController.addResponseEventListener(e,t)}removeResponseEventListener(e){this._webRtcController.responseController.removeResponseEventListener(e)}dispatchEvent(e){return this._eventEmitter.dispatchEvent(e)}addEventListener(e,t){this._eventEmitter.addEventListener(e,t)}removeEventListener(e,t){this._eventEmitter.removeEventListener(e,t)}toggleXR(){this.webXrController.xrClicked()}setSignallingUrlBuilder(e){this._webRtcController.signallingUrlBuilder=e}get webSocketController(){return this._webRtcController.webSocketController}get webXrController(){return this._webXrController}registerMessageHandler(t,s,n){s!==Oe.FromStreamer||void 0!==n?s===Oe.ToStreamer&&void 0===n?this._webRtcController.streamMessageController.registerMessageHandler(s,t,(e=>this._webRtcController.sendMessageController.sendMessageToStreamer(t,e))):this._webRtcController.streamMessageController.registerMessageHandler(s,t,(e=>n(e))):e.Warning(e.GetStackTrace(),`Unable to register an undefined handler for ${t}`)}get toStreamerHandlers(){return this._webRtcController.streamMessageController.toStreamerHandlers}isReconnecting(){return this._webRtcController.isReconnecting}}})(),r})()));
|