@epicgames-ps/lib-pixelstreamingfrontend-ue5.4
Version:
Frontend library for Unreal Engine 5.4 Pixel Streaming
1 lines • 146 kB
JavaScript
!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:()=>Ee,AfkTimedOutEvent:()=>x,AfkWarningActivateEvent:()=>P,AfkWarningDeactivateEvent:()=>L,AfkWarningUpdateEvent:()=>k,AggregatedStats:()=>xe,CandidatePairStats:()=>Et,CandidateStat:()=>Re,Config:()=>fe,ControlSchemeType:()=>Te,DataChannelCloseEvent:()=>z,DataChannelErrorEvent:()=>_,DataChannelLatencyTestResponseEvent:()=>te,DataChannelLatencyTestResultEvent:()=>se,DataChannelOpenEvent:()=>B,DataChannelStats:()=>be,EncoderSettings:()=>ze,EventEmitter:()=>ce,Flags:()=>he,HideFreezeFrameEvent:()=>j,InboundAudioStats:()=>Me,InboundVideoStats:()=>we,InitialSettings:()=>Ge,InitialSettingsEvent:()=>ne,LatencyTestResultEvent:()=>ee,LatencyTestResults:()=>He,LoadFreezeFrameEvent:()=>X,Logger:()=>e,MessageDirection:()=>Oe,MessageRecv:()=>p,MessageSend:()=>i,MessageStreamerList:()=>S,NumericParameters:()=>ge,OptionParameters:()=>ve,OutBoundVideoStats:()=>Pe,PixelStreaming:()=>Tt,PlayStreamErrorEvent:()=>Q,PlayStreamEvent:()=>$,PlayStreamRejectedEvent:()=>q,PlayerCountEvent:()=>le,SettingBase:()=>y,SettingFlag:()=>M,SettingNumber:()=>w,SettingOption:()=>R,SettingText:()=>b,SettingsChangedEvent:()=>re,SignallingProtocol:()=>v,StatsReceivedEvent:()=>J,StreamLoadingEvent:()=>V,StreamPreConnectEvent:()=>W,StreamPreDisconnectEvent:()=>N,StreamReconnectEvent:()=>K,StreamerIDChangedMessageEvent:()=>Z,StreamerListMessageEvent:()=>Y,TextParameters:()=>pe,UnquantizedAndDenormalizeUnsigned:()=>ut,VideoEncoderAvgQPEvent:()=>A,VideoInitializedEvent:()=>H,WebRTCSettings:()=>_e,WebRtcAutoConnectEvent:()=>D,WebRtcConnectedEvent:()=>I,WebRtcConnectingEvent:()=>O,WebRtcDisconnectedEvent:()=>G,WebRtcFailedEvent:()=>U,WebRtcPlayerController:()=>mt,WebRtcSdpEvent:()=>F,WebRtcTCPRelayDetectedEvent:()=>de,WebSocketController:()=>C,WebXRController:()=>St,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{sendFilter(e,t){return t}payload(){return e.Log(e.GetStackTrace(),"Sending => \n"+JSON.stringify(this,this.sendFilter,4),6),JSON.stringify(this,this.sendFilter)}}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 l extends i{constructor(){super(),this.type=t.UNSUBSCRIBE}}class d extends i{constructor(e){super(),this.type=t.PONG,this.time=e}}class c extends i{constructor(e,s){super(),this.type=t.OFFER,this.minBitrate=0,this.maxBitrate=0,e&&(this.type=e.type,this.sdp=e.sdp,this.minBitrate=s.minBitrateBps,this.maxBitrate=s.maxBitrateBps)}sendFilter(e,t){if("minBitrate"!=e&&"maxBitrate"!=e||!(t<=0))return t}}class h extends i{constructor(e,s){super(),this.type=t.ANSWER,this.minBitrate=0,this.maxBitrate=0,e&&(this.type=e.type,this.sdp=e.sdp,this.minBitrate=s.minBitrateBps,this.maxBitrate=s.maxBitrateBps)}sendFilter(e,t){if("minBitrate"!=e&&"maxBitrate"!=e||!(t<=0))return t}}class u extends i{constructor(){super(),this.type=t.DATACHANNELREQUEST}}class g 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.STREAMER_ID_CHANGED="streamerIDChanged",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 d((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.STREAMER_ID_CHANGED,(n=>{e.Log(e.GetStackTrace(),s.STREAMER_ID_CHANGED,6);const r=JSON.parse(n);t.onStreamerIDChanged(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 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){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 l;this.webSocket.send(e.payload())}sendWebRtcOffer(e,t){const s=new c(e,t);this.webSocket.send(s.payload())}sendWebRtcAnswer(e,t){const s=new h(e,t);this.webSocket.send(s.payload())}sendWebRtcDatachannelRequest(){const e=new u;this.webSocket.send(e.payload())}sendSFURecvDataChannelReady(){const e=new g;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()}onConfig(e){}onStreamerList(e){}onStreamerIDChanged(e){}onIceCandidate(e){}onWebRtcAnswer(e){}onWebRtcOffer(e){}onWebRtcPeerDataChannels(e){}onPlayerCount(e){}}class f{constructor(e){this.videoElementProvider=e,this.audioElement=document.createElement("Audio"),this.videoElementProvider.setAudioElement(this.audioElement)}handleOnTrack(t){if(e.Log(e.GetStackTrace(),"handleOnTrack "+JSON.stringify(t.streams),6),"probator"==t.track.id)return;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 M 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 w extends y{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.parseFloat(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 null==this._min&&null==this._max?e:null==this._min?Math.min(this._max,e):null==this._max?Math.max(this._min,e):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 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.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 R extends y{constructor(e,t,s,n,r,i,o=(()=>{})){super(e,t,s,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 P 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 I extends Event{constructor(){super("webRtcConnected")}}class U extends Event{constructor(){super("webRtcFailed")}}class G extends Event{constructor(e){super("webRtcDisconnected"),this.data=e}}class B extends Event{constructor(e){super("dataChannelOpen"),this.data=e}}class z extends Event{constructor(e){super("dataChannelClose"),this.data=e}}class _ extends Event{constructor(e){super("dataChannelError"),this.data=e}}class H extends Event{constructor(){super("videoInitialized")}}class V extends Event{constructor(){super("streamLoading")}}class W 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("StreamerIDChangedMessage"),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 Event{constructor(){super("webRtcTCPRelayDetected")}}class ce extends EventTarget{dispatchEvent(e){return super.dispatchEvent(e)}addEventListener(e,t){super.addEventListener(e,t)}removeEventListener(e,t){super.removeEventListener(e,t)}}class he{}he.AutoConnect="AutoConnect",he.AutoPlayVideo="AutoPlayVideo",he.AFKDetection="TimeoutIfIdle",he.BrowserSendOffer="OfferToReceive",he.HoveringMouseMode="HoveringMouse",he.ForceMonoAudio="ForceMonoAudio",he.ForceTURN="ForceTURN",he.FakeMouseWithTouches="FakeMouseWithTouches",he.IsQualityController="ControlsQuality",he.MatchViewportResolution="MatchViewportRes",he.StartVideoMuted="StartVideoMuted",he.SuppressBrowserKeys="SuppressBrowserKeys",he.UseMic="UseMic",he.KeyboardInput="KeyboardInput",he.MouseInput="MouseInput",he.TouchInput="TouchInput",he.GamepadInput="GamepadInput",he.XRControllerInput="XRControllerInput",he.WaitForStreamer="WaitForStreamer",he.HideUI="HideUI";const ue=e=>Object.getOwnPropertyNames(he).some((t=>he[t]===e));class ge{}ge.AFKTimeoutSecs="AFKTimeout",ge.AFKCountdownSecs="AFKCountdown",ge.MinQP="MinQP",ge.MaxQP="MaxQP",ge.WebRTCFPS="WebRTCFPS",ge.WebRTCMinBitrate="WebRTCMinBitrate",ge.WebRTCMaxBitrate="WebRTCMaxBitrate",ge.MaxReconnectAttempts="MaxReconnectAttempts",ge.StreamerAutoJoinInterval="StreamerAutoJoinInterval";const me=e=>Object.getOwnPropertyNames(ge).some((t=>ge[t]===e));class pe{}pe.SignallingServerUrl="ss";const Se=e=>Object.getOwnPropertyNames(pe).some((t=>pe[t]===e));class ve{}ve.PreferredCodec="PreferredCodec",ve.StreamerId="StreamerId";const Ce=e=>Object.getOwnPropertyNames(ve).some((t=>ve[t]===e));class fe{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)}get useUrlParams(){return this._useUrlParams}populateDefaultSettings(e,t){this.textParameters.set(pe.SignallingServerUrl,new b(pe.SignallingServerUrl,"Signalling url","Url of the signalling server",t&&t.hasOwnProperty(pe.SignallingServerUrl)?t[pe.SignallingServerUrl]:("https:"===location.protocol?"wss://":"ws://")+window.location.hostname+("80"===window.location.port||""===window.location.port?"":`:${window.location.port}`),e)),this.optionParameters.set(ve.StreamerId,new R(ve.StreamerId,"Streamer ID","The ID of the streamer to stream.",t&&t.hasOwnProperty(ve.StreamerId)?t[ve.StreamerId]:"",[],e)),this.optionParameters.set(ve.PreferredCodec,new R(ve.PreferredCodec,"Preferred Codec","The preferred codec to be used during codec negotiation","H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f",t&&t.hasOwnProperty(ve.PreferredCodec)?[t[ve.PreferredCodec]]: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(he.AutoConnect,new M(he.AutoConnect,"Auto connect to stream","Whether we should attempt to auto connect to the signalling server or show a click to start prompt.",!(!t||!t.hasOwnProperty(he.AutoConnect))&&t[he.AutoConnect],e)),this.flags.set(he.AutoPlayVideo,new M(he.AutoPlayVideo,"Auto play video","When video is ready automatically start playing it as opposed to showing a play button.",!t||!t.hasOwnProperty(he.AutoPlayVideo)||t[he.AutoPlayVideo],e)),this.flags.set(he.BrowserSendOffer,new M(he.BrowserSendOffer,"Browser send offer","Browser will initiate the WebRTC handshake by sending the offer to the streamer",!(!t||!t.hasOwnProperty(he.BrowserSendOffer))&&t[he.BrowserSendOffer],e)),this.flags.set(he.UseMic,new M(he.UseMic,"Use microphone","Make browser request microphone access and open an input audio track.",!(!t||!t.hasOwnProperty(he.UseMic))&&t[he.UseMic],e)),this.flags.set(he.StartVideoMuted,new M(he.StartVideoMuted,"Start video muted","Video will start muted if true.",!(!t||!t.hasOwnProperty(he.StartVideoMuted))&&t[he.StartVideoMuted],e)),this.flags.set(he.SuppressBrowserKeys,new M(he.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.",!t||!t.hasOwnProperty(he.SuppressBrowserKeys)||t[he.SuppressBrowserKeys],e)),this.flags.set(he.IsQualityController,new M(he.IsQualityController,"Is quality controller?","True if this peer controls stream quality",!t||!t.hasOwnProperty(he.IsQualityController)||t[he.IsQualityController],e)),this.flags.set(he.ForceMonoAudio,new M(he.ForceMonoAudio,"Force mono audio","Force browser to request mono audio in the SDP",!(!t||!t.hasOwnProperty(he.ForceMonoAudio))&&t[he.ForceMonoAudio],e)),this.flags.set(he.ForceTURN,new M(he.ForceTURN,"Force TURN","Only generate TURN/Relayed ICE candidates.",!(!t||!t.hasOwnProperty(he.ForceTURN))&&t[he.ForceTURN],e)),this.flags.set(he.AFKDetection,new M(he.AFKDetection,"AFK if idle","Timeout the experience if user is AFK for a period.",!(!t||!t.hasOwnProperty(he.AFKDetection))&&t[he.AFKDetection],e)),this.flags.set(he.MatchViewportResolution,new M(he.MatchViewportResolution,"Match viewport resolution","Pixel Streaming will be instructed to dynamically resize the video stream to match the size of the video element.",!(!t||!t.hasOwnProperty(he.MatchViewportResolution))&&t[he.MatchViewportResolution],e)),this.flags.set(he.HoveringMouseMode,new M(he.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.",!(!t||!t.hasOwnProperty(he.HoveringMouseMode))&&t[he.HoveringMouseMode],e,((e,t)=>{t.label=`Control Scheme: ${e?"Hovering":"Locked"} Mouse`}))),this.flags.set(he.FakeMouseWithTouches,new M(he.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.",!(!t||!t.hasOwnProperty(he.FakeMouseWithTouches))&&t[he.FakeMouseWithTouches],e)),this.flags.set(he.KeyboardInput,new M(he.KeyboardInput,"Keyboard input","If enabled, send keyboard events to streamer",!t||!t.hasOwnProperty(he.KeyboardInput)||t[he.KeyboardInput],e)),this.flags.set(he.MouseInput,new M(he.MouseInput,"Mouse input","If enabled, send mouse events to streamer",!t||!t.hasOwnProperty(he.MouseInput)||t[he.MouseInput],e)),this.flags.set(he.TouchInput,new M(he.TouchInput,"Touch input","If enabled, send touch events to streamer",!t||!t.hasOwnProperty(he.TouchInput)||t[he.TouchInput],e)),this.flags.set(he.GamepadInput,new M(he.GamepadInput,"Gamepad input","If enabled, send gamepad events to streamer",!t||!t.hasOwnProperty(he.GamepadInput)||t[he.GamepadInput],e)),this.flags.set(he.XRControllerInput,new M(he.XRControllerInput,"XR controller input","If enabled, send XR controller events to streamer",!t||!t.hasOwnProperty(he.XRControllerInput)||t[he.XRControllerInput],e)),this.flags.set(he.WaitForStreamer,new M(he.WaitForStreamer,"Wait for streamer","Will continue trying to connect to the first streamer available.",!t||!t.hasOwnProperty(he.WaitForStreamer)||t[he.WaitForStreamer],e)),this.flags.set(he.HideUI,new M(he.HideUI,"Hide the UI overlay","Will hide all UI overlay details",!(!t||!t.hasOwnProperty(he.HideUI))&&t[he.HideUI],e)),this.numericParameters.set(ge.AFKTimeoutSecs,new w(ge.AFKTimeoutSecs,"AFK timeout","The time (in seconds) it takes for the application to time out if AFK timeout is enabled.",0,null,t&&t.hasOwnProperty(ge.AFKTimeoutSecs)?t[ge.AFKTimeoutSecs]:120,e)),this.numericParameters.set(ge.AFKCountdownSecs,new w(ge.AFKCountdownSecs,"AFK countdown","The time (in seconds) for a user to respond before the stream is ended after an AFK timeout.",10,null,10,e)),this.numericParameters.set(ge.MaxReconnectAttempts,new w(ge.MaxReconnectAttempts,"Max Reconnects","Maximum number of reconnects the application will attempt when a streamer disconnects.",0,999,t&&t.hasOwnProperty(ge.MaxReconnectAttempts)?t[ge.MaxReconnectAttempts]:3,e)),this.numericParameters.set(ge.MinQP,new w(ge.MinQP,"Min QP","The lower bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.",0,51,t&&t.hasOwnProperty(ge.MinQP)?t[ge.MinQP]:0,e)),this.numericParameters.set(ge.MaxQP,new w(ge.MaxQP,"Max QP","The upper bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.",0,51,t&&t.hasOwnProperty(ge.MaxQP)?t[ge.MaxQP]:51,e)),this.numericParameters.set(ge.WebRTCFPS,new w(ge.WebRTCFPS,"Max FPS","The maximum FPS that WebRTC will try to transmit frames at.",1,999,t&&t.hasOwnProperty(ge.WebRTCFPS)?t[ge.WebRTCFPS]:60,e)),this.numericParameters.set(ge.WebRTCMinBitrate,new w(ge.WebRTCMinBitrate,"Min Bitrate (kbps)","The minimum bitrate that WebRTC should use.",0,5e5,t&&t.hasOwnProperty(ge.WebRTCMinBitrate)?t[ge.WebRTCMinBitrate]:0,e)),this.numericParameters.set(ge.WebRTCMaxBitrate,new w(ge.WebRTCMaxBitrate,"Max Bitrate (kbps)","The maximum bitrate that WebRTC should use.",0,5e5,t&&t.hasOwnProperty(ge.WebRTCMaxBitrate)?t[ge.WebRTCMaxBitrate]:0,e)),this.numericParameters.set(ge.StreamerAutoJoinInterval,new w(ge.StreamerAutoJoinInterval,"Streamer Auto Join Interval (ms)","Delay between retries when waiting for an available streamer.",500,9e5,t&&t.hasOwnProperty(ge.StreamerAutoJoinInterval)?t[ge.StreamerAutoJoinInterval]: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)?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){if(this.optionParameters.has(t)){const e=this.optionParameters.get(t),n=e.options;n.includes(s)||(n.push(s),e.options=n),e.selected=s}else 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))ue(t)?this.setFlagEnabled(t,e[t]):me(t)?this.setNumericSetting(t,e[t]):Se(t)?this.setTextSetting(t,e[t]):Ce(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 Te;!function(e){e[e.LockedMouse=0]="LockedMouse",e[e.HoveringMouse=1]="HoveringMouse"}(Te||(Te={}));class Ee{constructor(e,t,s){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(ge.AFKTimeoutSecs)>0&&this.config.isFlagEnabled(he.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(he.AFKDetection)&&(clearTimeout(this.warnTimer),this.warnTimer=setTimeout((()=>this.activateAfkEvent()),1e3*this.config.getNumericSettingValue(ge.AFKTimeoutSecs)))}activateAfkEvent(){this.pauseAfkWarningTimer(),this.pixelStreaming.dispatchEvent(new P({countDown:this.countDown,dismissAfk:this.onDismissAfk})),this.countDown=this.config.getNumericSettingValue(ge.AFKCountdownSecs),this.countdownActive=!0,this.pixelStreaming.dispatchEvent(new k({countDown:this.countDown})),this.config.isFlagEnabled(he.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 ye{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 Me{}class we{}class be{}class Re{}class Pe{}class ke{}class Le{}class xe{constructor(){this.inboundVideoStats=new we,this.inboundAudioStats=new Me,this.DataChannelStats=new be,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,this.candidatePairs=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":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"transport":this.handleTransport(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.candidatePairs.push(e)}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 Re;t.label="local-candidate",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.candidateType=e.candidateType,t.id=e.id,t.relayProtocol=e.relayProtocol,t.transportId=e.transportId,this.localCandidates.push(t)}handleRemoteCandidate(e){const t=new Re;t.label="remote-candidate",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.id=e.id,t.candidateType=e.candidateType,t.relayProtocol=e.relayProtocol,t.transportId=e.transportId,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)}handleTransport(e){this.transportStats=e}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)}getActiveCandidatePair(){return this.transportStats?this.candidatePairs.find((e=>e.id===this.transportStats.selectedCandidatePairId),null):this.candidatePairs.find((e=>e.selected),null)}}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 Ue{constructor(e,t,s){this.config=t,this.createPeerConnection(e,s)}createPeerConnection(t,s){this.config.isFlagEnabled(he.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(he.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 n="localhost"===location.hostname||"127.0.0.1"===location.hostname,r="https:"===location.protocol;let i=s.isFlagEnabled(he.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.config.setOptionSettingOptions(ve.PreferredCodec,this.fuzzyIntersectUEAndBrowserCodecs(t)),this.setupTransceiversAsync(i).finally((()=>{var t;null===(t=this.peerConnection)||void 0===t||t.createAnswer().then((e=>{var t;return e.sdp=this.mungeSDP(e.sdp,i),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")}))}))}))}))}receiveAnswer(e){var t;null===(t=this.peerConnection)||void 0===t||t.setRemoteDescription(e),this.config.setOptionSettingOptions(ve.PreferredCodec,this.fuzzyIntersectUEAndBrowserCodecs(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.aggregatedStats.inboundVideoStats.codecId&&this.config.setOptionSettingValue(ve.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(he.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(he.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){}fuzzyIntersectUEAndBrowserCodecs(e){const t=new Array,s=this.parseAvailableCodecs(e),n=this.config.getSettingOption(ve.PreferredCodec).options;for(const e of s)if(n.includes(e))t.push(e);else{const s=e.split(" ")[0];for(const e of n)if(e.includes(s)){t.push(e);break}}return t}setupTransceiversAsync(e){var t,s,n,r,i,o,a,l,d,c,h,u;return Ie(this,void 0,void 0,(function*(){let g=!1;for(const e of null!==(s=null===(t=this.peerConnection)||void 0===t?void 0:t.getTransceivers())&&void 0!==s?s:[])if(e&&e.receiver&&e.receiver.track&&"video"===e.receiver.track.kind){g=!0;break}if(g||null===(n=this.peerConnection)||void 0===n||n.addTransceiver("video",{direction:"recvonly"}),RTCRtpReceiver.getCapabilities&&""!=this.preferredCodec)for(const e of null!==(i=null===(r=this.peerConnection)||void 0===r?void 0:r.getTransceivers())&&void 0!==i?i:[])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]:""},n=[s];RTCRtpReceiver.getCapabilities("video").codecs.forEach((e=>{(e.mimeType!=s.mimeType||(null==e?void 0:e.sdpFmtpLine)!=(null==s?void 0:s.sdpFmtpLine))&&n.push(e)}));for(const e of n)void 0!==(null==e?void 0:e.sdpFmtpLine)&&""!==e.sdpFmtpLine||delete e.sdpFmtpLine;e.setCodecPreferences(n)}let m=!1;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){m=!0;break}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(m){for(const e of null!==(c=null===(d=this.peerConnection)||void 0===d?void 0:d.getTransceivers())&&void 0!==c?c:[])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===(h=this.peerConnection)||void 0===h||h.addTransceiver(e,{direction:"sendrecv"}));else m||null===(u=this.peerConnection)||void 0===u||u.addTransceiver("audio",{direction:"recvonly"})}else m||null===(l=this.peerConnection)||void 0===l||l.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 Ge{constructor(){this.PixelStreamingSettings=new Be,this.EncoderSettings=new ze,this.WebRTCSettings=new _e}ueCompatible(){null!=this.WebRTCSettings.MaxFPS&&(this.WebRTCSettings.FPS=this.WebRTCSettings.MaxFPS)}}class Be{}class ze{}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.PostCaptureT