@yang__yj/pixelstreaming-core 1.0.0 → 1.0.2

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.
Files changed (243) hide show
  1. package/.cspell.json +48 -0
  2. package/.eslintignore +8 -0
  3. package/.eslintrc.js +8 -0
  4. package/.prettierignore +0 -0
  5. package/.prettierrc.json +6 -0
  6. package/coverage/clover.xml +3480 -0
  7. package/coverage/coverage-final.json +62 -0
  8. package/coverage/lcov-report/base.css +224 -0
  9. package/coverage/lcov-report/block-navigation.js +87 -0
  10. package/coverage/lcov-report/favicon.png +0 -0
  11. package/coverage/lcov-report/index.html +356 -0
  12. package/coverage/lcov-report/prettify.css +1 -0
  13. package/coverage/lcov-report/prettify.js +2 -0
  14. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  15. package/coverage/lcov-report/sorter.js +196 -0
  16. package/coverage/lcov-report/src/AFK/AFKController.ts.html +559 -0
  17. package/coverage/lcov-report/src/AFK/index.html +116 -0
  18. package/coverage/lcov-report/src/Config/Config.ts.html +2764 -0
  19. package/coverage/lcov-report/src/Config/SettingBase.ts.html +280 -0
  20. package/coverage/lcov-report/src/Config/SettingFlag.ts.html +382 -0
  21. package/coverage/lcov-report/src/Config/SettingNumber.ts.html +418 -0
  22. package/coverage/lcov-report/src/Config/SettingOption.ts.html +424 -0
  23. package/coverage/lcov-report/src/Config/SettingText.ts.html +331 -0
  24. package/coverage/lcov-report/src/Config/index.html +191 -0
  25. package/coverage/lcov-report/src/DataChannel/DataChannelController.ts.html +499 -0
  26. package/coverage/lcov-report/src/DataChannel/DataChannelSender.ts.html +262 -0
  27. package/coverage/lcov-report/src/DataChannel/InitialSettings.ts.html +268 -0
  28. package/coverage/lcov-report/src/DataChannel/LatencyTestResults.ts.html +313 -0
  29. package/coverage/lcov-report/src/DataChannel/index.html +161 -0
  30. package/coverage/lcov-report/src/FreezeFrame/FreezeFrame.ts.html +427 -0
  31. package/coverage/lcov-report/src/FreezeFrame/FreezeFrameController.ts.html +427 -0
  32. package/coverage/lcov-report/src/FreezeFrame/index.html +131 -0
  33. package/coverage/lcov-report/src/Inputs/FakeTouchController.ts.html +682 -0
  34. package/coverage/lcov-report/src/Inputs/GamepadController.ts.html +985 -0
  35. package/coverage/lcov-report/src/Inputs/HoveringMouseEvents.ts.html +688 -0
  36. package/coverage/lcov-report/src/Inputs/InputClassesFactory.ts.html +505 -0
  37. package/coverage/lcov-report/src/Inputs/KeyboardController.ts.html +1048 -0
  38. package/coverage/lcov-report/src/Inputs/LockedMouseEvents.ts.html +946 -0
  39. package/coverage/lcov-report/src/Inputs/MouseButtons.ts.html +160 -0
  40. package/coverage/lcov-report/src/Inputs/MouseController.ts.html +1171 -0
  41. package/coverage/lcov-report/src/Inputs/SpecialKeyCodes.ts.html +133 -0
  42. package/coverage/lcov-report/src/Inputs/TouchController.ts.html +712 -0
  43. package/coverage/lcov-report/src/Inputs/XRGamepadController.ts.html +463 -0
  44. package/coverage/lcov-report/src/Inputs/index.html +266 -0
  45. package/coverage/lcov-report/src/Logger/Logger.ts.html +325 -0
  46. package/coverage/lcov-report/src/Logger/index.html +116 -0
  47. package/coverage/lcov-report/src/PeerConnectionController/AggregatedStats.ts.html +1018 -0
  48. package/coverage/lcov-report/src/PeerConnectionController/CandidatePairStats.ts.html +136 -0
  49. package/coverage/lcov-report/src/PeerConnectionController/CandidateStat.ts.html +124 -0
  50. package/coverage/lcov-report/src/PeerConnectionController/DataChannelStats.ts.html +136 -0
  51. package/coverage/lcov-report/src/PeerConnectionController/InboundRTPStats.ts.html +547 -0
  52. package/coverage/lcov-report/src/PeerConnectionController/OutBoundRTPStats.ts.html +163 -0
  53. package/coverage/lcov-report/src/PeerConnectionController/PeerConnectionController.ts.html +1795 -0
  54. package/coverage/lcov-report/src/PeerConnectionController/SessionStats.ts.html +115 -0
  55. package/coverage/lcov-report/src/PeerConnectionController/StreamStats.ts.html +118 -0
  56. package/coverage/lcov-report/src/PeerConnectionController/index.html +236 -0
  57. package/coverage/lcov-report/src/PixelStreaming/PixelStreaming.ts.html +2269 -0
  58. package/coverage/lcov-report/src/PixelStreaming/index.html +116 -0
  59. package/coverage/lcov-report/src/UI/OnScreenKeyboard.ts.html +376 -0
  60. package/coverage/lcov-report/src/UI/index.html +116 -0
  61. package/coverage/lcov-report/src/UeInstanceMessage/ResponseController.ts.html +226 -0
  62. package/coverage/lcov-report/src/UeInstanceMessage/SendDescriptorController.ts.html +346 -0
  63. package/coverage/lcov-report/src/UeInstanceMessage/SendMessageController.ts.html +364 -0
  64. package/coverage/lcov-report/src/UeInstanceMessage/StreamMessageController.ts.html +862 -0
  65. package/coverage/lcov-report/src/UeInstanceMessage/ToStreamerMessagesController.ts.html +271 -0
  66. package/coverage/lcov-report/src/UeInstanceMessage/TwoWayMap.ts.html +241 -0
  67. package/coverage/lcov-report/src/UeInstanceMessage/index.html +191 -0
  68. package/coverage/lcov-report/src/Util/CoordinateConverter.ts.html +952 -0
  69. package/coverage/lcov-report/src/Util/EventEmitter.ts.html +1705 -0
  70. package/coverage/lcov-report/src/Util/EventListenerTracker.ts.html +172 -0
  71. package/coverage/lcov-report/src/Util/FileUtil.ts.html +505 -0
  72. package/coverage/lcov-report/src/Util/WebGLUtils.ts.html +232 -0
  73. package/coverage/lcov-report/src/Util/WebXRUtils.ts.html +160 -0
  74. package/coverage/lcov-report/src/Util/index.html +191 -0
  75. package/coverage/lcov-report/src/VideoPlayer/StreamController.ts.html +349 -0
  76. package/coverage/lcov-report/src/VideoPlayer/VideoPlayer.ts.html +799 -0
  77. package/coverage/lcov-report/src/VideoPlayer/index.html +131 -0
  78. package/coverage/lcov-report/src/WebRtcPlayer/WebRtcPlayerController.ts.html +6199 -0
  79. package/coverage/lcov-report/src/WebRtcPlayer/index.html +116 -0
  80. package/coverage/lcov-report/src/WebSockets/MessageReceive.ts.html +352 -0
  81. package/coverage/lcov-report/src/WebSockets/MessageSend.ts.html +604 -0
  82. package/coverage/lcov-report/src/WebSockets/SignallingProtocol.ts.html +622 -0
  83. package/coverage/lcov-report/src/WebSockets/WebSocketController.ts.html +844 -0
  84. package/coverage/lcov-report/src/WebSockets/index.html +161 -0
  85. package/coverage/lcov-report/src/WebXR/WebXRController.ts.html +1042 -0
  86. package/coverage/lcov-report/src/WebXR/index.html +116 -0
  87. package/coverage/lcov-report/src/__test__/index.html +161 -0
  88. package/coverage/lcov-report/src/__test__/mockMediaStream.ts.html +457 -0
  89. package/coverage/lcov-report/src/__test__/mockRTCPeerConnection.ts.html +1126 -0
  90. package/coverage/lcov-report/src/__test__/mockRTCRtpReceiver.ts.html +151 -0
  91. package/coverage/lcov-report/src/__test__/mockWebSocket.ts.html +475 -0
  92. package/coverage/lcov-report/src/index.html +116 -0
  93. package/coverage/lcov-report/src/pixelstreamingfrontend.ts.html +232 -0
  94. package/coverage/lcov.info +6458 -0
  95. package/dist/lib-pixelstreamingfrontend.esm.js +1 -0
  96. package/dist/lib-pixelstreamingfrontend.js +1 -0
  97. package/jest.config.js +18 -0
  98. package/package.json +47 -18
  99. package/readme.md +15 -0
  100. package/src/AFK/AFKController.test.ts +162 -0
  101. package/src/AFK/AFKController.ts +158 -0
  102. package/src/Config/Config.test.ts +222 -0
  103. package/src/Config/Config.ts +909 -0
  104. package/src/Config/SettingBase.ts +65 -0
  105. package/src/Config/SettingFlag.ts +99 -0
  106. package/src/Config/SettingNumber.ts +111 -0
  107. package/src/Config/SettingOption.ts +124 -0
  108. package/src/Config/SettingText.ts +82 -0
  109. package/src/DataChannel/DataChannelController.ts +138 -0
  110. package/src/DataChannel/DataChannelLatencyTestController.ts +129 -0
  111. package/src/DataChannel/DataChannelLatencyTestResults.ts +67 -0
  112. package/src/DataChannel/DataChannelSender.ts +59 -0
  113. package/src/DataChannel/InitialSettings.ts +61 -0
  114. package/src/DataChannel/LatencyTestResults.ts +76 -0
  115. package/src/FreezeFrame/FreezeFrame.ts +114 -0
  116. package/src/FreezeFrame/FreezeFrameController.ts +114 -0
  117. package/src/Inputs/FakeTouchController.ts +199 -0
  118. package/src/Inputs/GamepadController.ts +300 -0
  119. package/src/Inputs/GamepadTypes.ts +10 -0
  120. package/src/Inputs/HoveringMouseEvents.ts +192 -0
  121. package/src/Inputs/IMouseEvents.ts +64 -0
  122. package/src/Inputs/ITouchController.ts +29 -0
  123. package/src/Inputs/InputClassesFactory.ts +140 -0
  124. package/src/Inputs/KeyboardController.ts +318 -0
  125. package/src/Inputs/LockedMouseEvents.ts +287 -0
  126. package/src/Inputs/MouseButtons.ts +25 -0
  127. package/src/Inputs/MouseController.ts +362 -0
  128. package/src/Inputs/SpecialKeyCodes.ts +16 -0
  129. package/src/Inputs/TouchController.ts +253 -0
  130. package/src/Inputs/XRGamepadController.ts +126 -0
  131. package/src/Logger/Logger.ts +80 -0
  132. package/src/PeerConnectionController/AggregatedStats.ts +311 -0
  133. package/src/PeerConnectionController/CandidatePairStats.ts +17 -0
  134. package/src/PeerConnectionController/CandidateStat.ts +13 -0
  135. package/src/PeerConnectionController/CodecStats.ts +19 -0
  136. package/src/PeerConnectionController/DataChannelStats.ts +17 -0
  137. package/src/PeerConnectionController/InboundRTPStats.ts +154 -0
  138. package/src/PeerConnectionController/InboundTrackStats.ts +34 -0
  139. package/src/PeerConnectionController/OutBoundRTPStats.ts +26 -0
  140. package/src/PeerConnectionController/PeerConnectionController.ts +563 -0
  141. package/src/PeerConnectionController/SessionStats.ts +10 -0
  142. package/src/PeerConnectionController/StreamStats.ts +11 -0
  143. package/src/PixelStreaming/PixelStreaming.test.ts +624 -0
  144. package/src/PixelStreaming/PixelStreaming.ts +847 -0
  145. package/src/UI/OnScreenKeyboard.ts +97 -0
  146. package/src/UeInstanceMessage/ResponseController.ts +47 -0
  147. package/src/UeInstanceMessage/SendMessageController.ts +154 -0
  148. package/src/UeInstanceMessage/StreamMessageController.ts +233 -0
  149. package/src/UeInstanceMessage/ToStreamerMessagesController.ts +62 -0
  150. package/src/Util/CoordinateConverter.ts +289 -0
  151. package/src/Util/EventEmitter.ts +595 -0
  152. package/src/Util/EventListenerTracker.ts +29 -0
  153. package/src/Util/FileUtil.ts +140 -0
  154. package/src/Util/RTCUtils.ts +41 -0
  155. package/src/Util/WebGLUtils.ts +49 -0
  156. package/src/Util/WebXRUtils.ts +25 -0
  157. package/src/VideoPlayer/StreamController.ts +89 -0
  158. package/src/VideoPlayer/VideoPlayer.ts +246 -0
  159. package/src/WebRtcPlayer/WebRtcPlayerController.ts +2221 -0
  160. package/src/WebSockets/MessageReceive.ts +89 -0
  161. package/src/WebSockets/MessageSend.ts +185 -0
  162. package/src/WebSockets/SignallingProtocol.ts +180 -0
  163. package/src/WebSockets/WebSocketController.ts +267 -0
  164. package/src/WebXR/WebXRController.ts +319 -0
  165. package/src/__test__/mockMediaStream.ts +124 -0
  166. package/src/__test__/mockRTCPeerConnection.ts +347 -0
  167. package/src/__test__/mockRTCRtpReceiver.ts +22 -0
  168. package/src/__test__/mockWebSocket.ts +130 -0
  169. package/src/pixelstreamingfrontend.ts +50 -0
  170. package/tsconfig.jest.json +8 -0
  171. package/tsconfig.json +24 -0
  172. package/{library/types → types}/Config/Config.d.ts +5 -4
  173. package/types/DataChannel/DataChannelLatencyTestController.d.ts +26 -0
  174. package/types/DataChannel/DataChannelLatencyTestResults.d.ts +46 -0
  175. package/{library/types → types}/Inputs/HoveringMouseEvents.d.ts +1 -1
  176. package/{library/types → types}/PeerConnectionController/PeerConnectionController.d.ts +1 -1
  177. package/{library/types → types}/PixelStreaming/PixelStreaming.d.ts +31 -6
  178. package/{library/types → types}/UeInstanceMessage/SendMessageController.d.ts +1 -1
  179. package/{library/types → types}/UeInstanceMessage/StreamMessageController.d.ts +3 -5
  180. package/{library/types → types}/Util/EventEmitter.d.ts +40 -3
  181. package/types/Util/RTCUtils.d.ts +8 -0
  182. package/{library/types → types}/VideoPlayer/StreamController.d.ts +3 -3
  183. package/{library/types → types}/VideoPlayer/VideoPlayer.d.ts +2 -0
  184. package/{library/types → types}/WebRtcPlayer/WebRtcPlayerController.d.ts +30 -27
  185. package/{library/types → types}/WebSockets/MessageReceive.d.ts +9 -9
  186. package/{library/types → types}/WebSockets/MessageSend.d.ts +13 -9
  187. package/{library/types → types}/WebSockets/SignallingProtocol.d.ts +3 -3
  188. package/{library/types → types}/WebSockets/WebSocketController.d.ts +16 -12
  189. package/{library/types → types}/pixelstreamingfrontend.d.ts +2 -1
  190. package/webpack.common.js +35 -0
  191. package/webpack.dev.js +35 -0
  192. package/webpack.prod.js +36 -0
  193. package/yang__yj-pixelstreaming-core-1.0.1.tgz +0 -0
  194. package/yang__yj-pixelstreaming-core-1.0.2.tgz +0 -0
  195. package/library/dist/lib-pixelstreamingfrontend.esm.js +0 -1
  196. package/library/dist/lib-pixelstreamingfrontend.js +0 -1
  197. /package/{library/types → types}/AFK/AFKController.d.ts +0 -0
  198. /package/{library/types → types}/Config/SettingBase.d.ts +0 -0
  199. /package/{library/types → types}/Config/SettingFlag.d.ts +0 -0
  200. /package/{library/types → types}/Config/SettingNumber.d.ts +0 -0
  201. /package/{library/types → types}/Config/SettingOption.d.ts +0 -0
  202. /package/{library/types → types}/Config/SettingText.d.ts +0 -0
  203. /package/{library/types → types}/DataChannel/DataChannelController.d.ts +0 -0
  204. /package/{library/types → types}/DataChannel/DataChannelSender.d.ts +0 -0
  205. /package/{library/types → types}/DataChannel/InitialSettings.d.ts +0 -0
  206. /package/{library/types → types}/DataChannel/LatencyTestResults.d.ts +0 -0
  207. /package/{library/types → types}/FreezeFrame/FreezeFrame.d.ts +0 -0
  208. /package/{library/types → types}/FreezeFrame/FreezeFrameController.d.ts +0 -0
  209. /package/{library/types → types}/Inputs/FakeTouchController.d.ts +0 -0
  210. /package/{library/types → types}/Inputs/GamepadController.d.ts +0 -0
  211. /package/{library/types → types}/Inputs/GamepadTypes.d.ts +0 -0
  212. /package/{library/types → types}/Inputs/IMouseEvents.d.ts +0 -0
  213. /package/{library/types → types}/Inputs/ITouchController.d.ts +0 -0
  214. /package/{library/types → types}/Inputs/InputClassesFactory.d.ts +0 -0
  215. /package/{library/types → types}/Inputs/KeyboardController.d.ts +0 -0
  216. /package/{library/types → types}/Inputs/LockedMouseEvents.d.ts +0 -0
  217. /package/{library/types → types}/Inputs/MouseButtons.d.ts +0 -0
  218. /package/{library/types → types}/Inputs/MouseController.d.ts +0 -0
  219. /package/{library/types → types}/Inputs/SpecialKeyCodes.d.ts +0 -0
  220. /package/{library/types → types}/Inputs/TouchController.d.ts +0 -0
  221. /package/{library/types → types}/Inputs/XRGamepadController.d.ts +0 -0
  222. /package/{library/types → types}/Logger/Logger.d.ts +0 -0
  223. /package/{library/types → types}/PeerConnectionController/AggregatedStats.d.ts +0 -0
  224. /package/{library/types → types}/PeerConnectionController/CandidatePairStats.d.ts +0 -0
  225. /package/{library/types → types}/PeerConnectionController/CandidateStat.d.ts +0 -0
  226. /package/{library/types → types}/PeerConnectionController/CodecStats.d.ts +0 -0
  227. /package/{library/types → types}/PeerConnectionController/DataChannelStats.d.ts +0 -0
  228. /package/{library/types → types}/PeerConnectionController/InboundRTPStats.d.ts +0 -0
  229. /package/{library/types → types}/PeerConnectionController/InboundTrackStats.d.ts +0 -0
  230. /package/{library/types → types}/PeerConnectionController/OutBoundRTPStats.d.ts +0 -0
  231. /package/{library/types → types}/PeerConnectionController/SessionStats.d.ts +0 -0
  232. /package/{library/types → types}/PeerConnectionController/StreamStats.d.ts +0 -0
  233. /package/{library/types → types}/UI/OnScreenKeyboard.d.ts +0 -0
  234. /package/{library/types → types}/UeInstanceMessage/ResponseController.d.ts +0 -0
  235. /package/{library/types → types}/UeInstanceMessage/SendDescriptorController.d.ts +0 -0
  236. /package/{library/types → types}/UeInstanceMessage/ToStreamerMessagesController.d.ts +0 -0
  237. /package/{library/types → types}/UeInstanceMessage/TwoWayMap.d.ts +0 -0
  238. /package/{library/types → types}/Util/CoordinateConverter.d.ts +0 -0
  239. /package/{library/types → types}/Util/EventListenerTracker.d.ts +0 -0
  240. /package/{library/types → types}/Util/FileUtil.d.ts +0 -0
  241. /package/{library/types → types}/Util/WebGLUtils.d.ts +0 -0
  242. /package/{library/types → types}/Util/WebXRUtils.d.ts +0 -0
  243. /package/{library/types → types}/WebXR/WebXRController.d.ts +0 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The Send Types that are pushed from the signaling server
2
+ * 从发信服务器推送的发送类型
3
3
  */
4
4
  export declare enum MessageSendTypes {
5
5
  LIST_STREAMERS = "listStreamers",
@@ -13,27 +13,31 @@ export declare enum MessageSendTypes {
13
13
  PONG = "pong"
14
14
  }
15
15
  /**
16
- * A Wrapper for the message to send to the signaling server
16
+ * 要发送到发信服务器的消息的包装器
17
17
  */
18
18
  export declare class MessageSend implements Send {
19
19
  type: string;
20
20
  peerConnectionOptions: object;
21
21
  /**
22
- * Turns the wrapper into a JSON String
23
- * @returns - JSON String of the Message to send
22
+ * 将包装器转换为JSON字符串
23
+ * @returns——要发送的消息的JSON字符串
24
24
  */
25
25
  payload(): string;
26
26
  }
27
27
  export interface Send {
28
28
  /**
29
- * Turns the wrapper into a JSON String
30
- * @returns - JSON String of the Message to send
29
+ *将包装器转换为JSON字符串
30
+ * @returns——要发送的消息的JSON字符串
31
31
  */
32
32
  payload: () => string;
33
33
  }
34
34
  export declare class MessageListStreamers extends MessageSend {
35
35
  constructor();
36
36
  }
37
+ export declare class requestStreamerObject extends MessageSend {
38
+ streamerName: string;
39
+ constructor(streamerid: string);
40
+ }
37
41
  export declare class MessageSubscribe extends MessageSend {
38
42
  streamerId: string;
39
43
  constructor(streamerid: string);
@@ -42,14 +46,14 @@ export declare class MessageUnsubscribe extends MessageSend {
42
46
  constructor();
43
47
  }
44
48
  /**
45
- * Instance Request Message Wrapper
49
+ * 实例请求消息包装器
46
50
  */
47
51
  export declare class MessagePong extends MessageSend {
48
52
  time: number;
49
53
  constructor(time: number);
50
54
  }
51
55
  /**
52
- * Web RTC Offer message wrapper
56
+ * Web RTC提供消息包装器
53
57
  */
54
58
  export declare class MessageWebRTCOffer extends MessageSend {
55
59
  sdp: string;
@@ -59,7 +63,7 @@ export declare class MessageWebRTCOffer extends MessageSend {
59
63
  constructor(offer?: RTCSessionDescriptionInit);
60
64
  }
61
65
  /**
62
- * Web RTC Answer message wrapper
66
+ * Web RTC应答消息包装器
63
67
  */
64
68
  export declare class MessageWebRTCAnswer extends MessageSend {
65
69
  sdp: string;
@@ -1,6 +1,6 @@
1
1
  import { WebSocketController } from './WebSocketController';
2
2
  /**
3
- * Signalling protocol for handling messages from the signalling server.
3
+ * 信令协议,用于处理来自信令服务器的消息。
4
4
  */
5
5
  export declare class SignallingProtocol {
6
6
  private FromUEMessageHandlers;
@@ -8,8 +8,8 @@ export declare class SignallingProtocol {
8
8
  addMessageHandler(messageId: string, messageHandler: (payload: string) => void): void;
9
9
  handleMessage(messageId: string, messageData: string): void;
10
10
  /**
11
- * Setup any default signalling message handling, these can be overridden or additional handlers added with `addMessageHandler`.
12
- * @param websocketController The controller to setup these handlers on.
11
+ * 设置任何默认的信号消息处理,这些可以被覆盖或使用`addMessageHandler`添加额外的处理程序。
12
+ * @param websocketController 设置这些处理程序的控制器。
13
13
  */
14
14
  static setupDefaultHandlers(websocketController: WebSocketController): void;
15
15
  }
@@ -16,37 +16,38 @@ export declare class WebSocketController {
16
16
  signallingProtocol: SignallingProtocol;
17
17
  constructor();
18
18
  /**
19
- * Connect to the signaling server
20
- * @param connectionURL - The Address of the signaling server
21
- * @returns - If there is a connection
19
+ * 连接发信服务器
20
+ * @param connectionURL——发信服务器的地址
21
+ * @returns—是否存在连接
22
22
  */
23
23
  connect(connectionURL: string): boolean;
24
24
  /**
25
- * Handles what happens when a message is received in binary form
25
+ * 处理以二进制形式接收消息时发生的情况
26
26
  * @param event - Message Received
27
27
  */
28
28
  handleOnMessageBinary(event: MessageEvent): void;
29
29
  /**
30
- * Handles what happens when a message is received
30
+ * 处理接收到消息时发生的事情
31
31
  * @param event - Message Received
32
32
  */
33
33
  handleOnMessage(event: MessageEvent): void;
34
34
  /**
35
- * Handles when the Websocket is opened
35
+ * 处理Websocket打开时的事件
36
36
  * @param event - Not Used
37
37
  */
38
38
  handleOnOpen(event: Event): void;
39
39
  /**
40
- * Handles when there is an error on the websocket
40
+ * websocket中处理错误
41
41
  * @param event - Error Payload
42
42
  */
43
43
  handleOnError(): void;
44
44
  /**
45
- * Handles when the Websocket is closed
45
+ * Websocket关闭时处理
46
46
  * @param event - Close Event
47
47
  */
48
48
  handleOnClose(event: CloseEvent): void;
49
49
  requestStreamerList(): void;
50
+ requestStreamerObject(streamerid: string): void;
50
51
  sendSubscribe(streamerid: string): void;
51
52
  sendUnsubscribe(): void;
52
53
  sendWebRtcOffer(offer: RTCSessionDescriptionInit): void;
@@ -54,16 +55,14 @@ export declare class WebSocketController {
54
55
  sendWebRtcDatachannelRequest(): void;
55
56
  sendSFURecvDataChannelReady(): void;
56
57
  /**
57
- * Sends an RTC Ice Candidate to the Server
58
- * @param candidate - RTC Ice Candidate
58
+ *向服务器发送一个RTC Ice候选项
59
+ * @param candidateRTC Ice候选
59
60
  */
60
61
  sendIceCandidate(candidate: RTCIceCandidate): void;
61
62
  /**
62
63
  * Closes the Websocket connection
63
64
  */
64
65
  close(): void;
65
- /** Event used for Displaying websocket closed messages */
66
- onWebSocketOncloseOverlayMessage(event: CloseEvent): void;
67
66
  /**
68
67
  * The Message Contains the payload of the peer connection options used for the RTC Peer hand shake
69
68
  * @param messageConfig - Config Message received from he signaling server
@@ -93,4 +92,9 @@ export declare class WebSocketController {
93
92
  * @param messageDataChannels - The data channels details
94
93
  */
95
94
  onWebRtcPeerDataChannels(messageDataChannels: MessageReceive.MessagePeerDataChannels): void;
95
+ /**
96
+ * Event is fired when the websocket receives the an updated player count from cirrus
97
+ * @param MessagePlayerCount - The new player count
98
+ */
99
+ onPlayerCount(playerCount: MessageReceive.MessagePlayerCount): void;
96
100
  }
@@ -1,6 +1,6 @@
1
1
  export { WebRtcPlayerController } from './WebRtcPlayer/WebRtcPlayerController';
2
2
  export { WebXRController } from './WebXR/WebXRController';
3
- export { Config, ControlSchemeType, Flags, NumericParameters, TextParameters, OptionParameters, FlagsIds, NumericParametersIds, TextParametersIds, OptionParametersIds, AllSettings } from './Config/Config';
3
+ export { Config, ControlSchemeType, Flags, NumericParameters, TextParameters, OptionParameters, } from './Config/Config';
4
4
  export { SettingBase } from './Config/SettingBase';
5
5
  export { SettingFlag } from './Config/SettingFlag';
6
6
  export { SettingNumber } from './Config/SettingNumber';
@@ -13,6 +13,7 @@ export { EncoderSettings, InitialSettings, WebRTCSettings } from './DataChannel/
13
13
  export { AggregatedStats } from './PeerConnectionController/AggregatedStats';
14
14
  export { Logger } from './Logger/Logger';
15
15
  export { UnquantizedDenormalizedUnsignedCoord as UnquantizedAndDenormalizeUnsigned } from './Util/CoordinateConverter';
16
+ export { MessageDirection } from './UeInstanceMessage/StreamMessageController';
16
17
  export { MessageSend } from './WebSockets/MessageSend';
17
18
  export { MessageRecv, MessageStreamerList } from './WebSockets/MessageReceive';
18
19
  export { WebSocketController } from './WebSockets/WebSocketController';
@@ -0,0 +1,35 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ const package = require('./package.json');
4
+ const path = require('path');
5
+ const webpack = require('webpack');
6
+
7
+ module.exports = {
8
+ entry: {
9
+ index: './src/pixelstreamingfrontend.ts'
10
+ },
11
+ module: {
12
+ rules: [
13
+ {
14
+ test: /\.tsx?$/,
15
+ loader: 'ts-loader',
16
+ exclude: [/node_modules/]
17
+ }
18
+ ]
19
+ },
20
+ resolve: {
21
+ extensions: ['.tsx', '.ts', '.js']
22
+ },
23
+ externals: {
24
+ sdp: "sdp"
25
+ },
26
+ plugins: [
27
+ new webpack.DefinePlugin({
28
+ LIBRARY_VERSION: JSON.stringify(package.version)
29
+ })
30
+ ],
31
+ output: {
32
+ path: path.resolve(__dirname, 'dist'),
33
+ globalObject: 'this'
34
+ }
35
+ };
package/webpack.dev.js ADDED
@@ -0,0 +1,35 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ const { merge } = require('webpack-merge');
4
+ const common = require('./webpack.common.js');
5
+
6
+ const devCommon = {
7
+ mode: 'development',
8
+ devtool: 'inline-source-map',
9
+ devServer: {
10
+ static: './dist',
11
+ }
12
+ };
13
+
14
+ module.exports = [
15
+ merge(common, devCommon, {
16
+ output: {
17
+ filename: 'lib-pixelstreamingfrontend.js',
18
+ library: {
19
+ name: 'lib-pixelstreamingfrontend', // exposed variable that will provide access to the library classes
20
+ type: 'umd'
21
+ },
22
+ },
23
+ }),
24
+ merge(common, devCommon, {
25
+ output: {
26
+ filename: 'lib-pixelstreamingfrontend.esm.js',
27
+ library: {
28
+ type: 'module'
29
+ },
30
+ },
31
+ experiments: {
32
+ outputModule: true
33
+ }
34
+ })
35
+ ];
@@ -0,0 +1,36 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ const { merge } = require('webpack-merge');
4
+ const common = require('./webpack.common.js');
5
+
6
+ const prodCommon = {
7
+ mode: 'production',
8
+ optimization: {
9
+ usedExports: true,
10
+ minimize: true
11
+ },
12
+ stats: 'errors-only',
13
+ };
14
+
15
+ module.exports = [
16
+ merge(common, prodCommon, {
17
+ output: {
18
+ filename: 'lib-pixelstreamingfrontend.js',
19
+ library: {
20
+ name: 'lib-pixelstreamingfrontend', // exposed variable that will provide access to the library classes
21
+ type: 'umd'
22
+ },
23
+ },
24
+ }),
25
+ merge(common, prodCommon, {
26
+ output: {
27
+ filename: 'lib-pixelstreamingfrontend.esm.js',
28
+ library: {
29
+ type: 'module'
30
+ },
31
+ },
32
+ experiments: {
33
+ outputModule: true
34
+ }
35
+ })
36
+ ];
@@ -1 +0,0 @@
1
- import*as e from"sdp";var t,s,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]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},r={};n.d(r,{Dz:()=>ve,g$:()=>A,Lt:()=>k,Q9:()=>x,qf:()=>L,hV:()=>Re,z$:()=>be,J0:()=>ye,De:()=>Se,$C:()=>pe,al:()=>_,_W:()=>W,tz:()=>B,Nu:()=>Ee,zg:()=>Ge,vp:()=>oe,vU:()=>ae,wF:()=>Y,rv:()=>fe,Nh:()=>Te,ss:()=>Ue,qW:()=>te,QL:()=>ee,cf:()=>Be,eM:()=>j,Yd:()=>i,iM:()=>p,qy:()=>o,ce:()=>v,sK:()=>de,Ok:()=>ue,q5:()=>Me,g:()=>Tt,xl:()=>$,I:()=>q,bx:()=>X,Ib:()=>b,Az:()=>M,Iw:()=>w,qY:()=>R,db:()=>P,mR:()=>se,Tn:()=>C,rV:()=>J,gh:()=>V,Mi:()=>N,j:()=>K,YB:()=>Q,i5:()=>Z,x_:()=>he,Am:()=>gt,eR:()=>F,r8:()=>H,u3:()=>ze,vd:()=>O,iV:()=>I,jZ:()=>U,SW:()=>z,ZH:()=>G,Ni:()=>mt,lh:()=>D,bq:()=>f,$f:()=>Ct,eu:()=>ie,Ax:()=>re,Mc:()=>ne});class i{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)}}i.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 o{payload(){return i.Log(i.GetStackTrace(),"Sending => \n"+JSON.stringify(this,void 0,4),6),JSON.stringify(this)}}class a extends o{constructor(){super(),this.type=t.LIST_STREAMERS}}class l extends o{constructor(e){super(),this.type=t.SUBSCRIBE,this.streamerId=e}}class d extends o{constructor(){super(),this.type=t.UNSUBSCRIBE}}class c extends o{constructor(e){super(),this.type=t.PONG,this.time=e}}class h extends o{constructor(e){super(),this.type=t.OFFER,e&&(this.type=e.type,this.sdp=e.sdp)}}class g extends o{constructor(e){super(),this.type=t.ANSWER,e&&(this.type=e.type,this.sdp=e.sdp)}}class u extends o{constructor(){super(),this.type=t.DATACHANNELREQUEST}}class m extends o{constructor(){super(),this.type=t.SFURECVDATACHANNELREADY}}class S{constructor(e){this.type=t.ICE_CANDIDATE,this.candidate=e}payload(){return i.Log(i.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(e,t){this.FromUEMessageHandlers.has(e)?this.FromUEMessageHandlers.get(e)(t):i.Error(i.GetStackTrace(),`Message type of ${e} does not have a message handler registered on the frontend - ignoring message.`)}static setupDefaultHandlers(e){e.signallingProtocol.addMessageHandler(s.PING,(t=>{const n=new c((new Date).getTime()).payload();i.Log(i.GetStackTrace(),s.PING+": "+t,6),e.webSocket.send(n)})),e.signallingProtocol.addMessageHandler(s.CONFIG,(t=>{i.Log(i.GetStackTrace(),s.CONFIG,6);const n=JSON.parse(t);e.onConfig(n)})),e.signallingProtocol.addMessageHandler(s.STREAMER_LIST,(t=>{i.Log(i.GetStackTrace(),s.STREAMER_LIST,6);const n=JSON.parse(t);e.onStreamerList(n)})),e.signallingProtocol.addMessageHandler(s.PLAYER_COUNT,(e=>{i.Log(i.GetStackTrace(),s.PLAYER_COUNT,6);const t=JSON.parse(e);i.Log(i.GetStackTrace(),"Player Count: "+t.count,6)})),e.signallingProtocol.addMessageHandler(s.ANSWER,(t=>{i.Log(i.GetStackTrace(),s.ANSWER,6);const n=JSON.parse(t);e.onWebRtcAnswer(n)})),e.signallingProtocol.addMessageHandler(s.OFFER,(t=>{i.Log(i.GetStackTrace(),s.OFFER,6);const n=JSON.parse(t);e.onWebRtcOffer(n)})),e.signallingProtocol.addMessageHandler(s.ICE_CANDIDATE,(t=>{i.Log(i.GetStackTrace(),s.ICE_CANDIDATE,6);const n=JSON.parse(t);e.onIceCandidate(n.candidate)})),e.signallingProtocol.addMessageHandler(s.WARNING,(e=>{i.Warning(i.GetStackTrace(),`Warning received: ${e}`)})),e.signallingProtocol.addMessageHandler(s.PEER_DATA_CHANNELS,(t=>{i.Log(i.GetStackTrace(),s.PEER_DATA_CHANNELS,6);const n=JSON.parse(t);e.onWebRtcPeerDataChannels(n)}))}}class f{constructor(){this.WS_OPEN_STATE=1,this.onOpen=new EventTarget,this.onClose=new EventTarget,this.signallingProtocol=new C,C.setupDefaultHandlers(this)}connect(e){i.Log(i.GetStackTrace(),e,6);try{return this.webSocket=new WebSocket(e),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(e){return i.Error(e,e),!1}}handleOnMessageBinary(e){e&&e.data&&e.data.text().then((e=>{const t=new MessageEvent("messageFromBinary",{data:e});this.handleOnMessage(t)})).catch((e=>{i.Error(i.GetStackTrace(),`Failed to parse binary blob from websocket, reason: ${e}`)}))}handleOnMessage(e){if(e.data&&e.data instanceof Blob)return void this.handleOnMessageBinary(e);const t=JSON.parse(e.data);i.Log(i.GetStackTrace(),"received => \n"+JSON.stringify(JSON.parse(e.data),void 0,4),6),this.signallingProtocol.handleMessage(t.type,e.data)}handleOnOpen(e){i.Log(i.GetStackTrace(),"Connected to the signalling server via WebSocket",6),this.onOpen.dispatchEvent(new Event("open"))}handleOnError(){i.Error(i.GetStackTrace(),"WebSocket error")}handleOnClose(e){this.onWebSocketOncloseOverlayMessage(e),i.Log(i.GetStackTrace(),"Disconnected to the signalling server via WebSocket: "+JSON.stringify(e.code)+" - "+e.reason),this.onClose.dispatchEvent(new CustomEvent("close",{detail:e}))}requestStreamerList(){const e=new a;this.webSocket.send(e.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(e){if(i.Log(i.GetStackTrace(),"Sending Ice Candidate"),this.webSocket&&this.webSocket.readyState===this.WS_OPEN_STATE){const t=new S(e);this.webSocket.send(t.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 T{constructor(e){this.videoElementProvider=e,this.audioElement=document.createElement("Audio")}handleOnTrack(e){i.Log(i.GetStackTrace(),"handleOnTrack "+JSON.stringify(e.streams),6);const t=this.videoElementProvider.getVideoElement();if(e.track&&i.Log(i.GetStackTrace(),"Got track - "+e.track.kind+" id="+e.track.id+" readyState="+e.track.readyState,6),"audio"!=e.track.kind)return"video"==e.track.kind&&t.srcObject!==e.streams[0]?(t.srcObject=e.streams[0],void i.Log(i.GetStackTrace(),"Set video source from video track ontrack.")):void 0;this.CreateAudioTrack(e.streams[0])}CreateAudioTrack(e){const t=this.videoElementProvider.getVideoElement();t.srcObject!=e&&t.srcObject&&t.srcObject!==e&&(this.audioElement.srcObject=e,i.Log(i.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(e,t){this.receiving||(this.receiving=!0,this.valid=!1,this.size=0,this.jpeg=void 0),this.size=new DataView(e.slice(1,5).buffer).getInt32(0,!0);const s=e.slice(5);if(this.jpeg){const e=new Uint8Array(this.jpeg.length+s.length);e.set(this.jpeg,0),e.set(s,this.jpeg.length),this.jpeg=e}else this.jpeg=s,this.receiving=!0,i.Log(i.GetStackTrace(),`received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`,6);this.jpeg.length===this.size?(this.receiving=!1,this.valid=!0,i.Log(i.GetStackTrace(),`received complete freeze frame ${this.size}`,6),this.updateFreezeFrameAndShow(this.jpeg,t)):this.jpeg.length>this.size&&(i.Error(i.GetStackTrace(),`received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`),this.jpeg=void 0,this.receiving=!1)}}class b{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 b{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 b{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 P extends b{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 b{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){const t=this.options.filter((t=>-1!==t.indexOf(e)));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 U extends Event{constructor(){super("webRtcConnecting")}}class I extends Event{constructor(){super("webRtcConnected")}}class G 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 W extends Event{constructor(e){super("dataChannelError"),this.data=e}}class H 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 $ extends Event{constructor(e){super("playStreamError"),this.data=e}}class q 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 Y extends Event{constructor(){super("hideFreezeFrame")}}class J 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("initialSettings"),this.data=e}}class se extends Event{constructor(e){super("settingsChanged"),this.data=e}}class ne extends Event{constructor(){super("xrSessionStarted")}}class re extends Event{constructor(){super("xrSessionEnded")}}class ie extends Event{constructor(e){super("xrFrame"),this.data=e}}class oe extends EventTarget{dispatchEvent(e){return super.dispatchEvent(e)}addEventListener(e,t){super.addEventListener(e,t)}removeEventListener(e,t){super.removeEventListener(e,t)}}class ae{}ae.AutoConnect="AutoConnect",ae.AutoPlayVideo="AutoPlayVideo",ae.AFKDetection="TimeoutIfIdle",ae.BrowserSendOffer="OfferToReceive",ae.HoveringMouseMode="HoveringMouse",ae.ForceMonoAudio="ForceMonoAudio",ae.ForceTURN="ForceTURN",ae.FakeMouseWithTouches="FakeMouseWithTouches",ae.IsQualityController="ControlsQuality",ae.MatchViewportResolution="MatchViewportRes",ae.PreferSFU="preferSFU",ae.StartVideoMuted="StartVideoMuted",ae.SuppressBrowserKeys="SuppressBrowserKeys",ae.UseMic="UseMic",ae.KeyboardInput="KeyboardInput",ae.MouseInput="MouseInput",ae.TouchInput="TouchInput",ae.GamepadInput="GamepadInput",ae.XRControllerInput="XRControllerInput";const le=e=>Object.getOwnPropertyNames(ae).some((t=>ae[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 ce=e=>Object.getOwnPropertyNames(de).some((t=>de[t]===e));class he{}he.SignallingServerUrl="ss";const ge=e=>Object.getOwnPropertyNames(he).some((t=>he[t]===e));class ue{}ue.PreferredCodec="PreferredCodec",ue.StreamerId="StreamerId";const me=e=>Object.getOwnPropertyNames(ue).some((t=>ue[t]===e));class Se{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(he.SignallingServerUrl,new P(he.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(ue.StreamerId,new R(ue.StreamerId,"Streamer ID","The ID of the streamer to stream.","",[],e)),this.optionParameters.set(ue.PreferredCodec,new R(ue.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(ae.AutoConnect,new M(ae.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(ae.AutoPlayVideo,new M(ae.AutoPlayVideo,"Auto play video","When video is ready automatically start playing it as opposed to showing a play button.",!0,e)),this.flags.set(ae.BrowserSendOffer,new M(ae.BrowserSendOffer,"Browser send offer","Browser will initiate the WebRTC handshake by sending the offer to the streamer",!1,e)),this.flags.set(ae.UseMic,new M(ae.UseMic,"Use microphone","Make browser request microphone access and open an input audio track.",!1,e)),this.flags.set(ae.StartVideoMuted,new M(ae.StartVideoMuted,"Start video muted","Video will start muted if true.",!1,e)),this.flags.set(ae.SuppressBrowserKeys,new M(ae.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(ae.PreferSFU,new M(ae.PreferSFU,"Prefer SFU","Try to connect to the SFU instead of P2P.",!1,e)),this.flags.set(ae.IsQualityController,new M(ae.IsQualityController,"Is quality controller?","True if this peer controls stream quality",!0,e)),this.flags.set(ae.ForceMonoAudio,new M(ae.ForceMonoAudio,"Force mono audio","Force browser to request mono audio in the SDP",!1,e)),this.flags.set(ae.ForceTURN,new M(ae.ForceTURN,"Force TURN","Only generate TURN/Relayed ICE candidates.",!1,e)),this.flags.set(ae.AFKDetection,new M(ae.AFKDetection,"AFK if idle","Timeout the experience if user is AFK for a period.",!1,e)),this.flags.set(ae.MatchViewportResolution,new M(ae.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(ae.HoveringMouseMode,new M(ae.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(ae.FakeMouseWithTouches,new M(ae.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(ae.KeyboardInput,new M(ae.KeyboardInput,"Keyboard input","If enabled, send keyboard events to streamer",!0,e)),this.flags.set(ae.MouseInput,new M(ae.MouseInput,"Mouse input","If enabled, send mouse events to streamer",!0,e)),this.flags.set(ae.TouchInput,new M(ae.TouchInput,"Touch input","If enabled, send touch events to streamer",!0,e)),this.flags.set(ae.GamepadInput,new M(ae.GamepadInput,"Gamepad input","If enabled, send gamepad events to streamer",!0,e)),this.flags.set(ae.XRControllerInput,new M(ae.XRControllerInput,"XR controller input","If enabled, send XR controller events to streamer",!0,e)),this.numericParameters.set(de.AFKTimeoutSecs,new w(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 w(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 w(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 w(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 w(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 w(de.WebRTCMinBitrate,"Min Bitrate (kbps)","The minimum bitrate that WebRTC should use.",0,5e5,0,e)),this.numericParameters.set(de.WebRTCMaxBitrate,new w(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(e,t){this.flags.has(e)?this.flags.get(e).flag=t:i.Warning(i.GetStackTrace(),`Cannot toggle flag called ${e} - it does not exist in the Config.flags map.`)}setTextSetting(e,t){this.textParameters.has(e)?this.textParameters.get(e).text=t:i.Warning(i.GetStackTrace(),`Cannot set text setting called ${e} - it does not exist in the Config.textParameters map.`)}setOptionSettingOptions(e,t){this.optionParameters.has(e)?this.optionParameters.get(e).options=t:i.Warning(i.GetStackTrace(),`Cannot set text setting called ${e} - it does not exist in the Config.optionParameters map.`)}setOptionSettingValue(e,t){this.optionParameters.has(e)?this.optionParameters.get(e).selected=t:i.Warning(i.GetStackTrace(),`Cannot set text setting called ${e} - it does not exist in the Config.enumParameters map.`)}setFlagLabel(e,t){this.flags.has(e)?this.flags.get(e).label=t:i.Warning(i.GetStackTrace(),`Cannot set label for flag called ${e} - it does not exist in the Config.flags map.`)}setSettings(e){for(const t of Object.keys(e))le(t)?this.setFlagEnabled(t,e[t]):ce(t)?this.setNumericSetting(t,e[t]):ge(t)?this.setTextSetting(t,e[t]):me(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 se({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 se({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 se({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 se({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 ve{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(de.AFKTimeoutSecs)>0&&this.config.isFlagEnabled(ae.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(ae.AFKDetection)&&(clearTimeout(this.warnTimer),this.warnTimer=setTimeout((()=>this.activateAfkEvent()),1e3*this.config.getNumericSettingValue(de.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(ae.HoveringMouseMode)||document.exitPointerLock&&document.exitPointerLock(),this.countDownTimer=setInterval((()=>{this.countDown--,0==this.countDown?(this.pixelStreaming.dispatchEvent(new A),this.onAFKTimedOutCallback(),i.Log(i.GetStackTrace(),"You have been disconnected due to inactivity"),this.stopAfkWarningTimer()):this.pixelStreaming.dispatchEvent(new L({countDown:this.countDown}))}),1e3)}}class Ce{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(e){var t;i.Log(i.GetStackTrace(),`Data Channel (${this.label}) opened.`,7),this.onOpen(null===(t=this.dataChannel)||void 0===t?void 0:t.label,e)}handleOnClose(e){var t;i.Log(i.GetStackTrace(),`Data Channel (${this.label}) closed.`,7),this.onClose(null===(t=this.dataChannel)||void 0===t?void 0:t.label,e)}handleOnMessage(e){i.Log(i.GetStackTrace(),`Data Channel (${this.label}) message: ${e}`,8)}handleOnError(e){var t;i.Log(i.GetStackTrace(),`Data Channel (${this.label}) error: ${e}`,7),this.onError(null===(t=this.dataChannel)||void 0===t?void 0:t.label,e)}onOpen(e,t){}onClose(e,t){}onError(e,t){}}class fe{}class Te{}class Ee{}class ye{}class be{}class Me{}class we{}class Pe{}class Re{constructor(){this.inboundVideoStats=new Te,this.inboundAudioStats=new fe,this.candidatePair=new be,this.DataChannelStats=new Ee,this.outBoundVideoStats=new Me,this.sessionStats=new we,this.streamStats=new Pe,this.codecs=new Map}processStats(e){this.localCandidates=new Array,this.remoteCandidates=new Array,e.forEach((e=>{switch(e.type){case"candidate-pair":this.handleCandidatePair(e);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(e);break;case"data-channel":this.handleDataChannel(e);break;case"inbound-rtp":this.handleInBoundRTP(e);break;case"local-candidate":this.handleLocalCandidate(e);break;case"remote-candidate":this.handleRemoteCandidate(e);break;case"remote-outbound-rtp":this.handleRemoteOutBound(e);break;case"track":this.handleTrack(e);break;case"stream":this.handleStream(e);break;default:i.Error(i.GetStackTrace(),"unhandled Stat Type"),i.Log(i.GetStackTrace(),e)}}))}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 ye;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 ye;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(e){switch(e.kind){case"video":this.inboundVideoStats=e,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=e,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:i.Log(i.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)}}const ke=(Le={parseRtpParameters:()=>e.parseRtpParameters,splitSections:()=>e.splitSections},xe={},n.d(xe,Le),xe);var Le,xe,Ae,Fe,De=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 Oe{constructor(e,t,s){this.config=t,this.createPeerConnection(e,s)}createPeerConnection(e,t){this.config.isFlagEnabled(ae.ForceTURN)&&(e.iceTransportPolicy="relay",i.Log(i.GetStackTrace(),"Forcing TURN usage by setting ICE Transport Policy in peer connection config.")),this.peerConnection=new RTCPeerConnection(e),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 Re,this.preferredCodec=t,this.updateCodecSelection=!0}createOffer(e,t){return De(this,void 0,void 0,(function*(){i.Log(i.GetStackTrace(),"Create Offer",6);const s="localhost"===location.hostname||"127.0.0.1"===location.hostname,n="https:"===location.protocol;let r=t.isFlagEnabled(ae.UseMic);!r||s||n||(r=!1,i.Error(i.GetStackTrace(),"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access."),i.Error(i.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.createOffer(e).then((e=>{var t;this.showTextOverlayConnecting(),e.sdp=this.mungeSDP(e.sdp,r),null===(t=this.peerConnection)||void 0===t||t.setLocalDescription(e),this.onSendWebRTCOffer(e)})).catch((()=>{this.showTextOverlaySetupFailure()}))}))}))}receiveOffer(e,t){var s;return De(this,void 0,void 0,(function*(){i.Log(i.GetStackTrace(),"Receive Offer",6),null===(s=this.peerConnection)||void 0===s||s.setRemoteDescription(e).then((()=>{const e="localhost"===location.hostname||"127.0.0.1"===location.hostname,s="https:"===location.protocol;let n=t.isFlagEnabled(ae.UseMic);!n||e||s||(n=!1,i.Error(i.GetStackTrace(),"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access."),i.Error(i.GetStackTrace(),"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'")),this.setupTransceiversAsync(n).finally((()=>{var e;null===(e=this.peerConnection)||void 0===e||e.createAnswer().then((e=>{var t;return e.sdp=this.mungeSDP(e.sdp,n),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((()=>{i.Error(i.GetStackTrace(),"createAnswer() failed")}))}))})),this.config.setOptionSettingOptions(ue.PreferredCodec,this.parseAvailableCodecs(e).filter((e=>this.config.getSettingOption(ue.PreferredCodec).options.includes(e))))}))}receiveAnswer(e){var t;null===(t=this.peerConnection)||void 0===t||t.setRemoteDescription(e),this.config.setOptionSettingOptions(ue.PreferredCodec,this.parseAvailableCodecs(e).filter((e=>this.config.getSettingOption(ue.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(ue.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(ae.ForceMonoAudio)?"stereo=0;":"stereo=1;",n+="useinbandfec=1",s.replace("useinbandfec=1",n),s}handleOnIce(e){var t;i.Log(i.GetStackTrace(),"peerconnection handleOnIce",6),this.config.isFlagEnabled(ae.ForceTURN)&&e.candidate.indexOf("relay")<0?i.Info(i.GetStackTrace(),`Dropping candidate because it was not TURN relay. | Type= ${e.type} | Protocol= ${e.protocol} | Address=${e.address} | Port=${e.port} |`,6):null===(t=this.peerConnection)||void 0===t||t.addIceCandidate(e)}handleSignalStateChange(e){i.Log(i.GetStackTrace(),"signaling state change: "+e,6)}handleIceConnectionStateChange(e){i.Log(i.GetStackTrace(),"ice connection state change: "+e,6),this.onIceConnectionStateChange(e)}handleIceGatheringStateChange(e){i.Log(i.GetStackTrace(),"ice gathering state change: "+JSON.stringify(e),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 De(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(ue.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===(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,ke.splitSections)(e.sdp);return s.shift(),s.forEach((e=>{const{codecs:s}=(0,ke.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 Ie,this.EncoderSettings=new Ge,this.WebRTCSettings=new ze}ueCompatible(){null!=this.WebRTCSettings.MaxFPS&&(this.WebRTCSettings.FPS=this.WebRTCSettings.MaxFPS)}}class Ie{}class Ge{}class ze{}class Be{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||(i.Log(i.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||(i.Log(i.GetStackTrace(),`Setting CaptureToSendMs Ms \n ${this.PostCaptureTimeMs} \n ${this.PreCaptureTimeMs}`,6),this.CaptureToSendMs=this.PostCaptureTimeMs-this.PreCaptureTimeMs)}}class _e{static setExtensionFromBytes(e,t){t.receiving||(t.mimetype="",t.extension="",t.receiving=!0,t.valid=!1,t.size=0,t.data=[],t.timestampStart=(new Date).getTime(),i.Log(i.GetStackTrace(),"Received first chunk of file",6));const s=new TextDecoder("utf-16").decode(e.slice(1));i.Log(i.GetStackTrace(),s,6),t.extension=s}static setMimeTypeFromBytes(e,t){t.receiving||(t.mimetype="",t.extension="",t.receiving=!0,t.valid=!1,t.size=0,t.data=[],t.timestampStart=(new Date).getTime(),i.Log(i.GetStackTrace(),"Received first chunk of file",6));const s=new TextDecoder("utf-16").decode(e.slice(1));i.Log(i.GetStackTrace(),s,6),t.mimetype=s}static setContentsFromBytes(e,t){if(!t.receiving)return;t.size=Math.ceil(new DataView(e.slice(1,5).buffer).getInt32(0,!0)/16379);const s=e.slice(5);if(t.data.push(s),i.Log(i.GetStackTrace(),`Received file chunk: ${t.data.length}/${t.size}`,6),t.data.length===t.size){t.receiving=!1,t.valid=!0,i.Log(i.GetStackTrace(),"Received complete file",6);const e=(new Date).getTime()-t.timestampStart,s=Math.round(16*t.size*1024/e);i.Log(i.GetStackTrace(),`Average transfer bitrate: ${s}kb/s over ${e/1e3} seconds`,6);const n=new Blob(t.data,{type:t.mimetype}),r=document.createElement("a");r.setAttribute("href",URL.createObjectURL(n)),r.setAttribute("download",`transfer.${t.extension}`),document.body.append(r),r.remove()}else t.data.length>t.size&&(t.receiving=!1,i.Error(i.GetStackTrace(),`Received bigger file than advertised: ${t.data.length}/${t.size}`))}}class We{constructor(){this.mimetype="",this.extension="",this.receiving=!1,this.size=0,this.data=[],this.valid=!1}}class He{}He.mainButton=0,He.auxiliaryButton=1,He.secondaryButton=2,He.fourthButton=3,He.fifthButton=4;class Ve{}Ve.primaryButton=1,Ve.secondaryButton=2,Ve.auxiliaryButton=4,Ve.fourthButton=8,Ve.fifthButton=16;class Ne{constructor(){this.unregisterCallbacks=[]}addUnregisterCallback(e){this.unregisterCallbacks.push(e)}unregisterAll(){for(const e of this.unregisterCallbacks)e();this.unregisterCallbacks=[]}}class Ke{constructor(e,t,s){this.touchEventListenerTracker=new Ne,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 Qe(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")([He.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")([He.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 Qe{constructor(e,t,s){this.id=e,this.x=t,this.y=s}}class $e{}$e.backSpace=8,$e.shift=16,$e.control=17,$e.alt=18,$e.rightShift=253,$e.rightControl=254,$e.rightAlt=255;class qe{constructor(e,t,s){this.keyboardEventListenerTracker=new Ne,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(e){const t=this.getKeycode(e);t&&(i.Log(i.GetStackTrace(),`key down ${t}, repeat = ${e.repeat}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyDown")([this.getKeycode(e),e.repeat?1:0]),this.activeKeysProvider.getActiveKeys().push(t),t===$e.backSpace&&document.dispatchEvent(new KeyboardEvent("keypress",{charCode:$e.backSpace})),this.config.isFlagEnabled(ae.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(t)&&e.preventDefault())}handleOnKeyUp(e){const t=this.getKeycode(e);t&&(i.Log(i.GetStackTrace(),`key up ${t}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyUp")([t,e.repeat?1:0]),this.config.isFlagEnabled(ae.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(t)&&e.preventDefault())}handleOnKeyPress(e){if(!("charCode"in e))return void i.Warning(i.GetStackTrace(),"KeyboardEvent.charCode is deprecated in this browser, cannot send key press.");const t=e.charCode;i.Log(i.GetStackTrace(),`key press ${t}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyPress")([t])}getKeycode(e){if(!("keyCode"in e)){const t=e;return t.code in this.CodeToKeyCode?this.CodeToKeyCode[t.code]:(i.Warning(i.GetStackTrace(),`Keyboard code of ${t.code} is not supported in our mapping, ignoring this key.`),null)}return e.keyCode===$e.shift&&"ShiftRight"===e.code?$e.rightShift:e.keyCode===$e.control&&"ControlRight"===e.code?$e.rightControl:e.keyCode===$e.alt&&"AltRight"===e.code?$e.rightAlt:e.keyCode}isKeyCodeBrowserKey(e){return e>=112&&e<=123||9===e}}class Xe{constructor(e,t,s){this.x=0,this.y=0,this.updateMouseMovePositionEvent=e=>{this.updateMouseMovePosition(e)},this.mouseEventListenerTracker=new Ne,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 e=this.videoElementProvider.getVideoParentElement(),t=this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;if(document.pointerLockElement===e||document.mozPointerLockElement===e)i.Log(i.GetStackTrace(),"Pointer locked",6),document.addEventListener("mousemove",this.updateMouseMovePositionEvent,!1),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("mousemove",this.updateMouseMovePositionEvent,!1)));else{i.Log(i.GetStackTrace(),"The pointer lock status is now unlocked",6),document.removeEventListener("mousemove",this.updateMouseMovePositionEvent,!1);let e=this.activeKeysProvider.getActiveKeys();const s=new Set(e),n=[];s.forEach((e=>{n[e]})),n.forEach((e=>{t.get("KeyUp")([e])})),e=[]}}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 je{constructor(e){this.mouseController=e}unregisterMouseEvents(){}updateMouseMovePosition(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;i.Log(i.GetStackTrace(),"MouseMove",6);const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY),s=this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(e.movementX,e.movementY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseMove")([t.x,t.y,s.x,s.y]),e.preventDefault()}handleMouseDown(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;i.Log(i.GetStackTrace(),"onMouse Down",6);const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([e.button,t.x,t.y]),e.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 Ye{constructor(e,t,s,n){this.mouseEventListenerTracker=new Ne,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 Xe(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 je(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 e=this.videoElementProvider.getVideoParentElement(),t=e=>{this.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),"Mouse Entered",6),this.sendMouseEnter(),this.pressMouseButtons(e.buttons,e.x,e.y))},s=e=>{this.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),"Mouse Left",6),this.sendMouseLeave(),this.releaseMouseButtons(e.buttons,e.x,e.y))};e.addEventListener("mouseenter",t),e.addEventListener("mouseleave",s),this.mouseEventListenerTracker.addUnregisterCallback((()=>e.removeEventListener("mouseenter",t))),this.mouseEventListenerTracker.addUnregisterCallback((()=>e.removeEventListener("mouseleave",s)))}releaseMouseButtons(e,t,s){const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&Ve.primaryButton&&this.sendMouseUp(He.mainButton,n.x,n.y),e&Ve.secondaryButton&&this.sendMouseUp(He.secondaryButton,n.x,n.y),e&Ve.auxiliaryButton&&this.sendMouseUp(He.auxiliaryButton,n.x,n.y),e&Ve.fourthButton&&this.sendMouseUp(He.fourthButton,n.x,n.y),e&Ve.fifthButton&&this.sendMouseUp(He.fifthButton,n.x,n.y)}pressMouseButtons(e,t,s){if(!this.videoElementProvider.isVideoReady())return;const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&Ve.primaryButton&&this.sendMouseDown(He.mainButton,n.x,n.y),e&Ve.secondaryButton&&this.sendMouseDown(He.secondaryButton,n.x,n.y),e&Ve.auxiliaryButton&&this.sendMouseDown(He.auxiliaryButton,n.x,n.y),e&Ve.fourthButton&&this.sendMouseDown(He.fourthButton,n.x,n.y),e&Ve.fifthButton&&this.sendMouseDown(He.fifthButton,n.x,n.y)}sendMouseEnter(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseEnter")()}sendMouseLeave(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseLeave")()}sendMouseDown(e,t,s){this.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),`mouse button ${e} down at (${t}, ${s})`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([e,t,s]))}sendMouseUp(e,t,s){if(!this.videoElementProvider.isVideoReady())return;i.Log(i.GetStackTrace(),`mouse button ${e} up at (${t}, ${s})`,6);const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([e,n.x,n.y])}}class Je{constructor(e,t,s){this.fingers=[9,8,7,6,5,4,3,2,1,0],this.fingerIds=new Map,this.maxByteValue=255,this.touchEventListenerTracker=new Ne,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s,this.videoElementParent=t.getVideoElement();const n=e=>this.onTouchStart(e),r=e=>this.onTouchEnd(e),o=e=>this.onTouchMove(e);this.videoElementParent.addEventListener("touchstart",n),this.videoElementParent.addEventListener("touchend",r),this.videoElementParent.addEventListener("touchmove",o),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchstart",n))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchend",r))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchmove",o))),i.Log(i.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(e){const t=this.fingers.pop();void 0===t&&i.Log(i.GetStackTrace(),"exhausted touch identifiers",6),this.fingerIds.set(e.identifier,t)}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(e){if(this.videoElementProvider.isVideoReady()){for(let t=0;t<e.changedTouches.length;t++)this.rememberTouch(e.changedTouches[t]);i.Log(i.GetStackTrace(),"touch start",6),this.emitTouchData("TouchStart",e.changedTouches),e.preventDefault()}}onTouchEnd(e){if(this.videoElementProvider.isVideoReady()){i.Log(i.GetStackTrace(),"touch end",6),this.emitTouchData("TouchEnd",e.changedTouches);for(let t=0;t<e.changedTouches.length;t++)this.forgetTouch(e.changedTouches[t]);e.preventDefault()}}onTouchMove(e){this.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),"touch move",6),this.emitTouchData("TouchMove",e.touches),e.preventDefault())}emitTouchData(e,t){if(!this.videoElementProvider.isVideoReady())return;const s=this.videoElementProvider.getVideoParentElement(),n=this.toStreamerMessagesProvider.toStreamerHandlers;for(let r=0;r<t.length;r++){const o=1,a=t[r],l=a.clientX-s.offsetLeft,d=a.clientY-s.offsetTop;i.Log(i.GetStackTrace(),`F${this.fingerIds.get(a.identifier)}=(${l}, ${d})`,6);const c=this.coordinateConverter.normalizeAndQuantizeUnsigned(l,d);switch(e){case"TouchStart":n.get("TouchStart")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0]);break;case"TouchEnd":n.get("TouchEnd")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0]);break;case"TouchMove":n.get("TouchMove")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0])}}}}class Ze{constructor(e){this.gamePadEventListenerTracker=new Ne,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(e){i.Log(i.GetStackTrace(),"Gamepad connect handler",6);const t=e.gamepad,s={currentState:t,prevState:t,id:void 0};this.controllers.push(s),this.controllers[t.index].currentState=t,this.controllers[t.index].prevState=t,i.Log(i.GetStackTrace(),"gamepad: "+t.id+" connected",6),window.requestAnimationFrame((()=>this.updateStatus())),this.onGamepadConnected()}gamePadDisconnectHandler(e){i.Log(i.GetStackTrace(),"Gamepad disconnect handler",6),i.Log(i.GetStackTrace(),"gamepad: "+e.gamepad.id+" disconnected",6);const t=this.controllers[e.gamepad.index];delete this.controllers[e.gamepad.index],this.controllers=this.controllers.filter((e=>void 0!==e)),this.onGamepadDisconnected(t.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==Ae.LeftTrigger?e.get("GamepadAnalog")([s,5,r.value]):n==Ae.RightTrigger?e.get("GamepadAnalog")([s,6,r.value]):e.get("GamepadButtonPressed")([s,n,i.pressed?1:0]):!r.pressed&&i.pressed&&(n==Ae.LeftTrigger?e.get("GamepadAnalog")([s,5,0]):n==Ae.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"}(Ae||(Ae={}));class et{constructor(e,t,s){this.activeKeys=new tt,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s}registerKeyBoard(e){i.Log(i.GetStackTrace(),"Register Keyboard Events",7);const t=new qe(this.toStreamerMessagesProvider,e,this.activeKeys);return t.registerKeyBoardEvents(),t}registerMouse(e){i.Log(i.GetStackTrace(),"Register Mouse Events",7);const t=new Ye(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter,this.activeKeys);switch(e){case pe.LockedMouse:t.registerLockedMouseEvents(t);break;case pe.HoveringMouse:t.registerHoveringMouseEvents(t);break;default:i.Info(i.GetStackTrace(),"unknown Control Scheme Type Defaulting to Locked Mouse Events"),t.registerLockedMouseEvents(t)}return t}registerTouch(e,t){if(i.Log(i.GetStackTrace(),"Registering Touch",6),e){const e=new Ke(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter);return e.setVideoElementParentClientRect(t),e}return new Je(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter)}registerGamePad(){return i.Log(i.GetStackTrace(),"Register Game Pad",7),new Ze(this.toStreamerMessagesProvider)}}class tt{constructor(){this.activeKeys=[],this.activeKeys=[]}getActiveKeys(){return this.activeKeys}}class st{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(ae.StartVideoMuted),this.videoElement.autoplay=this.config.isFlagEnabled(ae.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(ae.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 i.Log(i.GetStackTrace(),"Resizing too often - skipping",6),clearTimeout(this.resizeTimeoutHandle),this.resizeTimeoutHandle=window.setTimeout((()=>this.updateVideoStreamSize()),100)}}class nt{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 rt{constructor(){this.toStreamerHandlers=new Map,this.fromStreamerHandlers=new Map,this.toStreamerMessages=new nt,this.fromStreamerMessages=new nt}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(e,t,s){switch(e){case Fe.ToStreamer:this.toStreamerHandlers.set(t,s);break;case Fe.FromStreamer:this.fromStreamerHandlers.set(t,s);break;default:i.Log(i.GetStackTrace(),`Unknown message direction ${e}`)}}}!function(e){e[e.ToStreamer=0]="ToStreamer",e[e.FromStreamer=1]="FromStreamer"}(Fe||(Fe={}));class it{constructor(){this.responseEventListeners=new Map}addResponseEventListener(e,t){this.responseEventListeners.set(e,t)}removeResponseEventListener(e){this.responseEventListeners.delete(e)}onResponse(e){i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.Response",6);const t=new TextDecoder("utf-16").decode(e.slice(1));i.Log(i.GetStackTrace(),t,6),this.responseEventListeners.forEach((e=>{e(t)}))}}class ot{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(e,t){const s=JSON.stringify(t),n=this.toStreamerMessagesMapProvider.toStreamerMessages.getFromKey(e);void 0===n&&i.Error(i.GetStackTrace(),`Attempted to emit descriptor with message type: ${e}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`),i.Log(i.GetStackTrace(),"Sending: "+t,6);const r=new DataView(new ArrayBuffer(3+2*s.length));let o=0;r.setUint8(o,n.id),o++,r.setUint16(o,s.length,!0),o+=2;for(let e=0;e<s.length;e++)r.setUint16(o,s.charCodeAt(e),!0),o+=2;this.dataChannelSender.canSend()?this.dataChannelSender.sendData(r.buffer):i.Info(i.GetStackTrace(),`Data channel cannot send yet, skipping sending descriptor message: ${e} - ${s}`)}}class at{constructor(e,t){this.dataChannelSender=e,this.toStreamerMessagesMapProvider=t}sendMessageToStreamer(e,t){void 0===t&&(t=[]);const s=this.toStreamerMessagesMapProvider.toStreamerMessages.getFromKey(e);if(void 0===s)return void i.Error(i.GetStackTrace(),`Attempted to send a message to the streamer with message type: ${e}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`);const n=new DataView(new ArrayBuffer(s.byteLength+1));n.setUint8(0,s.id);let r=1;t.forEach(((e,t)=>{switch(s.structure[t]){case"uint8":n.setUint8(r,e),r+=1;break;case"uint16":n.setUint16(r,e,!0),r+=2;break;case"int16":n.setInt16(r,e,!0),r+=2;break;case"float":n.setFloat32(r,e,!0),r+=4;break;case"double":n.setFloat64(r,e,!0),r+=8}})),this.dataChannelSender.canSend()?this.dataChannelSender.sendData(n.buffer):i.Info(i.GetStackTrace(),`Data channel cannot send yet, skipping sending message: ${e} - ${new Uint8Array(n.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(e){const t=this.dataChannelProvider.getDataChannelInstance();"open"==t.dataChannel.readyState?(t.dataChannel.send(e),i.Log(i.GetStackTrace(),`Message Sent: ${new Uint8Array(e)}`,6),this.resetAfkWarningTimerOnDataSend()):i.Error(i.GetStackTrace(),`Message Failed: ${new Uint8Array(e)}`)}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 e=this.videoElementParent.clientHeight/this.videoElementParent.clientWidth,t=this.videoElement.videoHeight/this.videoElement.videoWidth;e>t?(i.Log(i.GetStackTrace(),"Setup Normalize and Quantize for playerAspectRatio > videoAspectRatio",6),this.ratio=e/t,this.normalizeAndQuantizeUnsignedFunc=(e,t)=>this.normalizeAndQuantizeUnsignedPlayerBigger(e,t),this.normalizeAndQuantizeSignedFunc=(e,t)=>this.normalizeAndQuantizeSignedPlayerBigger(e,t),this.denormalizeAndUnquantizeUnsignedFunc=(e,t)=>this.denormalizeAndUnquantizeUnsignedPlayerBigger(e,t)):(i.Log(i.GetStackTrace(),"Setup Normalize and Quantize for playerAspectRatio <= videoAspectRatio",6),this.ratio=t/e,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.config=e,this.pixelStreaming=t,this.responseController=new it,this.file=new We,this.sdpConstraints={offerToReceiveAudio:!0,offerToReceiveVideo:!0},this.afkController=new ve(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 y(this.pixelStreaming.videoElementParent),this.videoPlayer=new st(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 T(this.videoPlayer),this.coordinateConverter=new ct(this.videoPlayer),this.sendrecvDataChannelController=new Ce,this.recvDataChannelController=new Ce,this.registerDataChannelEventEmitters(this.sendrecvDataChannelController),this.registerDataChannelEventEmitters(this.recvDataChannelController),this.dataChannelSender=new dt(this.sendrecvDataChannelController),this.dataChannelSender.resetAfkWarningTimerOnDataSend=()=>this.afkController.resetAfkWarningTimer(),this.streamMessageController=new rt,this.webSocketController=new f,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(ae.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 ot(this.dataChannelSender,this.streamMessageController),this.sendMessageController=new at(this.dataChannelSender,this.streamMessageController),this.toStreamerMessagesController=new lt(this.sendMessageController),this.registerMessageHandlers(),this.streamMessageController.populateDefaultProtocol(),this.inputClassesFactory=new et(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(ue.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(he.SignallingServerUrl);return this.config.isFlagEnabled(ae.BrowserSendOffer)&&(e+="?"+ae.BrowserSendOffer+"=true"),e}}requestUnquantizedAndDenormalizeUnsigned(e,t){return this.coordinateConverter.unquantizeAndDenormalizeUnsigned(e,t)}handleOnMessage(e){const t=new Uint8Array(e.data);i.Log(i.GetStackTrace(),"Message incoming:"+t,6);const s=this.streamMessageController.fromStreamerMessages.getFromValue(t[0]);this.streamMessageController.fromStreamerHandlers.get(s)(e.data)}registerMessageHandlers(){this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"QualityControlOwnership",(e=>this.onQualityControlOwnership(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"Response",(e=>this.responseController.onResponse(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"Command",(e=>{this.onCommand(e)})),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"FreezeFrame",(e=>this.onFreezeFrameMessage(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"UnfreezeFrame",(()=>this.invalidateFreezeFrameAndEnableVideo())),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"VideoEncoderAvgQP",(e=>this.handleVideoEncoderAvgQP(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"LatencyTest",(e=>this.handleLatencyTestResult(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"InitialSettings",(e=>this.handleInitialSettings(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"FileExtension",(e=>this.onFileExtension(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"FileMimeType",(e=>this.onFileMimeType(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"FileContents",(e=>this.onFileContents(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"TestEcho",(()=>{})),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"InputControlOwnership",(e=>this.onInputControlOwnership(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"GamepadResponse",(e=>this.onGamepadResponse(e))),this.streamMessageController.registerMessageHandler(Fe.FromStreamer,"Protocol",(e=>this.onProtocolMessage(e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"IFrameRequest",(()=>this.sendMessageController.sendMessageToStreamer("IFrameRequest"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"RequestQualityControl",(()=>this.sendMessageController.sendMessageToStreamer("RequestQualityControl"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"FpsRequest",(()=>this.sendMessageController.sendMessageToStreamer("FpsRequest"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"AverageBitrateRequest",(()=>this.sendMessageController.sendMessageToStreamer("AverageBitrateRequest"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"StartStreaming",(()=>this.sendMessageController.sendMessageToStreamer("StartStreaming"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"StopStreaming",(()=>this.sendMessageController.sendMessageToStreamer("StopStreaming"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"LatencyTest",(()=>this.sendMessageController.sendMessageToStreamer("LatencyTest"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"RequestInitialSettings",(()=>this.sendMessageController.sendMessageToStreamer("RequestInitialSettings"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"TestEcho",(()=>{})),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"UIInteraction",(e=>this.sendDescriptorController.emitUIInteraction(e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"Command",(e=>this.sendDescriptorController.emitCommand(e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"KeyDown",(e=>this.sendMessageController.sendMessageToStreamer("KeyDown",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"KeyUp",(e=>this.sendMessageController.sendMessageToStreamer("KeyUp",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"KeyPress",(e=>this.sendMessageController.sendMessageToStreamer("KeyPress",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"MouseEnter",(e=>this.sendMessageController.sendMessageToStreamer("MouseEnter",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"MouseLeave",(e=>this.sendMessageController.sendMessageToStreamer("MouseLeave",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"MouseDown",(e=>this.sendMessageController.sendMessageToStreamer("MouseDown",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"MouseUp",(e=>this.sendMessageController.sendMessageToStreamer("MouseUp",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"MouseMove",(e=>this.sendMessageController.sendMessageToStreamer("MouseMove",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"MouseWheel",(e=>this.sendMessageController.sendMessageToStreamer("MouseWheel",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"MouseDouble",(e=>this.sendMessageController.sendMessageToStreamer("MouseDouble",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"TouchStart",(e=>this.sendMessageController.sendMessageToStreamer("TouchStart",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"TouchEnd",(e=>this.sendMessageController.sendMessageToStreamer("TouchEnd",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"TouchMove",(e=>this.sendMessageController.sendMessageToStreamer("TouchMove",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"GamepadConnected",(()=>this.sendMessageController.sendMessageToStreamer("GamepadConnected"))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"GamepadButtonPressed",(e=>this.sendMessageController.sendMessageToStreamer("GamepadButtonPressed",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"GamepadButtonReleased",(e=>this.sendMessageController.sendMessageToStreamer("GamepadButtonReleased",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"GamepadAnalog",(e=>this.sendMessageController.sendMessageToStreamer("GamepadAnalog",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"GamepadDisconnected",(e=>this.sendMessageController.sendMessageToStreamer("GamepadDisconnected",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"XRHMDTransform",(e=>this.sendMessageController.sendMessageToStreamer("XRHMDTransform",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"XRControllerTransform",(e=>this.sendMessageController.sendMessageToStreamer("XRControllerTransform",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"XRSystem",(e=>this.sendMessageController.sendMessageToStreamer("XRSystem",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"XRButtonTouched",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonTouched",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"XRButtonPressed",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonPressed",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"XRButtonReleased",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonReleased",e))),this.streamMessageController.registerMessageHandler(Fe.ToStreamer,"XRAnalog",(e=>this.sendMessageController.sendMessageToStreamer("XRAnalog",e)))}onCommand(e){i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.Command",6);const t=new TextDecoder("utf-16").decode(e.slice(1));i.Log(i.GetStackTrace(),"Data Channel Command: "+t,6);const s=JSON.parse(t);"onScreenKeyboard"===s.command&&this.pixelStreaming._activateOnScreenKeyboard(s)}onProtocolMessage(e){try{const t=new TextDecoder("utf-16").decode(e.slice(1)),s=JSON.parse(t);Object.prototype.hasOwnProperty.call(s,"Direction")||i.Error(i.GetStackTrace(),"Malformed protocol received. Ensure the protocol message contains a direction");const n=s.Direction;delete s.Direction,i.Log(i.GetStackTrace(),`Received new ${n==Fe.FromStreamer?"FromStreamer":"ToStreamer"} protocol. Updating existing protocol...`),Object.keys(s).forEach((e=>{const t=s[e];switch(n){case Fe.ToStreamer:if(!Object.prototype.hasOwnProperty.call(t,"id")||!Object.prototype.hasOwnProperty.call(t,"byteLength"))return void i.Error(i.GetStackTrace(),`ToStreamer->${e} protocol definition was malformed as it didn't contain at least an id and a byteLength\n\n Definition was: ${JSON.stringify(t,null,2)}`);if(t.byteLength>0&&!Object.prototype.hasOwnProperty.call(t,"structure"))return void i.Error(i.GetStackTrace(),`ToStreamer->${e} protocol definition was malformed as it specified a byteLength but no accompanying structure`);this.streamMessageController.toStreamerHandlers.get(e)?this.streamMessageController.toStreamerMessages.add(e,t):i.Error(i.GetStackTrace(),`There was no registered handler for "${e}" - try adding one using registerMessageHandler(MessageDirection.ToStreamer, "${e}", myHandler)`);break;case Fe.FromStreamer:if(!Object.prototype.hasOwnProperty.call(t,"id"))return void i.Error(i.GetStackTrace(),`FromStreamer->${e} protocol definition was malformed as it didn't contain at least an id\n\n Definition was: ${JSON.stringify(t,null,2)}`);this.streamMessageController.fromStreamerHandlers.get(e)?this.streamMessageController.fromStreamerMessages.add(e,t.id):i.Error(i.GetStackTrace(),`There was no registered handler for "${t}" - try adding one using registerMessageHandler(MessageDirection.FromStreamer, "${e}", myHandler)`);break;default:i.Error(i.GetStackTrace(),`Unknown direction: ${n}`)}})),this.toStreamerMessagesController.SendRequestInitialSettings(),this.toStreamerMessagesController.SendRequestQualityControl()}catch(e){i.Log(i.GetStackTrace(),e)}}onInputControlOwnership(e){const t=new Uint8Array(e);i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.InputControlOwnership",6);const s=new Boolean(t[1]).valueOf();i.Log(i.GetStackTrace(),`Received input controller message - will your input control the stream: ${s}`),this.pixelStreaming._onInputControlOwnership(s)}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 i.Log(i.GetStackTrace(),"A websocket connection has not been made yet so we will start the stream"),this.pixelStreaming._onWebRtcAutoConnect(),this.connectToSignallingServer();else i.Log(i.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?(i.Log(i.GetStackTrace(),"showing play overlay"),this.resizePlayerStyle()):(i.Log(i.GetStackTrace(),"showing freeze frame"),this.freezeFrameController.showFreezeFrame()),setTimeout((()=>{this.videoPlayer.setVideoEnabled(!1)}),this.freezeFrameController.freezeFrameDelay)}onFreezeFrameMessage(e){i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.FreezeFrame",6);const t=new Uint8Array(e);this.freezeFrameController.processFreezeFrameMessage(t,(()=>this.loadFreezeFrameOrShowPlayOverlay()))}invalidateFreezeFrameAndEnableVideo(){i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.FreezeFrame",6),setTimeout((()=>{this.pixelStreaming.dispatchEvent(new Y),this.freezeFrameController.hideFreezeFrame()}),this.freezeFrameController.freezeFrameDelay),this.videoPlayer.getVideoElement()&&this.videoPlayer.setVideoEnabled(!0)}onFileExtension(e){const t=new Uint8Array(e);_e.setExtensionFromBytes(t,this.file)}onFileMimeType(e){const t=new Uint8Array(e);_e.setMimeTypeFromBytes(t,this.file)}onFileContents(e){const t=new Uint8Array(e);_e.setContentsFromBytes(t,this.file)}playStream(){if(!this.videoPlayer.getVideoElement()){const e="Could not play video stream because the video player was not initialized correctly.";return this.pixelStreaming.dispatchEvent(new $({message:e})),i.Error(i.GetStackTrace(),e),this.setDisconnectMessageOverride("Stream not initialized correctly"),void this.closeSignalingServer()}this.videoPlayer.hasVideoSource()?(this.setTouchInputEnabled(this.config.isFlagEnabled(ae.TouchInput)),this.pixelStreaming.dispatchEvent(new q),this.streamController.audioElement.srcObject?(this.streamController.audioElement.muted=this.config.isFlagEnabled(ae.StartVideoMuted),this.streamController.audioElement.play().then((()=>{this.playVideo()})).catch((e=>{i.Log(i.GetStackTrace(),e),i.Log(i.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:e}))}))):this.playVideo(),this.shouldShowPlayOverlay=!1,this.freezeFrameController.showFreezeFrame()):i.Warning(i.GetStackTrace(),"Cannot play stream, the video element has no srcObject to play.")}playVideo(){this.videoPlayer.play().catch((e=>{this.streamController.audioElement.srcObject&&this.streamController.audioElement.pause(),i.Log(i.GetStackTrace(),e),i.Log(i.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:e}))}))}autoPlayVideoOrSetUpPlayOverlay(){this.config.isFlagEnabled(ae.AutoPlayVideo)&&this.playStream(),this.resizePlayerStyle()}connectToSignallingServer(){const e=this.signallingUrlBuilder();this.webSocketController.connect(e)}startSession(e){if(this.peerConfig=e,this.config.isFlagEnabled(ae.ForceTURN)&&!this.checkTurnServerAvailability(e))return i.Info(i.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 Oe(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 t=!1;this.peerConnectionController.onIceConnectionStateChange=()=>{!t&&["connected","completed"].includes(this.peerConnectionController.peerConnection.iceConnectionState)&&(this.pixelStreaming._onWebRtcConnected(),t=!0)},this.peerConnectionController.onTrack=e=>this.streamController.handleOnTrack(e),this.config.isFlagEnabled(ae.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(e){if(!e.iceServers)return i.Info(i.GetStackTrace(),"A turn sever was not found"),!1;for(const t of e.iceServers)for(const e of t.urls)if(e.includes("turn"))return i.Log(i.GetStackTrace(),`A turn sever was found at ${e}`),!0;return i.Info(i.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(e){if(i.Log(i.GetStackTrace(),`Got streamer list ${e.ids}`,6),this.isReconnecting)e.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(ue.StreamerId,""),this.config.setOptionSettingOptions(ue.StreamerId,[]));else{const t=[...e.ids];t.unshift(""),this.config.setOptionSettingOptions(ue.StreamerId,t);const s=new URLSearchParams(window.location.search);let n=null;1==e.ids.length?n=e.ids[0]:this.config.isFlagEnabled(ae.PreferSFU)&&e.ids.includes("SFU")?n="SFU":s.has(ue.StreamerId)&&e.ids.includes(s.get(ue.StreamerId))&&(n=s.get(ue.StreamerId)),null!==n&&this.config.setOptionSettingValue(ue.StreamerId,n),this.pixelStreaming.dispatchEvent(new Z({messageStreamerList:e,autoSelectedStreamerId:n}))}}handleWebRtcAnswer(e){i.Log(i.GetStackTrace(),`Got answer sdp ${e.sdp}`,6);const t={sdp:e.sdp,type:"answer"};this.peerConnectionController.receiveAnswer(t),this.handlePostWebrtcNegotiation()}handleWebRtcOffer(e){i.Log(i.GetStackTrace(),`Got offer sdp ${e.sdp}`,6),this.isUsingSFU=!!e.sfu&&e.sfu,this.isUsingSFU&&(this.peerConnectionController.preferredCodec="");const t={sdp:e.sdp,type:"offer"};this.peerConnectionController.receiveOffer(t,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(ae.MouseInput)),this.setKeyboardInputEnabled(this.config.isFlagEnabled(ae.KeyboardInput)),this.setGamePadInputEnabled(this.config.isFlagEnabled(ae.GamepadInput))}handleIceCandidate(e){i.Log(i.GetStackTrace(),"Web RTC Controller: onWebRtcIce",6);const t=new RTCIceCandidate(e);this.peerConnectionController.handleOnIce(t)}handleSendIceCandidate(e){i.Log(i.GetStackTrace(),"OnIceCandidate",6),e.candidate&&e.candidate.candidate&&this.webSocketController.sendIceCandidate(e.candidate)}handleDataChannel(e){i.Log(i.GetStackTrace(),"Data channel created for us by browser as we are a receiving peer.",6),this.sendrecvDataChannelController.dataChannel=e.channel,this.sendrecvDataChannelController.setupDataChannel(),this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}handleSendWebRTCOffer(e){i.Log(i.GetStackTrace(),"Sending the offer to the Server",6),this.webSocketController.sendWebRtcOffer(e)}handleSendWebRTCAnswer(e){i.Log(i.GetStackTrace(),"Sending the answer to the Server",6),this.webSocketController.sendWebRtcAnswer(e),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(e){i.Log(i.GetStackTrace(),`MinQP=${e}\n`,6),null!=e&&this.sendDescriptorController.emitCommand({"Encoder.MinQP":e})}sendEncoderMaxQP(e){i.Log(i.GetStackTrace(),`MaxQP=${e}\n`,6),null!=e&&this.sendDescriptorController.emitCommand({"Encoder.MaxQP":e})}sendWebRTCMinBitrate(e){i.Log(i.GetStackTrace(),`WebRTC Min Bitrate=${e}`,6),null!=e&&this.sendDescriptorController.emitCommand({"WebRTC.MinBitrate":e})}sendWebRTCMaxBitrate(e){i.Log(i.GetStackTrace(),`WebRTC Max Bitrate=${e}`,6),null!=e&&this.sendDescriptorController.emitCommand({"WebRTC.MaxBitrate":e})}sendWebRTCFps(e){i.Log(i.GetStackTrace(),`WebRTC FPS=${e}`,6),null!=e&&(this.sendDescriptorController.emitCommand({"WebRTC.Fps":e}),this.sendDescriptorController.emitCommand({"WebRTC.MaxFps":e}))}sendShowFps(){i.Log(i.GetStackTrace(),"---- Sending show stat to UE ----",6),this.sendDescriptorController.emitCommand({"stat.fps":""})}sendIframeRequest(){i.Log(i.GetStackTrace(),"---- Sending Request for an IFrame ----",6),this.streamMessageController.toStreamerHandlers.get("IFrameRequest")()}emitUIInteraction(e){i.Log(i.GetStackTrace(),"---- Sending custom UIInteraction message ----",6),this.sendDescriptorController.emitUIInteraction(e)}emitCommand(e){i.Log(i.GetStackTrace(),"---- Sending custom Command message ----",6),this.sendDescriptorController.emitCommand(e)}emitConsoleCommand(e){i.Log(i.GetStackTrace(),"---- Sending custom Command:ConsoleCommand message ----",6),this.sendDescriptorController.emitCommand({ConsoleCommand:e})}sendRequestQualityControlOwnership(){i.Log(i.GetStackTrace(),"---- Sending Request to Control Quality ----",6),this.toStreamerMessagesController.SendRequestQualityControl()}handleLatencyTestResult(e){i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.latencyTest",6);const t=new TextDecoder("utf-16").decode(e.slice(1)),s=new Be;Object.assign(s,JSON.parse(t)),s.processFields(),s.testStartTimeMs=this.latencyStartTime,s.browserReceiptTimeMs=Date.now(),s.latencyExcludingDecode=~~(s.browserReceiptTimeMs-s.testStartTimeMs),s.testDuration=~~(s.TransmissionTimeMs-s.ReceiptTimeMs),s.networkLatency=~~(s.latencyExcludingDecode-s.testDuration),s.frameDisplayDeltaTimeMs&&s.browserReceiptTimeMs&&(s.endToEndLatency=(s.frameDisplayDeltaTimeMs,s.networkLatency,~~+s.CaptureToSendMs)),this.pixelStreaming._onLatencyTestResult(s)}handleInitialSettings(e){i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.InitialSettings",6);const t=new TextDecoder("utf-16").decode(e.slice(1)),s=JSON.parse(t),n=new Ue;s.Encoder&&(n.EncoderSettings=s.Encoder),s.WebRTC&&(n.WebRTCSettings=s.WebRTC),s.PixelStreaming&&(n.PixelStreamingSettings=s.PixelStreaming),s.ConfigOptions&&void 0!==s.ConfigOptions.DefaultToHover&&this.config.setFlagEnabled(ae.HoveringMouseMode,!!s.ConfigOptions.DefaultToHover),n.ueCompatible(),i.Log(i.GetStackTrace(),t,6),this.pixelStreaming._onInitialSettings(n)}handleVideoEncoderAvgQP(e){i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.VideoEncoderAvgQP",6);const t=Number(new TextDecoder("utf-16").decode(e.slice(1)));this.setVideoEncoderAvgQP(t)}handleVideoInitialized(){this.pixelStreaming._onVideoInitialized(),this.autoPlayVideoOrSetUpPlayOverlay(),this.resizePlayerStyle(),this.videoPlayer.updateVideoStreamSize()}onQualityControlOwnership(e){const t=new Uint8Array(e);i.Log(i.GetStackTrace(),"DataChannelReceiveMessageType.QualityControlOwnership",6),this.isQualityController=new Boolean(t[1]).valueOf(),i.Log(i.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(ae.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(ae.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 W({label:e,event:t}))}}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(){i.Log(i.GetStackTrace(),"XR Session ended"),this.xrSession=null,this.onSessionEnded.dispatchEvent(new Event("xrSessionEnded"))}onXrSessionStarted(e){i.Log(i.GetStackTrace(),"XR Session started"),this.xrSession=e,this.xrSession.addEventListener("end",(()=>{this.onXrSessionEnded()}));const t=document.createElement("canvas");this.gl=t.getContext("webgl2",{xrCompatible:!0}),this.xrSession.updateRenderState({baseLayer:new XRWebGLLayer(this.xrSession,this.gl)});const s=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(s,St.vertexShader()),this.gl.compileShader(s);const n=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(n,St.fragmentShader()),this.gl.compileShader(n);const r=this.gl.createProgram();this.gl.attachShader(r,s),this.gl.attachShader(r,n),this.gl.linkProgram(r),this.gl.useProgram(r),this.positionLocation=this.gl.getAttribLocation(r,"a_position"),this.texcoordLocation=this.gl.getAttribLocation(r,"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(r,"u_resolution"),this.offsetLocation=this.gl.getUniformLocation(r,"u_offset"),e.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(ae.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 ie({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,t){this._showActionOrErrorOnDisconnect=!0,this.allowConsoleCommands=!1,this.config=e,(null==t?void 0:t.videoElementParent)&&(this._videoElementParent=t.videoElementParent),this._eventEmitter=new oe,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(ae.IsQualityController,(e=>{!0!==e||this._webRtcController.isQualityController||this._webRtcController.sendRequestQualityControlOwnership()})),this.config._addOnSettingChangedListener(ae.AFKDetection,(e=>{this._webRtcController.setAfkEnabled(e)})),this.config._addOnSettingChangedListener(ae.MatchViewportResolution,(()=>{this._webRtcController.videoPlayer.updateVideoStreamSize()})),this.config._addOnSettingChangedListener(ae.HoveringMouseMode,(e=>{this.config.setFlagLabel(ae.HoveringMouseMode,`Control Scheme: ${e?"Hovering":"Locked"} Mouse`),this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(ae.MouseInput))})),this.config._addOnSettingChangedListener(ae.KeyboardInput,(e=>{this._webRtcController.setKeyboardInputEnabled(e)})),this.config._addOnSettingChangedListener(ae.MouseInput,(e=>{this._webRtcController.setMouseInputEnabled(e)})),this.config._addOnSettingChangedListener(ae.TouchInput,(e=>{this._webRtcController.setTouchInputEnabled(e)})),this.config._addOnSettingChangedListener(ae.GamepadInput,(e=>{this._webRtcController.setGamePadInputEnabled(e)})),this.config._addOnNumericSettingChangedListener(de.MinQP,(e=>{i.Log(i.GetStackTrace(),"-------- Sending MinQP --------",7),this._webRtcController.sendEncoderMinQP(e),i.Log(i.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.MaxQP,(e=>{i.Log(i.GetStackTrace(),"-------- Sending encoder settings --------",7),this._webRtcController.sendEncoderMaxQP(e),i.Log(i.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCMinBitrate,(e=>{i.Log(i.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCMinBitrate(1e3*e),i.Log(i.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCMaxBitrate,(e=>{i.Log(i.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCMaxBitrate(1e3*e),i.Log(i.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCFPS,(e=>{i.Log(i.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCFps(e),i.Log(i.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnOptionSettingChangedListener(ue.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(ue.PreferredCodec).selected),this._webRtcController.resizePlayerStyle(),this.checkForAutoConnect()}connect(){this._eventEmitter.dispatchEvent(new N),this._webRtcController.connectToSignallingServer()}reconnect(){this._eventEmitter.dispatchEvent(new Q),this._webRtcController.restartStreamAutomatically()}disconnect(){this._eventEmitter.dispatchEvent(new K),this._webRtcController.close()}play(){this._onStreamLoading(),this._webRtcController.playStream()}checkForAutoConnect(){this.config.isFlagEnabled(ae.AutoConnect)&&(this._onWebRtcAutoConnect(),this._webRtcController.connectToSignallingServer())}_onWebRtcAutoConnect(){this._eventEmitter.dispatchEvent(new O),this._showActionOrErrorOnDisconnect=!0}_onWebRtcSdp(){this._eventEmitter.dispatchEvent(new D)}_onStreamLoading(){this._eventEmitter.dispatchEvent(new V)}_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 z({eventString:e,showActionOrErrorOnDisconnect:this._showActionOrErrorOnDisconnect})),0==this._showActionOrErrorOnDisconnect&&(this._showActionOrErrorOnDisconnect=!0)}_onWebRtcConnecting(){this._eventEmitter.dispatchEvent(new U)}_onWebRtcConnected(){this._eventEmitter.dispatchEvent(new I)}_onWebRtcFailed(){this._eventEmitter.dispatchEvent(new G)}_onVideoInitialized(){this._eventEmitter.dispatchEvent(new H),this._videoStartTime=Date.now()}_onLatencyTestResult(e){this._eventEmitter.dispatchEvent(new ee({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 F({avgQP:e}))}_onInitialSettings(e){var t;this._eventEmitter.dispatchEvent(new te({settings:e})),e.PixelStreamingSettings&&(this.allowConsoleCommands=null!==(t=e.PixelStreamingSettings.AllowPixelStreamingCommands)&&void 0!==t&&t,!1===this.allowConsoleCommands&&i.Info(i.GetStackTrace(),"-AllowPixelStreamingCommands=false, sending arbitrary console commands from browser to UE is disabled."));const s=this.config.useUrlParams,n=new URLSearchParams(window.location.search);e.EncoderSettings&&(this.config.setNumericSetting(de.MinQP,s&&n.has(de.MinQP)?Number.parseInt(n.get(de.MinQP)):e.EncoderSettings.MinQP),this.config.setNumericSetting(de.MaxQP,s&&n.has(de.MaxQP)?Number.parseInt(n.get(de.MaxQP)):e.EncoderSettings.MaxQP)),e.WebRTCSettings&&(this.config.setNumericSetting(de.WebRTCMinBitrate,s&&n.has(de.WebRTCMinBitrate)?Number.parseInt(n.get(de.WebRTCMinBitrate))/1e3:e.WebRTCSettings.MinBitrate/1e3),this.config.setNumericSetting(de.WebRTCMaxBitrate,s&&n.has(de.WebRTCMaxBitrate)?Number.parseInt(n.get(de.WebRTCMaxBitrate))/1e3:e.WebRTCSettings.MaxBitrate/1e3),this.config.setNumericSetting(de.WebRTCFPS,s&&n.has(de.WebRTCFPS)?Number.parseInt(n.get(de.WebRTCFPS)):e.WebRTCSettings.FPS))}_onQualityControlOwnership(e){this.config.setFlagEnabled(ae.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}}var Et=r.Dz,yt=r.g$,bt=r.Lt,Mt=r.Q9,wt=r.qf,Pt=r.hV,Rt=r.z$,kt=r.J0,Lt=r.De,xt=r.$C,At=r.al,Ft=r._W,Dt=r.tz,Ot=r.Nu,Ut=r.zg,It=r.vp,Gt=r.vU,zt=r.wF,Bt=r.rv,_t=r.Nh,Wt=r.ss,Ht=r.qW,Vt=r.QL,Nt=r.cf,Kt=r.eM,Qt=r.Yd,$t=r.iM,qt=r.qy,Xt=r.ce,jt=r.sK,Yt=r.Ok,Jt=r.q5,Zt=r.g,es=r.xl,ts=r.I,ss=r.bx,ns=r.Ib,rs=r.Az,is=r.Iw,os=r.qY,as=r.db,ls=r.mR,ds=r.Tn,cs=r.rV,hs=r.gh,gs=r.Mi,us=r.j,ms=r.YB,Ss=r.i5,ps=r.x_,vs=r.Am,Cs=r.eR,fs=r.r8,Ts=r.u3,Es=r.vd,ys=r.iV,bs=r.jZ,Ms=r.SW,ws=r.ZH,Ps=r.Ni,Rs=r.lh,ks=r.bq,Ls=r.$f,xs=r.eu,As=r.Ax,Fs=r.Mc;export{Et as AfkLogic,yt as AfkTimedOutEvent,bt as AfkWarningActivateEvent,Mt as AfkWarningDeactivateEvent,wt as AfkWarningUpdateEvent,Pt as AggregatedStats,Rt as CandidatePairStats,kt as CandidateStat,Lt as Config,xt as ControlSchemeType,At as DataChannelCloseEvent,Ft as DataChannelErrorEvent,Dt as DataChannelOpenEvent,Ot as DataChannelStats,Ut as EncoderSettings,It as EventEmitter,Gt as Flags,zt as HideFreezeFrameEvent,Bt as InboundAudioStats,_t as InboundVideoStats,Wt as InitialSettings,Ht as InitialSettingsEvent,Vt as LatencyTestResultEvent,Nt as LatencyTestResults,Kt as LoadFreezeFrameEvent,Qt as Logger,$t as MessageRecv,qt as MessageSend,Xt as MessageStreamerList,jt as NumericParameters,Yt as OptionParameters,Jt as OutBoundVideoStats,Zt as PixelStreaming,es as PlayStreamErrorEvent,ts as PlayStreamEvent,ss as PlayStreamRejectedEvent,ns as SettingBase,rs as SettingFlag,is as SettingNumber,os as SettingOption,as as SettingText,ls as SettingsChangedEvent,ds as SignallingProtocol,cs as StatsReceivedEvent,hs as StreamLoadingEvent,gs as StreamPreConnectEvent,us as StreamPreDisconnectEvent,ms as StreamReconnectEvent,Ss as StreamerListMessageEvent,ps as TextParameters,vs as UnquantizedAndDenormalizeUnsigned,Cs as VideoEncoderAvgQPEvent,fs as VideoInitializedEvent,Ts as WebRTCSettings,Es as WebRtcAutoConnectEvent,ys as WebRtcConnectedEvent,bs as WebRtcConnectingEvent,Ms as WebRtcDisconnectedEvent,ws as WebRtcFailedEvent,Ps as WebRtcPlayerController,Rs as WebRtcSdpEvent,ks as WebSocketController,Ls as WebXRController,xs as XrFrameEvent,As as XrSessionEndedEvent,Fs as XrSessionStartedEvent};