@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,199 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { CoordinateConverter } from '../Util/CoordinateConverter';
4
+ import { StreamMessageController } from '../UeInstanceMessage/StreamMessageController';
5
+ import { VideoPlayer } from '../VideoPlayer/VideoPlayer';
6
+ import { ITouchController } from './ITouchController';
7
+ import { MouseButton } from './MouseButtons';
8
+ import { EventListenerTracker } from '../Util/EventListenerTracker';
9
+
10
+ /**
11
+ * Allows for the usage of fake touch events and implements ITouchController
12
+ * @param dataChannelController - The controller for the Data channel
13
+ * @param videoElementParent - The video player DOM element
14
+ */
15
+ export class FakeTouchController implements ITouchController {
16
+ fakeTouchFinger: FakeTouchFinger;
17
+ toStreamerMessagesProvider: StreamMessageController;
18
+ videoElementProvider: VideoPlayer;
19
+ coordinateConverter: CoordinateConverter;
20
+ videoElementParentClientRect: DOMRect;
21
+
22
+ // Utility for keeping track of event handlers and unregistering them
23
+ private touchEventListenerTracker = new EventListenerTracker();
24
+
25
+ /**
26
+ * @param toStreamerMessagesProvider - Stream message instance
27
+ * @param videoElementProvider - Video element instance
28
+ * @param coordinateConverter - A coordinate converter instance
29
+ */
30
+ constructor(
31
+ toStreamerMessagesProvider: StreamMessageController,
32
+ videoElementProvider: VideoPlayer,
33
+ coordinateConverter: CoordinateConverter
34
+ ) {
35
+ this.toStreamerMessagesProvider = toStreamerMessagesProvider;
36
+ this.videoElementProvider = videoElementProvider;
37
+ this.coordinateConverter = coordinateConverter;
38
+ const ontouchstart = (ev: TouchEvent) => this.onTouchStart(ev);
39
+ const ontouchend = (ev: TouchEvent) => this.onTouchEnd(ev);
40
+ const ontouchmove = (ev: TouchEvent) => this.onTouchMove(ev);
41
+ document.addEventListener('touchstart', ontouchstart, { passive: false });
42
+ document.addEventListener('touchend', ontouchend, { passive: false });
43
+ document.addEventListener('touchmove', ontouchmove, { passive: false });
44
+ this.touchEventListenerTracker.addUnregisterCallback(
45
+ () => document.removeEventListener('touchstart', ontouchstart)
46
+ );
47
+ this.touchEventListenerTracker.addUnregisterCallback(
48
+ () => document.removeEventListener('touchend', ontouchend)
49
+ );
50
+ this.touchEventListenerTracker.addUnregisterCallback(
51
+ () => document.removeEventListener('touchmove', ontouchmove)
52
+ );
53
+ }
54
+
55
+ /**
56
+ * Unregister all touch events
57
+ */
58
+ unregisterTouchEvents() {
59
+ this.touchEventListenerTracker.unregisterAll();
60
+ }
61
+
62
+ /**
63
+ * Sets the video Element Parent Client Rect numbers for this class
64
+ * @param videoElementParentClientRect - a html ElementParentClientRect object
65
+ */
66
+ setVideoElementParentClientRect(videoElementParentClientRect: DOMRect) {
67
+ this.videoElementParentClientRect = videoElementParentClientRect;
68
+ }
69
+
70
+ /**
71
+ * When a touch event begins
72
+ * @param touch - the activating touch event
73
+ */
74
+ onTouchStart(touch: TouchEvent): void {
75
+ if (!this.videoElementProvider.isVideoReady()) {
76
+ return;
77
+ }
78
+ if (this.fakeTouchFinger == null) {
79
+ const first_touch = touch.changedTouches[0];
80
+ this.fakeTouchFinger = new FakeTouchFinger(
81
+ first_touch.identifier,
82
+ first_touch.clientX - this.videoElementParentClientRect.left,
83
+ first_touch.clientY - this.videoElementParentClientRect.top
84
+ );
85
+
86
+ const videoElementParent =
87
+ this.videoElementProvider.getVideoParentElement() as HTMLDivElement;
88
+ const mouseEvent = new MouseEvent('mouseenter', first_touch);
89
+ videoElementParent.dispatchEvent(mouseEvent);
90
+
91
+ const coord = this.coordinateConverter.normalizeAndQuantizeUnsigned(
92
+ this.fakeTouchFinger.x,
93
+ this.fakeTouchFinger.y
94
+ );
95
+ const toStreamerHandlers =
96
+ this.toStreamerMessagesProvider.toStreamerHandlers;
97
+ toStreamerHandlers.get('MouseDown')([
98
+ MouseButton.mainButton,
99
+ coord.x,
100
+ coord.y
101
+ ]);
102
+ }
103
+ touch.preventDefault();
104
+ }
105
+
106
+ /**
107
+ * When a touch event ends
108
+ * @param touchEvent - the activating touch event
109
+ */
110
+ onTouchEnd(touchEvent: TouchEvent): void {
111
+ if (!this.videoElementProvider.isVideoReady()) {
112
+ return;
113
+ }
114
+ const videoElementParent =
115
+ this.videoElementProvider.getVideoParentElement();
116
+ const toStreamerHandlers =
117
+ this.toStreamerMessagesProvider.toStreamerHandlers;
118
+
119
+ for (let t = 0; t < touchEvent.changedTouches.length; t++) {
120
+ const touch = touchEvent.changedTouches[t];
121
+ if (touch.identifier === this.fakeTouchFinger.id) {
122
+ const x =
123
+ touch.clientX - this.videoElementParentClientRect.left;
124
+ const y = touch.clientY - this.videoElementParentClientRect.top;
125
+ const coord =
126
+ this.coordinateConverter.normalizeAndQuantizeUnsigned(x, y);
127
+ toStreamerHandlers.get('MouseUp')([
128
+ MouseButton.mainButton,
129
+ coord.x,
130
+ coord.y
131
+ ]);
132
+
133
+ const mouseEvent = new MouseEvent('mouseleave', touch);
134
+ videoElementParent.dispatchEvent(mouseEvent);
135
+ this.fakeTouchFinger = null;
136
+ break;
137
+ }
138
+ }
139
+ touchEvent.preventDefault();
140
+ }
141
+
142
+ /**
143
+ * On a Move touch event
144
+ * @param touchEvent - the activating touch event
145
+ */
146
+ onTouchMove(touchEvent: TouchEvent): void {
147
+ if (!this.videoElementProvider.isVideoReady()) {
148
+ return;
149
+ }
150
+ const toStreamerHandlers =
151
+ this.toStreamerMessagesProvider.toStreamerHandlers;
152
+
153
+ for (let t = 0; t < touchEvent.touches.length; t++) {
154
+ const touch = touchEvent.touches[t];
155
+ if (touch.identifier === this.fakeTouchFinger.id) {
156
+ const x =
157
+ touch.clientX - this.videoElementParentClientRect.left;
158
+ const y = touch.clientY - this.videoElementParentClientRect.top;
159
+ const coord =
160
+ this.coordinateConverter.normalizeAndQuantizeUnsigned(x, y);
161
+ const delta =
162
+ this.coordinateConverter.normalizeAndQuantizeSigned(
163
+ x - this.fakeTouchFinger.x,
164
+ y - this.fakeTouchFinger.y
165
+ );
166
+ toStreamerHandlers.get('MouseMove')([
167
+ coord.x,
168
+ coord.y,
169
+ delta.x,
170
+ delta.y
171
+ ]);
172
+ this.fakeTouchFinger.x = x;
173
+ this.fakeTouchFinger.y = y;
174
+ break;
175
+ }
176
+ }
177
+ touchEvent.preventDefault();
178
+ }
179
+ }
180
+
181
+ /**
182
+ * The interface for finger position mapping
183
+ */
184
+ export class FakeTouchFinger {
185
+ id: number;
186
+ x: number;
187
+ y: number;
188
+
189
+ /**
190
+ * @param id - the button id
191
+ * @param x - the x axis value
192
+ * @param y - the y axis value
193
+ */
194
+ constructor(id: number, x: number, y: number) {
195
+ this.id = id;
196
+ this.x = x;
197
+ this.y = y;
198
+ }
199
+ }
@@ -0,0 +1,300 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { Logger } from '../Logger/Logger';
4
+ import { StreamMessageController } from '../UeInstanceMessage/StreamMessageController';
5
+ import { EventListenerTracker } from '../Util/EventListenerTracker';
6
+ import { Controller } from './GamepadTypes';
7
+
8
+ /**
9
+ * The class that handles the functionality of gamepads and controllers
10
+ */
11
+ export class GamePadController {
12
+ controllers: Array<Controller>;
13
+ requestAnimationFrame: (callback: FrameRequestCallback) => number;
14
+ toStreamerMessagesProvider: StreamMessageController;
15
+
16
+ // Utility for keeping track of event handlers and unregistering them
17
+ private gamePadEventListenerTracker = new EventListenerTracker();
18
+
19
+ /**
20
+ * @param toStreamerMessagesProvider - Stream message instance
21
+ */
22
+ constructor(toStreamerMessagesProvider: StreamMessageController) {
23
+ this.toStreamerMessagesProvider = toStreamerMessagesProvider;
24
+
25
+ this.requestAnimationFrame = (
26
+ window.mozRequestAnimationFrame ||
27
+ window.webkitRequestAnimationFrame ||
28
+ window.requestAnimationFrame
29
+ ).bind(window);
30
+ const browserWindow = window as Window;
31
+ if ('GamepadEvent' in browserWindow) {
32
+ const onGamePadConnected = (ev: GamepadEvent) =>
33
+ this.gamePadConnectHandler(ev);
34
+ const onGamePadDisconnected = (ev: GamepadEvent) =>
35
+ this.gamePadDisconnectHandler(ev);
36
+ window.addEventListener('gamepadconnected', onGamePadConnected);
37
+ window.addEventListener('gamepaddisconnected', onGamePadDisconnected);
38
+ this.gamePadEventListenerTracker.addUnregisterCallback(
39
+ () => window.removeEventListener('gamepadconnected', onGamePadConnected)
40
+ );
41
+ this.gamePadEventListenerTracker.addUnregisterCallback(
42
+ () => window.removeEventListener('gamepaddisconnected', onGamePadDisconnected)
43
+ );
44
+ } else if ('WebKitGamepadEvent' in browserWindow) {
45
+ const onWebkitGamePadConnected = (ev: GamepadEvent) => this.gamePadConnectHandler(ev);
46
+ const onWebkitGamePadDisconnected = (ev: GamepadEvent) => this.gamePadDisconnectHandler(ev);
47
+ window.addEventListener('webkitgamepadconnected', onWebkitGamePadConnected);
48
+ window.addEventListener('webkitgamepaddisconnected', onWebkitGamePadDisconnected);
49
+ this.gamePadEventListenerTracker.addUnregisterCallback(
50
+ () => window.removeEventListener('webkitgamepadconnected', onWebkitGamePadConnected)
51
+ );
52
+ this.gamePadEventListenerTracker.addUnregisterCallback(
53
+ () => window.removeEventListener('webkitgamepaddisconnected', onWebkitGamePadDisconnected)
54
+ );
55
+ }
56
+ this.controllers = [];
57
+ if (navigator.getGamepads) {
58
+ for (const gamepad of navigator.getGamepads()) {
59
+ if (gamepad) {
60
+ this.gamePadConnectHandler(new GamepadEvent('gamepadconnected', { gamepad }));
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Unregisters all event handlers
68
+ */
69
+ unregisterGamePadEvents() {
70
+ this.gamePadEventListenerTracker.unregisterAll();
71
+ for(const controller of this.controllers) {
72
+ if(controller.id !== undefined) {
73
+ this.onGamepadDisconnected(controller.id);
74
+ }
75
+ }
76
+ this.controllers = [];
77
+ this.onGamepadConnected = () => { /* */ };
78
+ this.onGamepadDisconnected = () => { /* */ };
79
+ }
80
+
81
+ /**
82
+ * Connects the gamepad handler
83
+ * @param gamePadEvent - the activating gamepad event
84
+ */
85
+ gamePadConnectHandler(gamePadEvent: GamepadEvent) {
86
+ Logger.Log(Logger.GetStackTrace(), 'Gamepad connect handler', 6);
87
+ const gamepad = gamePadEvent.gamepad;
88
+
89
+ const temp: Controller = {
90
+ currentState: gamepad,
91
+ prevState: gamepad,
92
+ id: undefined
93
+ };
94
+
95
+ this.controllers.push(temp);
96
+ this.controllers[gamepad.index].currentState = gamepad;
97
+ this.controllers[gamepad.index].prevState = gamepad;
98
+ Logger.Log(
99
+ Logger.GetStackTrace(),
100
+ 'gamepad: ' + gamepad.id + ' connected',
101
+ 6
102
+ );
103
+ window.requestAnimationFrame(() => this.updateStatus());
104
+ this.onGamepadConnected();
105
+ }
106
+
107
+ /**
108
+ * Disconnects the gamepad handler
109
+ * @param gamePadEvent - the activating gamepad event
110
+ */
111
+ gamePadDisconnectHandler(gamePadEvent: GamepadEvent) {
112
+ Logger.Log(Logger.GetStackTrace(), 'Gamepad disconnect handler', 6);
113
+ Logger.Log(
114
+ Logger.GetStackTrace(),
115
+ 'gamepad: ' + gamePadEvent.gamepad.id + ' disconnected',
116
+ 6
117
+ );
118
+ const deletedController = this.controllers[gamePadEvent.gamepad.index];
119
+ delete this.controllers[gamePadEvent.gamepad.index];
120
+ this.controllers = this.controllers.filter(
121
+ (controller) => controller !== undefined
122
+ );
123
+ this.onGamepadDisconnected(deletedController.id);
124
+ }
125
+
126
+ /**
127
+ * Scan for connected gamepads
128
+ */
129
+ scanGamePads() {
130
+ const gamepads = navigator.getGamepads
131
+ ? navigator.getGamepads()
132
+ : navigator.webkitGetGamepads
133
+ ? navigator.webkitGetGamepads()
134
+ : [];
135
+ for (let i = 0; i < gamepads.length; i++) {
136
+ if (gamepads[i] && gamepads[i].index in this.controllers) {
137
+ this.controllers[gamepads[i].index].currentState = gamepads[i];
138
+ }
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Updates the status of the gamepad and sends the inputs
144
+ */
145
+ updateStatus() {
146
+ this.scanGamePads();
147
+ const toStreamerHandlers =
148
+ this.toStreamerMessagesProvider.toStreamerHandlers;
149
+
150
+ // Iterate over multiple controllers in the case the multiple gamepads are connected
151
+ for (const controller of this.controllers) {
152
+ // If we haven't received an id (possible if using an older version of UE), return to original functionality
153
+ const controllerIndex = (controller.id === undefined) ? this.controllers.indexOf(controller) : controller.id;
154
+ const currentState = controller.currentState;
155
+ for (let i = 0; i < controller.currentState.buttons.length; i++) {
156
+ const currentButton = controller.currentState.buttons[i];
157
+ const previousButton = controller.prevState.buttons[i];
158
+ if (currentButton.pressed) {
159
+ // press
160
+ if (i == gamepadLayout.LeftTrigger) {
161
+ // UEs left analog has a button index of 5
162
+ toStreamerHandlers.get('GamepadAnalog')([
163
+ controllerIndex,
164
+ 5,
165
+ currentButton.value
166
+ ]);
167
+ } else if (i == gamepadLayout.RightTrigger) {
168
+ // UEs right analog has a button index of 6
169
+ toStreamerHandlers.get('GamepadAnalog')([
170
+ controllerIndex,
171
+ 6,
172
+ currentButton.value
173
+ ]);
174
+ } else {
175
+ toStreamerHandlers.get('GamepadButtonPressed')([
176
+ controllerIndex,
177
+ i,
178
+ previousButton.pressed ? 1 : 0
179
+ ]);
180
+ }
181
+ } else if (!currentButton.pressed && previousButton.pressed) {
182
+ // release
183
+ if (i == gamepadLayout.LeftTrigger) {
184
+ // UEs left analog has a button index of 5
185
+ toStreamerHandlers.get('GamepadAnalog')([
186
+ controllerIndex,
187
+ 5,
188
+ 0
189
+ ]);
190
+ } else if (i == gamepadLayout.RightTrigger) {
191
+ // UEs right analog has a button index of 6
192
+ toStreamerHandlers.get('GamepadAnalog')([
193
+ controllerIndex,
194
+ 6,
195
+ 0
196
+ ]);
197
+ } else {
198
+ toStreamerHandlers.get('GamepadButtonReleased')([
199
+ controllerIndex,
200
+ i
201
+ ]);
202
+ }
203
+ }
204
+ }
205
+ // Iterate over gamepad axes (we will increment in lots of 2 as there is 2 axes per stick)
206
+ for (let i = 0; i < currentState.axes.length; i += 2) {
207
+ // Horizontal axes are even numbered
208
+ const x = parseFloat(currentState.axes[i].toFixed(4));
209
+
210
+ // Vertical axes are odd numbered
211
+ // https://w3c.github.io/gamepad/#remapping Gamepad browser side standard mapping has positive down, negative up. This is downright disgusting. So we fix it.
212
+ const y = -parseFloat(currentState.axes[i + 1].toFixed(4));
213
+
214
+ // UE's analog axes follow the same order as the browsers, but start at index 1 so we will offset as such
215
+ toStreamerHandlers.get('GamepadAnalog')([
216
+ controllerIndex,
217
+ i + 1,
218
+ x
219
+ ]); // Horizontal axes, only offset by 1
220
+ toStreamerHandlers.get('GamepadAnalog')([
221
+ controllerIndex,
222
+ i + 2,
223
+ y
224
+ ]); // Vertical axes, offset by two (1 to match UEs axes convention and then another 1 for the vertical axes)
225
+ }
226
+ this.controllers[controllerIndex].prevState = currentState;
227
+ }
228
+ if (this.controllers.length > 0) {
229
+ this.requestAnimationFrame(() => this.updateStatus());
230
+ }
231
+ }
232
+
233
+ onGamepadResponseReceived(gamepadId: number) {
234
+ for(const controller of this.controllers) {
235
+ if(controller.id === undefined) {
236
+ controller.id = gamepadId;
237
+ break;
238
+ }
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Event to send the gamepadconnected message to the application
244
+ */
245
+ onGamepadConnected() {
246
+ // Default Functionality: Do Nothing
247
+ }
248
+
249
+ /**
250
+ * Event to send the gamepaddisconnected message to the application
251
+ */
252
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
253
+ onGamepadDisconnected(controllerIdx: number) {
254
+ // Default Functionality: Do Nothing
255
+ }
256
+ }
257
+
258
+
259
+
260
+ /**
261
+ * Additional types for Window and Navigator
262
+ */
263
+ declare global {
264
+ interface Window {
265
+ mozRequestAnimationFrame(callback: FrameRequestCallback): number;
266
+ webkitRequestAnimationFrame(callback: FrameRequestCallback): number;
267
+ }
268
+
269
+ interface Navigator {
270
+ webkitGetGamepads(): Gamepad[];
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Gamepad layout codes enum
276
+ */
277
+ export enum gamepadLayout {
278
+ RightClusterBottomButton = 0,
279
+ RightClusterRightButton = 1,
280
+ RightClusterLeftButton = 2,
281
+ RightClusterTopButton = 3,
282
+ LeftShoulder = 4,
283
+ RightShoulder = 5,
284
+ LeftTrigger = 6,
285
+ RightTrigger = 7,
286
+ SelectOrBack = 8,
287
+ StartOrForward = 9,
288
+ LeftAnalogPress = 10,
289
+ RightAnalogPress = 11,
290
+ LeftClusterTopButton = 12,
291
+ LeftClusterBottomButton = 13,
292
+ LeftClusterLeftButton = 14,
293
+ LeftClusterRightButton = 15,
294
+ CentreButton = 16,
295
+ // Axes
296
+ LeftStickHorizontal = 0,
297
+ LeftStickVertical = 1,
298
+ RightStickHorizontal = 2,
299
+ RightStickVertical = 3
300
+ }
@@ -0,0 +1,10 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ /**
4
+ * The interface for controllers
5
+ */
6
+ export interface Controller {
7
+ currentState: Gamepad;
8
+ prevState: Gamepad;
9
+ id: number | undefined;
10
+ }
@@ -0,0 +1,192 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { MouseController } from './MouseController';
4
+ import { Logger } from '../Logger/Logger';
5
+ import { IMouseEvents } from './IMouseEvents';
6
+
7
+ /**
8
+ * Video Player mouse Hover handler
9
+ */
10
+ export class HoveringMouseEvents implements IMouseEvents {
11
+ mouseController: MouseController;
12
+
13
+ /**
14
+ * @param mouseController - Mouse Controller instance
15
+ */
16
+ constructor(mouseController: MouseController) {
17
+ this.mouseController = mouseController;
18
+ }
19
+
20
+ /**
21
+ * Unregister event handlers
22
+ */
23
+ unregisterMouseEvents(): void {
24
+ // empty for HoveringMouseEvents implementation
25
+ }
26
+
27
+ /**
28
+ * Handle the mouse move event, sends the mouse data to the UE Instance
29
+ * @param mouseEvent - Mouse Event
30
+ */
31
+ updateMouseMovePosition(mouseEvent: MouseEvent) {
32
+ if (!this.mouseController.videoElementProvider.isVideoReady()) {
33
+ return;
34
+ }
35
+ Logger.Log(Logger.GetStackTrace(), 'MouseMove', 6);
36
+ const coord =
37
+ this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(
38
+ mouseEvent.offsetX,
39
+ mouseEvent.offsetY
40
+ );
41
+ const delta =
42
+ this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(
43
+ mouseEvent.movementX,
44
+ mouseEvent.movementY
45
+ );
46
+ const toStreamerHandlers =
47
+ this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;
48
+ toStreamerHandlers.get('MouseMove')([
49
+ coord.x,
50
+ coord.y,
51
+ delta.x,
52
+ delta.y
53
+ ]);
54
+ mouseEvent.preventDefault();
55
+ }
56
+
57
+ /**
58
+ * Handle the mouse Down event, sends the mouse data to the UE Instance
59
+ * @param mouseEvent - Mouse Event
60
+ */
61
+ handleMouseDown(mouseEvent: MouseEvent) {
62
+ if (!this.mouseController.videoElementProvider.isVideoReady()) {
63
+ return;
64
+ }
65
+ Logger.Log(Logger.GetStackTrace(), 'onMouse Down', 6);
66
+ const coord =
67
+ this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(
68
+ mouseEvent.offsetX,
69
+ mouseEvent.offsetY
70
+ );
71
+ const toStreamerHandlers =
72
+ this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;
73
+ toStreamerHandlers.get('MouseDown')([
74
+ mouseEvent.button,
75
+ coord.x,
76
+ coord.y
77
+ ]);
78
+ mouseEvent.preventDefault();
79
+ }
80
+
81
+ /**
82
+ * Handle the mouse Up event, sends the mouse data to the UE Instance
83
+ * @param mouseEvent - Mouse Event
84
+ */
85
+ handleMouseUp(mouseEvent: MouseEvent) {
86
+ if (!this.mouseController.videoElementProvider.isVideoReady()) {
87
+ return;
88
+ }
89
+ Logger.Log(Logger.GetStackTrace(), 'onMouse Up', 6);
90
+ const coord =
91
+ this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(
92
+ mouseEvent.offsetX,
93
+ mouseEvent.offsetY
94
+ );
95
+ const toStreamerHandlers =
96
+ this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;
97
+ toStreamerHandlers.get('MouseUp')([
98
+ mouseEvent.button,
99
+ coord.x,
100
+ coord.y
101
+ ]);
102
+ mouseEvent.preventDefault();
103
+ }
104
+
105
+ /**
106
+ * Consumes the mouse context event. The UE instance has no equivalent and doesn't need to be informed.
107
+ * @param mouseEvent - Mouse Event
108
+ */
109
+ handleContextMenu(mouseEvent: MouseEvent) {
110
+ if (!this.mouseController.videoElementProvider.isVideoReady()) {
111
+ return;
112
+ }
113
+ mouseEvent.preventDefault();
114
+ }
115
+
116
+ /**
117
+ * Handle the mouse wheel event, sends the mouse wheel data to the UE Instance
118
+ * @param wheelEvent - Mouse Event
119
+ */
120
+ handleMouseWheel(wheelEvent: WheelEvent) {
121
+ if (!this.mouseController.videoElementProvider.isVideoReady()) {
122
+ return;
123
+ }
124
+ const coord =
125
+ this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(
126
+ wheelEvent.offsetX,
127
+ wheelEvent.offsetY
128
+ );
129
+ const toStreamerHandlers =
130
+ this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;
131
+ toStreamerHandlers.get('MouseWheel')([
132
+ wheelEvent.wheelDelta,
133
+ coord.x,
134
+ coord.y
135
+ ]);
136
+ wheelEvent.preventDefault();
137
+ }
138
+
139
+ /**
140
+ * Handle the mouse double click event, sends the mouse data to the UE Instance
141
+ * @param mouseEvent - Mouse Event
142
+ */
143
+ handleMouseDouble(mouseEvent: MouseEvent) {
144
+ if (!this.mouseController.videoElementProvider.isVideoReady()) {
145
+ return;
146
+ }
147
+ const coord =
148
+ this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(
149
+ mouseEvent.offsetX,
150
+ mouseEvent.offsetY
151
+ );
152
+ const toStreamerHandlers =
153
+ this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;
154
+ toStreamerHandlers.get('MouseDouble')([
155
+ mouseEvent.button,
156
+ coord.x,
157
+ coord.y
158
+ ]);
159
+ }
160
+
161
+ /**
162
+ * Handle the press mouse buttons event, sends the mouse data to the UE Instance
163
+ * @param mouseEvent - Mouse Event
164
+ */
165
+ handlePressMouseButtons(mouseEvent: MouseEvent) {
166
+ if (!this.mouseController.videoElementProvider.isVideoReady()) {
167
+ return;
168
+ }
169
+ Logger.Log(Logger.GetStackTrace(), 'onMouse press', 6);
170
+ this.mouseController.pressMouseButtons(
171
+ mouseEvent.buttons,
172
+ mouseEvent.offsetX,
173
+ mouseEvent.offsetY
174
+ );
175
+ }
176
+
177
+ /**
178
+ * Handle the release mouse buttons event, sends the mouse data to the UE Instance
179
+ * @param mouseEvent - Mouse Event
180
+ */
181
+ handleReleaseMouseButtons(mouseEvent: MouseEvent) {
182
+ if (!this.mouseController.videoElementProvider.isVideoReady()) {
183
+ return;
184
+ }
185
+ Logger.Log(Logger.GetStackTrace(), 'onMouse release', 6);
186
+ this.mouseController.releaseMouseButtons(
187
+ mouseEvent.buttons,
188
+ mouseEvent.offsetX,
189
+ mouseEvent.offsetY
190
+ );
191
+ }
192
+ }