@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
@@ -0,0 +1,267 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { Logger } from '../Logger/Logger';
4
+ import * as MessageReceive from './MessageReceive';
5
+ import * as MessageSend from './MessageSend';
6
+ import { SignallingProtocol } from './SignallingProtocol';
7
+
8
+ // declare the new method for the websocket interface
9
+ declare global {
10
+ interface WebSocket {
11
+ onmessagebinary?(event?: MessageEvent): void;
12
+ }
13
+ }
14
+
15
+ /**
16
+ * The controller for the WebSocket and all associated methods
17
+ */
18
+
19
+ export class WebSocketController {
20
+ WS_OPEN_STATE = 1;
21
+ webSocket: WebSocket;
22
+ onOpen: EventTarget;
23
+ onClose: EventTarget;
24
+ signallingProtocol: SignallingProtocol;
25
+
26
+ constructor() {
27
+ this.onOpen = new EventTarget();
28
+ this.onClose = new EventTarget();
29
+ this.signallingProtocol = new SignallingProtocol();
30
+ SignallingProtocol.setupDefaultHandlers(this);
31
+ }
32
+
33
+ /**
34
+ * 连接发信服务器
35
+ * @param connectionURL——发信服务器的地址
36
+ * @returns—是否存在连接
37
+ */
38
+ connect(connectionURL: string): boolean {
39
+ Logger.Log(Logger.GetStackTrace(), connectionURL, 6);
40
+ try {
41
+ this.webSocket = new WebSocket(connectionURL);
42
+ this.webSocket.onopen = (event) => this.handleOnOpen(event);
43
+ this.webSocket.onerror = () => this.handleOnError();
44
+ this.webSocket.onclose = (event) => this.handleOnClose(event);
45
+ this.webSocket.onmessage = (event) => this.handleOnMessage(event);
46
+ this.webSocket.onmessagebinary = (event) =>
47
+ this.handleOnMessageBinary(event);
48
+ return true;
49
+ } catch (error) {
50
+ Logger.Error(error, error);
51
+ return false;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * 处理以二进制形式接收消息时发生的情况
57
+ * @param event - Message Received
58
+ */
59
+ handleOnMessageBinary(event: MessageEvent) {
60
+ // if the event is empty return
61
+ if (!event || !event.data) {
62
+ return;
63
+ }
64
+
65
+ // handle the binary and then handle the message
66
+ event.data
67
+ .text()
68
+ .then((messageString: unknown) => {
69
+ // build a new message
70
+ const constructedMessage = new MessageEvent(
71
+ 'messageFromBinary',
72
+ {
73
+ data: messageString
74
+ }
75
+ );
76
+
77
+ // 将新的字符串化事件发送回`onmessage`
78
+ this.handleOnMessage(constructedMessage);
79
+ })
80
+ .catch((error: Error) => {
81
+ Logger.Error(
82
+ Logger.GetStackTrace(),
83
+ `从websocket解析二进制blob失败,原因: ${error}`
84
+ );
85
+ });
86
+ }
87
+
88
+ /**
89
+ * 处理接收到消息时发生的事情
90
+ * @param event - Message Received
91
+ */
92
+ handleOnMessage(event: MessageEvent) {
93
+ // 检查websocket消息是否为二进制,如果是,将其字符串化。
94
+ if (event.data && event.data instanceof Blob) {
95
+ this.handleOnMessageBinary(event);
96
+ return;
97
+ }
98
+
99
+ const message: MessageReceive.MessageRecv = JSON.parse(event.data);
100
+ Logger.Log(
101
+ Logger.GetStackTrace(),
102
+ 'received => \n' +
103
+ JSON.stringify(JSON.parse(event.data), undefined, 4),
104
+ 6
105
+ );
106
+
107
+ // 发送到我们的信号协议来处理传入的消息
108
+ this.signallingProtocol.handleMessage(message.type, event.data);
109
+ }
110
+
111
+ /**
112
+ * 处理Websocket打开时的事件
113
+ * @param event - Not Used
114
+ */
115
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
116
+ handleOnOpen(event: Event) {
117
+ Logger.Log(
118
+ Logger.GetStackTrace(),
119
+ '通过WebSocket连接到信令服务器',
120
+ 6
121
+ );
122
+ this.onOpen.dispatchEvent(new Event('open'));
123
+ }
124
+
125
+ /**
126
+ * 在websocket中处理错误
127
+ * @param event - Error Payload
128
+ */
129
+ handleOnError() {
130
+ Logger.Error(Logger.GetStackTrace(), 'WebSocket error');
131
+ }
132
+
133
+ /**
134
+ * 当Websocket关闭时处理
135
+ * @param event - Close Event
136
+ */
137
+ handleOnClose(event: CloseEvent) {
138
+ console.log(event);
139
+
140
+ Logger.Log(
141
+ Logger.GetStackTrace(),
142
+ '通过WebSocket与信令服务器断开连接: ' +
143
+ JSON.stringify(event.code) +
144
+ ' - ' +
145
+ event.reason
146
+ );
147
+
148
+ // 被踢下线
149
+ if (event.code == 4004) {
150
+ this.onOpen.dispatchEvent(new Event('close', event));
151
+ this.onClose.dispatchEvent(new CustomEvent('close', { 'detail': event }));
152
+ }
153
+
154
+ }
155
+
156
+ requestStreamerList() {
157
+ const payload = new MessageSend.MessageListStreamers();
158
+ this.webSocket.send(payload.payload());
159
+ }
160
+
161
+ requestStreamerObject(streamerid: string) {
162
+ const payload = new MessageSend.requestStreamerObject(streamerid);
163
+ this.webSocket.send(payload.payload());
164
+ }
165
+
166
+ sendSubscribe(streamerid: string) {
167
+ const payload = new MessageSend.MessageSubscribe(streamerid);
168
+ this.webSocket.send(payload.payload());
169
+ }
170
+
171
+ sendUnsubscribe() {
172
+ const payload = new MessageSend.MessageUnsubscribe();
173
+ this.webSocket.send(payload.payload());
174
+ }
175
+
176
+ sendWebRtcOffer(offer: RTCSessionDescriptionInit) {
177
+ const payload = new MessageSend.MessageWebRTCOffer(offer);
178
+ this.webSocket.send(payload.payload());
179
+ }
180
+
181
+ sendWebRtcAnswer(answer: RTCSessionDescriptionInit) {
182
+ const payload = new MessageSend.MessageWebRTCAnswer(answer);
183
+ this.webSocket.send(payload.payload());
184
+ }
185
+
186
+ sendWebRtcDatachannelRequest() {
187
+ const payload = new MessageSend.MessageWebRTCDatachannelRequest();
188
+ this.webSocket.send(payload.payload());
189
+ }
190
+
191
+ sendSFURecvDataChannelReady() {
192
+ const payload = new MessageSend.MessageSFURecvDataChannelReady();
193
+ this.webSocket.send(payload.payload());
194
+ }
195
+
196
+ /**
197
+ *向服务器发送一个RTC Ice候选项
198
+ * @param candidate—RTC Ice候选
199
+ */
200
+ sendIceCandidate(candidate: RTCIceCandidate) {
201
+ Logger.Log(Logger.GetStackTrace(), 'Sending Ice Candidate(发送Ice候选人)');
202
+ if (
203
+ this.webSocket &&
204
+ this.webSocket.readyState === this.WS_OPEN_STATE
205
+ ) {
206
+ //ws.send(JSON.stringify({ type: 'iceCandidate', candidate: candidate }));
207
+ const IceCandidate = new MessageSend.MessageIceCandidate(candidate);
208
+
209
+ this.webSocket.send(IceCandidate.payload());
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Closes the Websocket connection
215
+ */
216
+ close() {
217
+ this.webSocket?.close();
218
+ }
219
+
220
+ /**
221
+ * The Message Contains the payload of the peer connection options used for the RTC Peer hand shake
222
+ * @param messageConfig - Config Message received from he signaling server
223
+ */
224
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
225
+ onConfig(messageConfig: MessageReceive.MessageConfig) { }
226
+
227
+ /**
228
+ * The Message Contains the payload of the peer connection options used for the RTC Peer hand shake
229
+ * @param messageConfig - Config Message received from he signaling server
230
+ */
231
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
232
+ onStreamerList(messageStreamerList: MessageReceive.MessageStreamerList) { }
233
+
234
+ /**
235
+ * @param iceCandidate - Ice Candidate sent from the Signaling server server's RTC hand shake
236
+ */
237
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
238
+ onIceCandidate(iceCandidate: RTCIceCandidateInit) { }
239
+
240
+ /**
241
+ * Event is fired when the websocket receives the answer for the RTC peer Connection
242
+ * @param messageAnswer - The RTC Answer payload from the signaling server
243
+ */
244
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
245
+ onWebRtcAnswer(messageAnswer: MessageReceive.MessageAnswer) { }
246
+
247
+ /**
248
+ * Event is fired when the websocket receives the offer for the RTC peer Connection
249
+ * @param messageOffer - The sdp offer
250
+ */
251
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
252
+ onWebRtcOffer(messageOffer: MessageReceive.MessageOffer) { }
253
+
254
+ /**
255
+ * Event is fired when the websocket receives the data channels for the RTC peer Connection from the SFU
256
+ * @param messageDataChannels - The data channels details
257
+ */
258
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
259
+ onWebRtcPeerDataChannels(messageDataChannels: MessageReceive.MessagePeerDataChannels) { }
260
+
261
+ /**
262
+ * Event is fired when the websocket receives the an updated player count from cirrus
263
+ * @param MessagePlayerCount - The new player count
264
+ */
265
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
266
+ onPlayerCount(playerCount: MessageReceive.MessagePlayerCount) { }
267
+ }
@@ -0,0 +1,319 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { Logger } from '../Logger/Logger';
4
+ import { WebRtcPlayerController } from '../WebRtcPlayer/WebRtcPlayerController';
5
+ import { WebGLUtils } from '../Util/WebGLUtils';
6
+ import { Controller } from '../Inputs/GamepadTypes';
7
+ import { XRGamepadController } from '../Inputs/XRGamepadController';
8
+ import { XrFrameEvent } from '../Util/EventEmitter'
9
+ import { Flags } from '../pixelstreamingfrontend';
10
+
11
+ export class WebXRController {
12
+ private xrSession: XRSession;
13
+ private xrRefSpace: XRReferenceSpace;
14
+ private gl: WebGL2RenderingContext;
15
+
16
+ private positionLocation: number;
17
+ private texcoordLocation: number;
18
+ private resolutionLocation: WebGLUniformLocation;
19
+ private offsetLocation: WebGLUniformLocation;
20
+
21
+ private positionBuffer: WebGLBuffer;
22
+ private texcoordBuffer: WebGLBuffer;
23
+
24
+ private webRtcController: WebRtcPlayerController;
25
+ private xrGamepadController: XRGamepadController;
26
+ private xrControllers: Array<Controller>;
27
+
28
+ onSessionStarted: EventTarget;
29
+ onSessionEnded: EventTarget;
30
+ onFrame: EventTarget;
31
+
32
+ constructor(webRtcPlayerController: WebRtcPlayerController) {
33
+ this.xrSession = null;
34
+ this.webRtcController = webRtcPlayerController;
35
+ this.xrControllers = [];
36
+ this.xrGamepadController = new XRGamepadController(
37
+ this.webRtcController.streamMessageController
38
+ );
39
+ this.onSessionEnded = new EventTarget();
40
+ this.onSessionStarted = new EventTarget();
41
+ this.onFrame = new EventTarget();
42
+ }
43
+
44
+ public xrClicked() {
45
+ if (!this.xrSession) {
46
+ navigator.xr
47
+ .requestSession('immersive-vr')
48
+ .then((session: XRSession) => {
49
+ this.onXrSessionStarted(session);
50
+ });
51
+ } else {
52
+ this.xrSession.end();
53
+ }
54
+ }
55
+
56
+ onXrSessionEnded() {
57
+ Logger.Log(Logger.GetStackTrace(), 'XR Session ended');
58
+ this.xrSession = null;
59
+ this.onSessionEnded.dispatchEvent(new Event('xrSessionEnded'));
60
+ }
61
+
62
+ onXrSessionStarted(session: XRSession) {
63
+ Logger.Log(Logger.GetStackTrace(), 'XR Session started');
64
+
65
+ this.xrSession = session;
66
+ this.xrSession.addEventListener('end', () => {
67
+ this.onXrSessionEnded();
68
+ });
69
+
70
+ const canvas = document.createElement('canvas');
71
+ this.gl = canvas.getContext('webgl2', {
72
+ xrCompatible: true
73
+ });
74
+
75
+ this.xrSession.updateRenderState({
76
+ baseLayer: new XRWebGLLayer(this.xrSession, this.gl)
77
+ });
78
+
79
+ // setup vertex shader
80
+ const vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
81
+ this.gl.shaderSource(vertexShader, WebGLUtils.vertexShader());
82
+ this.gl.compileShader(vertexShader);
83
+
84
+ // setup fragment shader
85
+ const fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
86
+ this.gl.shaderSource(fragmentShader, WebGLUtils.fragmentShader());
87
+ this.gl.compileShader(fragmentShader);
88
+
89
+ // setup GLSL program
90
+ const shaderProgram = this.gl.createProgram();
91
+ this.gl.attachShader(shaderProgram, vertexShader);
92
+ this.gl.attachShader(shaderProgram, fragmentShader);
93
+ this.gl.linkProgram(shaderProgram);
94
+ this.gl.useProgram(shaderProgram);
95
+
96
+ // look up where vertex data needs to go
97
+ this.positionLocation = this.gl.getAttribLocation(
98
+ shaderProgram,
99
+ 'a_position'
100
+ );
101
+ this.texcoordLocation = this.gl.getAttribLocation(
102
+ shaderProgram,
103
+ 'a_texCoord'
104
+ );
105
+ // Create a buffer to put three 2d clip space points in
106
+ this.positionBuffer = this.gl.createBuffer();
107
+ // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
108
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
109
+
110
+ // Turn on the position attribute
111
+ this.gl.enableVertexAttribArray(this.positionLocation);
112
+ // Create a texture.
113
+ const texture = this.gl.createTexture();
114
+ this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
115
+ // Set the parameters so we can render any size image.
116
+ this.gl.texParameteri(
117
+ this.gl.TEXTURE_2D,
118
+ this.gl.TEXTURE_WRAP_S,
119
+ this.gl.CLAMP_TO_EDGE
120
+ );
121
+ this.gl.texParameteri(
122
+ this.gl.TEXTURE_2D,
123
+ this.gl.TEXTURE_WRAP_T,
124
+ this.gl.CLAMP_TO_EDGE
125
+ );
126
+ this.gl.texParameteri(
127
+ this.gl.TEXTURE_2D,
128
+ this.gl.TEXTURE_MIN_FILTER,
129
+ this.gl.NEAREST
130
+ );
131
+ this.gl.texParameteri(
132
+ this.gl.TEXTURE_2D,
133
+ this.gl.TEXTURE_MAG_FILTER,
134
+ this.gl.NEAREST
135
+ );
136
+
137
+ this.texcoordBuffer = this.gl.createBuffer();
138
+ // lookup uniforms
139
+ this.resolutionLocation = this.gl.getUniformLocation(
140
+ shaderProgram,
141
+ 'u_resolution'
142
+ );
143
+ this.offsetLocation = this.gl.getUniformLocation(
144
+ shaderProgram,
145
+ 'u_offset'
146
+ );
147
+
148
+ session.requestReferenceSpace('local').then((refSpace) => {
149
+ this.xrRefSpace = refSpace;
150
+ this.xrSession.requestAnimationFrame(
151
+ (time: DOMHighResTimeStamp, frame: XRFrame) =>
152
+ this.onXrFrame(time, frame)
153
+ );
154
+ });
155
+
156
+ this.onSessionStarted.dispatchEvent(new Event('xrSessionStarted'));
157
+ }
158
+
159
+ onXrFrame(time: DOMHighResTimeStamp, frame: XRFrame) {
160
+ const pose = frame.getViewerPose(this.xrRefSpace);
161
+ if (pose) {
162
+ const matrix = pose.transform.matrix;
163
+ const mat = [];
164
+ for (let i = 0; i < 16; i++) {
165
+ mat[i] = new Float32Array([matrix[i]])[0];
166
+ }
167
+
168
+ // prettier-ignore
169
+ this.webRtcController.streamMessageController.toStreamerHandlers.get('XRHMDTransform')([
170
+ mat[0], mat[4], mat[8], mat[12],
171
+ mat[1], mat[5], mat[9], mat[13],
172
+ mat[2], mat[6], mat[10], mat[14],
173
+ mat[3], mat[7], mat[11], mat[15]
174
+ ]);
175
+
176
+ const glLayer = this.xrSession.renderState.baseLayer;
177
+ // If we do have a valid pose, bind the WebGL layer's framebuffer,
178
+ // which is where any content to be displayed on the XRDevice must be
179
+ // rendered.
180
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, glLayer.framebuffer);
181
+
182
+ // Upload the image into the texture. WebGL knows how to extract the current frame from the video element
183
+ this.gl.texImage2D(
184
+ this.gl.TEXTURE_2D,
185
+ 0,
186
+ this.gl.RGBA,
187
+ this.gl.RGBA,
188
+ this.gl.UNSIGNED_BYTE,
189
+ this.webRtcController.videoPlayer.getVideoElement()
190
+ );
191
+ this.render(this.webRtcController.videoPlayer.getVideoElement());
192
+ }
193
+
194
+ if (this.webRtcController.config.isFlagEnabled(Flags.XRControllerInput)) {
195
+ this.xrSession.inputSources.forEach(
196
+ (source: XRInputSource, index: number, array: XRInputSource[]) => {
197
+ this.xrGamepadController.updateStatus(
198
+ source,
199
+ frame,
200
+ this.xrRefSpace
201
+ );
202
+ },
203
+ this
204
+ );
205
+ }
206
+
207
+ this.xrSession.requestAnimationFrame(
208
+ (time: DOMHighResTimeStamp, frame: XRFrame) =>
209
+ this.onXrFrame(time, frame)
210
+ );
211
+
212
+ this.onFrame.dispatchEvent(new XrFrameEvent({
213
+ time,
214
+ frame
215
+ }));
216
+ }
217
+
218
+ private render(videoElement: HTMLVideoElement) {
219
+ if (!this.gl) {
220
+ return;
221
+ }
222
+
223
+ const glLayer = this.xrSession.renderState.baseLayer;
224
+ this.gl.viewport(
225
+ 0,
226
+ 0,
227
+ glLayer.framebufferWidth,
228
+ glLayer.framebufferHeight
229
+ );
230
+ this.gl.uniform4f(this.offsetLocation, 1.0, 1.0, 0.0, 0.0);
231
+
232
+ // Set rectangle
233
+ // prettier-ignore
234
+ this.gl.bufferData(
235
+ this.gl.ARRAY_BUFFER,
236
+ new Float32Array([
237
+ 0, 0,
238
+ videoElement.videoWidth, 0,
239
+ 0, videoElement.videoHeight,
240
+ 0, videoElement.videoHeight,
241
+ videoElement.videoWidth, 0,
242
+ videoElement.videoWidth, videoElement.videoHeight
243
+ ]),
244
+ this.gl.STATIC_DRAW
245
+ );
246
+
247
+ // Provide texture coordinates for the rectangle
248
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.texcoordBuffer);
249
+ this.gl.bufferData(
250
+ this.gl.ARRAY_BUFFER,
251
+ new Float32Array([
252
+ 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0
253
+ ]),
254
+ this.gl.STATIC_DRAW
255
+ );
256
+
257
+ let size; // components per iteration
258
+ let type; // the data type
259
+ let normalize; // normalize the data
260
+ let stride; // 0 = move forward size * sizeof(type) each iteration to get the next position
261
+ let offset; // start position of the buffer
262
+
263
+ // Bind the position buffer.
264
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
265
+ // Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)
266
+ size = 2; // 2 components per iteration
267
+ type = this.gl.FLOAT; // the data is 32bit floats
268
+ normalize = false; // don't normalize the data
269
+ stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
270
+ offset = 0; // start at the beginning of the buffer
271
+ this.gl.vertexAttribPointer(
272
+ this.positionLocation,
273
+ size,
274
+ type,
275
+ normalize,
276
+ stride,
277
+ offset
278
+ );
279
+ // Turn on the texcoord attribute
280
+ this.gl.enableVertexAttribArray(this.texcoordLocation);
281
+ // bind the texcoord buffer.
282
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.texcoordBuffer);
283
+ // Tell the texcoord attribute how to get data out of texcoordBuffer (ARRAY_BUFFER)
284
+ size = 2; // 2 components per iteration
285
+ type = this.gl.FLOAT; // the data is 32bit floats
286
+ normalize = false; // don't normalize the data
287
+ stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
288
+ offset = 0; // start at the beginning of the buffer
289
+ this.gl.vertexAttribPointer(
290
+ this.texcoordLocation,
291
+ size,
292
+ type,
293
+ normalize,
294
+ stride,
295
+ offset
296
+ );
297
+ // set the resolution
298
+ this.gl.uniform2f(
299
+ this.resolutionLocation,
300
+ videoElement.videoWidth,
301
+ videoElement.videoHeight
302
+ );
303
+ // draw the rectangle.
304
+ const primitiveType = this.gl.TRIANGLES;
305
+ const count = 6;
306
+ offset = 0;
307
+ this.gl.drawArrays(primitiveType, offset, count);
308
+ }
309
+
310
+ static isSessionSupported(mode: XRSessionMode): Promise<boolean> {
311
+ if (navigator.xr) {
312
+ return navigator.xr.isSessionSupported(mode);
313
+ } else {
314
+ return new Promise<boolean>(() => {
315
+ return false;
316
+ });
317
+ }
318
+ }
319
+ }