@epicgames-ps/lib-pixelstreamingfrontend-ue5.5 0.0.5

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 (138) 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/dist/lib-pixelstreamingfrontend.esm.js +1 -0
  7. package/dist/lib-pixelstreamingfrontend.js +1 -0
  8. package/jest.config.js +18 -0
  9. package/package.json +48 -0
  10. package/readme.md +15 -0
  11. package/src/AFK/AFKController.test.ts +162 -0
  12. package/src/AFK/AFKController.ts +158 -0
  13. package/src/Config/Config.test.ts +222 -0
  14. package/src/Config/Config.ts +970 -0
  15. package/src/Config/SettingBase.ts +65 -0
  16. package/src/Config/SettingFlag.ts +99 -0
  17. package/src/Config/SettingNumber.ts +111 -0
  18. package/src/Config/SettingOption.ts +124 -0
  19. package/src/Config/SettingText.ts +82 -0
  20. package/src/DataChannel/DataChannelController.ts +138 -0
  21. package/src/DataChannel/DataChannelLatencyTestController.ts +129 -0
  22. package/src/DataChannel/DataChannelLatencyTestResults.ts +67 -0
  23. package/src/DataChannel/DataChannelSender.ts +59 -0
  24. package/src/DataChannel/InitialSettings.ts +61 -0
  25. package/src/DataChannel/LatencyTestResults.ts +76 -0
  26. package/src/FreezeFrame/FreezeFrame.ts +114 -0
  27. package/src/FreezeFrame/FreezeFrameController.ts +114 -0
  28. package/src/Inputs/FakeTouchController.ts +199 -0
  29. package/src/Inputs/GamepadController.ts +314 -0
  30. package/src/Inputs/GamepadTypes.ts +10 -0
  31. package/src/Inputs/HoveringMouseEvents.ts +192 -0
  32. package/src/Inputs/IMouseEvents.ts +64 -0
  33. package/src/Inputs/ITouchController.ts +29 -0
  34. package/src/Inputs/InputClassesFactory.ts +140 -0
  35. package/src/Inputs/KeyboardController.ts +354 -0
  36. package/src/Inputs/LockedMouseEvents.ts +287 -0
  37. package/src/Inputs/MouseButtons.ts +25 -0
  38. package/src/Inputs/MouseController.ts +362 -0
  39. package/src/Inputs/SpecialKeyCodes.ts +16 -0
  40. package/src/Inputs/TouchController.ts +208 -0
  41. package/src/Inputs/XRGamepadController.ts +126 -0
  42. package/src/PeerConnectionController/AggregatedStats.ts +311 -0
  43. package/src/PeerConnectionController/CandidatePairStats.ts +17 -0
  44. package/src/PeerConnectionController/CandidateStat.ts +13 -0
  45. package/src/PeerConnectionController/CodecStats.ts +19 -0
  46. package/src/PeerConnectionController/DataChannelStats.ts +17 -0
  47. package/src/PeerConnectionController/InboundRTPStats.ts +154 -0
  48. package/src/PeerConnectionController/InboundTrackStats.ts +34 -0
  49. package/src/PeerConnectionController/OutBoundRTPStats.ts +26 -0
  50. package/src/PeerConnectionController/PeerConnectionController.ts +563 -0
  51. package/src/PeerConnectionController/SessionStats.ts +10 -0
  52. package/src/PeerConnectionController/StreamStats.ts +11 -0
  53. package/src/PixelStreaming/PixelStreaming.test.ts +626 -0
  54. package/src/PixelStreaming/PixelStreaming.ts +851 -0
  55. package/src/UI/OnScreenKeyboard.ts +97 -0
  56. package/src/UeInstanceMessage/ResponseController.ts +47 -0
  57. package/src/UeInstanceMessage/SendMessageController.ts +154 -0
  58. package/src/UeInstanceMessage/StreamMessageController.ts +233 -0
  59. package/src/UeInstanceMessage/ToStreamerMessagesController.ts +62 -0
  60. package/src/Util/CoordinateConverter.ts +289 -0
  61. package/src/Util/EventEmitter.ts +611 -0
  62. package/src/Util/EventListenerTracker.ts +29 -0
  63. package/src/Util/FileUtil.ts +140 -0
  64. package/src/Util/RTCUtils.ts +41 -0
  65. package/src/Util/WebGLUtils.ts +49 -0
  66. package/src/Util/WebXRUtils.ts +25 -0
  67. package/src/VideoPlayer/StreamController.ts +89 -0
  68. package/src/VideoPlayer/VideoPlayer.ts +246 -0
  69. package/src/WebRtcPlayer/WebRtcPlayerController.ts +2158 -0
  70. package/src/WebXR/WebXRController.ts +319 -0
  71. package/src/__test__/mockMediaStream.ts +124 -0
  72. package/src/__test__/mockRTCPeerConnection.ts +347 -0
  73. package/src/__test__/mockRTCRtpReceiver.ts +22 -0
  74. package/src/__test__/mockWebSocket.ts +136 -0
  75. package/src/pixelstreamingfrontend.ts +46 -0
  76. package/tsconfig.jest.json +8 -0
  77. package/tsconfig.json +24 -0
  78. package/types/AFK/AFKController.d.ts +39 -0
  79. package/types/Config/Config.d.ts +218 -0
  80. package/types/Config/SettingBase.d.ts +30 -0
  81. package/types/Config/SettingFlag.d.ts +33 -0
  82. package/types/Config/SettingNumber.d.ts +45 -0
  83. package/types/Config/SettingOption.d.ts +43 -0
  84. package/types/Config/SettingText.d.ts +29 -0
  85. package/types/DataChannel/DataChannelController.d.ts +59 -0
  86. package/types/DataChannel/DataChannelLatencyTestController.d.ts +26 -0
  87. package/types/DataChannel/DataChannelLatencyTestResults.d.ts +46 -0
  88. package/types/DataChannel/DataChannelSender.d.ts +21 -0
  89. package/types/DataChannel/InitialSettings.d.ts +44 -0
  90. package/types/DataChannel/LatencyTestResults.d.ts +31 -0
  91. package/types/FreezeFrame/FreezeFrame.d.ts +36 -0
  92. package/types/FreezeFrame/FreezeFrameController.d.ts +37 -0
  93. package/types/Inputs/FakeTouchController.d.ts +61 -0
  94. package/types/Inputs/GamepadController.d.ts +85 -0
  95. package/types/Inputs/GamepadTypes.d.ts +8 -0
  96. package/types/Inputs/HoveringMouseEvents.d.ts +56 -0
  97. package/types/Inputs/IMouseEvents.d.ts +53 -0
  98. package/types/Inputs/ITouchController.d.ts +24 -0
  99. package/types/Inputs/InputClassesFactory.d.ts +54 -0
  100. package/types/Inputs/KeyboardController.d.ts +62 -0
  101. package/types/Inputs/LockedMouseEvents.d.ts +80 -0
  102. package/types/Inputs/MouseButtons.d.ts +22 -0
  103. package/types/Inputs/MouseController.d.ts +75 -0
  104. package/types/Inputs/SpecialKeyCodes.d.ts +14 -0
  105. package/types/Inputs/TouchController.d.ts +53 -0
  106. package/types/Inputs/XRGamepadController.d.ts +15 -0
  107. package/types/PeerConnectionController/AggregatedStats.d.ts +77 -0
  108. package/types/PeerConnectionController/CandidatePairStats.d.ts +15 -0
  109. package/types/PeerConnectionController/CandidateStat.d.ts +11 -0
  110. package/types/PeerConnectionController/CodecStats.d.ts +14 -0
  111. package/types/PeerConnectionController/DataChannelStats.d.ts +15 -0
  112. package/types/PeerConnectionController/InboundRTPStats.d.ts +141 -0
  113. package/types/PeerConnectionController/InboundTrackStats.d.ts +32 -0
  114. package/types/PeerConnectionController/OutBoundRTPStats.d.ts +23 -0
  115. package/types/PeerConnectionController/PeerConnectionController.d.ts +132 -0
  116. package/types/PeerConnectionController/SessionStats.d.ts +8 -0
  117. package/types/PeerConnectionController/StreamStats.d.ts +9 -0
  118. package/types/PixelStreaming/PixelStreaming.d.ts +259 -0
  119. package/types/UI/OnScreenKeyboard.d.ts +31 -0
  120. package/types/UeInstanceMessage/ResponseController.d.ts +19 -0
  121. package/types/UeInstanceMessage/SendMessageController.d.ts +18 -0
  122. package/types/UeInstanceMessage/StreamMessageController.d.ts +29 -0
  123. package/types/UeInstanceMessage/ToStreamerMessagesController.d.ts +32 -0
  124. package/types/Util/CoordinateConverter.d.ts +100 -0
  125. package/types/Util/EventEmitter.d.ts +422 -0
  126. package/types/Util/EventListenerTracker.d.ts +14 -0
  127. package/types/Util/FileUtil.d.ts +32 -0
  128. package/types/Util/RTCUtils.d.ts +8 -0
  129. package/types/Util/WebGLUtils.d.ts +4 -0
  130. package/types/Util/WebXRUtils.d.ts +9 -0
  131. package/types/VideoPlayer/StreamController.d.ts +24 -0
  132. package/types/VideoPlayer/VideoPlayer.d.ts +78 -0
  133. package/types/WebRtcPlayer/WebRtcPlayerController.d.ts +377 -0
  134. package/types/WebXR/WebXRController.d.ts +26 -0
  135. package/types/pixelstreamingfrontend.d.ts +22 -0
  136. package/webpack.common.js +35 -0
  137. package/webpack.dev.js +35 -0
  138. package/webpack.prod.js +36 -0
@@ -0,0 +1,347 @@
1
+ export interface MockRTCPeerConnectionSpyFunctions {
2
+ constructorSpy: null | ((config: RTCConfiguration) => void);
3
+ closeSpy: null | (() => void);
4
+ setRemoteDescriptionSpy: null | ((description: RTCSessionDescriptionInit) => void);
5
+ setLocalDescriptionSpy: null | ((description: RTCLocalSessionDescriptionInit) => void);
6
+ createAnswerSpy: null | (() => void);
7
+ addTransceiverSpy: null | ((trackOrKind: string | MediaStreamTrack, init?: RTCRtpTransceiverInit | undefined) => void);
8
+ addIceCandidateSpy: null | ((candidate: RTCIceCandidateInit) => void);
9
+ sendDataSpy: null | ((data: ArrayBuffer) => void);
10
+ }
11
+
12
+ export interface MockRTCPeerConnectionTriggerFunctions {
13
+ triggerIceConnectionStateChange: null | ((state: RTCIceConnectionState) => void);
14
+ triggerOnTrack: null | ((data: RTCTrackEventInit) => void);
15
+ triggerOnIceCandidate: null | ((data: RTCPeerConnectionIceEventInit) => void);
16
+ triggerOnDataChannel: null | ((data: RTCDataChannelEventInit) => void);
17
+ }
18
+
19
+ const spyFunctions: MockRTCPeerConnectionSpyFunctions = {
20
+ constructorSpy: null,
21
+ closeSpy: null,
22
+ setRemoteDescriptionSpy: null,
23
+ setLocalDescriptionSpy: null,
24
+ createAnswerSpy: null,
25
+ addTransceiverSpy: null,
26
+ addIceCandidateSpy: null,
27
+ sendDataSpy: null,
28
+ };
29
+
30
+ const triggerFunctions: MockRTCPeerConnectionTriggerFunctions = {
31
+ triggerIceConnectionStateChange: null,
32
+ triggerOnTrack: null,
33
+ triggerOnIceCandidate: null,
34
+ triggerOnDataChannel: null
35
+ };
36
+
37
+ export class MockRTCPeerConnectionImpl implements RTCPeerConnection {
38
+
39
+ canTrickleIceCandidates: boolean | null;
40
+ connectionState: RTCPeerConnectionState;
41
+ currentLocalDescription: RTCSessionDescription | null;
42
+ currentRemoteDescription: RTCSessionDescription | null;
43
+ iceConnectionState: RTCIceConnectionState;
44
+ iceGatheringState: RTCIceGatheringState;
45
+ localDescription: RTCSessionDescription | null;
46
+ pendingLocalDescription: RTCSessionDescription | null;
47
+ pendingRemoteDescription: RTCSessionDescription | null;
48
+ remoteDescription: RTCSessionDescription | null;
49
+ sctp: RTCSctpTransport | null;
50
+ signalingState: RTCSignalingState;
51
+ _dataChannels: RTCDataChannel[] = [];
52
+
53
+ constructor(config: RTCConfiguration) {
54
+ this.connectionState = "new";
55
+ this.iceConnectionState = "new";
56
+ spyFunctions.constructorSpy?.(config);
57
+ triggerFunctions.triggerIceConnectionStateChange = this.triggerIceConnectionStateChange.bind(this);
58
+ triggerFunctions.triggerOnTrack = this.triggerOnTrack.bind(this);
59
+ triggerFunctions.triggerOnIceCandidate = this.triggerOnIceCandidate.bind(this);
60
+ triggerFunctions.triggerOnDataChannel =
61
+ this.triggerOnDataChannel.bind(this);
62
+ }
63
+
64
+ onconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
65
+ ondatachannel: ((this: RTCPeerConnection, ev: RTCDataChannelEvent) => any) | null;
66
+ onicecandidate: ((this: RTCPeerConnection, ev: RTCPeerConnectionIceEvent) => any) | null;
67
+ onicecandidateerror: ((this: RTCPeerConnection, ev: Event) => any) | null;
68
+ oniceconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
69
+ onicegatheringstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
70
+ onnegotiationneeded: ((this: RTCPeerConnection, ev: Event) => any) | null;
71
+ onsignalingstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
72
+ ontrack: ((this: RTCPeerConnection, ev: RTCTrackEvent) => any) | null;
73
+ addIceCandidate(candidate?: RTCIceCandidateInit | undefined): Promise<void>;
74
+ addIceCandidate(candidate: RTCIceCandidateInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;
75
+ addIceCandidate(candidate?: unknown, successCallback?: unknown, failureCallback?: unknown): Promise<void> {
76
+ if (this.iceConnectionState !== "connected" && this.iceConnectionState !== "completed") {
77
+ this.iceConnectionState = "checking";
78
+ }
79
+ this.oniceconnectionstatechange?.(new Event("iceconnectionstatechange"));
80
+ spyFunctions.addIceCandidateSpy?.(candidate as RTCIceCandidateInit);
81
+ return Promise.resolve();
82
+ }
83
+ addTrack(track: MediaStreamTrack, ...streams: MediaStream[]): RTCRtpSender {
84
+ throw new Error("Method not implemented.");
85
+ }
86
+ addTransceiver(trackOrKind: string | MediaStreamTrack, init?: RTCRtpTransceiverInit | undefined): RTCRtpTransceiver {
87
+ spyFunctions.addTransceiverSpy?.(trackOrKind, init);
88
+ return {} as RTCRtpTransceiver;
89
+ }
90
+ createAnswer(options?: RTCAnswerOptions | undefined): Promise<RTCSessionDescriptionInit>;
91
+ createAnswer(successCallback: RTCSessionDescriptionCallback, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;
92
+ createAnswer(successCallback?: unknown, failureCallback?: unknown): Promise<void> | Promise<RTCSessionDescriptionInit> {
93
+ spyFunctions.createAnswerSpy?.();
94
+ const res: RTCSessionDescriptionInit = {
95
+ type: "answer",
96
+ sdp: "v=0\r\no=- 5791786663981007547 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1 2\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=video 9 UDP/TLS/RTP/SAVPF 96 98\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:z0li\r\na=ice-pwd:DkbG5Q3dFSIygDc47cms4TGA\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F9:5B:3C:AB:89:88:0E:1B:2E:63:B3:D2:B8:92:59:E2:3A:46:B6:85:09:F4:50:0E:72:4F:9F:70:6D:5F:BD:1A\r\na=setup:active\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:3 urn:3gpp:video-orientation\r\na=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\na=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\na=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\na=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=recvonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:96 H264/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 transport-cc\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:98 H264/90000\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 transport-cc\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=fmtp:98 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 63 110\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:z0li\r\na=ice-pwd:DkbG5Q3dFSIygDc47cms4TGA\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F9:5B:3C:AB:89:88:0E:1B:2E:63:B3:D2:B8:92:59:E2:3A:46:B6:85:09:F4:50:0E:72:4F:9F:70:6D:5F:BD:1A\r\na=setup:active\r\na=mid:1\r\na=extmap:14 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=recvonly\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:63 red/48000/2\r\na=fmtp:63 111/111\r\na=rtpmap:110 telephone-event/48000\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:z0li\r\na=ice-pwd:DkbG5Q3dFSIygDc47cms4TGA\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F9:5B:3C:AB:89:88:0E:1B:2E:63:B3:D2:B8:92:59:E2:3A:46:B6:85:09:F4:50:0E:72:4F:9F:70:6D:5F:BD:1A\r\na=setup:active\r\na=mid:2\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n"
97
+ };
98
+ return Promise.resolve(res);
99
+ }
100
+ createDataChannel(label: string, dataChannelDict?: RTCDataChannelInit | undefined): RTCDataChannel {
101
+ const dataChannel = new RTCDataChannel();
102
+ this._dataChannels.push(dataChannel);
103
+ return dataChannel;
104
+ }
105
+ createOffer(options?: RTCOfferOptions | undefined): Promise<RTCSessionDescriptionInit>;
106
+ createOffer(successCallback: RTCSessionDescriptionCallback, failureCallback: RTCPeerConnectionErrorCallback, options?: RTCOfferOptions | undefined): Promise<void>;
107
+ createOffer(successCallback?: unknown, failureCallback?: unknown, options?: unknown): Promise<void> | Promise<RTCSessionDescriptionInit> {
108
+ throw new Error("Method not implemented.");
109
+ }
110
+ getConfiguration(): RTCConfiguration {
111
+ throw new Error("Method not implemented.");
112
+ }
113
+ getReceivers(): RTCRtpReceiver[] {
114
+ throw new Error("Method not implemented.");
115
+ }
116
+ getSenders(): RTCRtpSender[] {
117
+ throw new Error("Method not implemented.");
118
+ }
119
+ getStats(selector?: MediaStreamTrack | null | undefined): Promise<RTCStatsReport> {
120
+ const stats = {
121
+ forEach: function (callbackfn: (value: any) => void): void {
122
+ callbackfn({
123
+ type: 'candidate-pair',
124
+ bytesReceived: 123,
125
+ });
126
+ callbackfn({
127
+ type: 'local-candidate',
128
+ address: 'mock-address',
129
+ });
130
+ },
131
+ };
132
+ return Promise.resolve(stats as RTCStatsReport);
133
+ }
134
+ getTransceivers(): RTCRtpTransceiver[] {
135
+ return [];
136
+ }
137
+ removeTrack(sender: RTCRtpSender): void {
138
+ throw new Error("Method not implemented.");
139
+ }
140
+ restartIce(): void {
141
+ throw new Error("Method not implemented.");
142
+ }
143
+ setConfiguration(configuration?: RTCConfiguration | undefined): void {
144
+ throw new Error("Method not implemented.");
145
+ }
146
+ setLocalDescription(description?: RTCLocalSessionDescriptionInit | undefined): Promise<void>;
147
+ setLocalDescription(description: RTCLocalSessionDescriptionInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;
148
+ setLocalDescription(description?: unknown, successCallback?: unknown, failureCallback?: unknown): Promise<void> {
149
+ spyFunctions.setLocalDescriptionSpy?.(description as RTCLocalSessionDescriptionInit);
150
+ return Promise.resolve();
151
+ }
152
+ setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void>;
153
+ setRemoteDescription(description: RTCSessionDescriptionInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;
154
+ setRemoteDescription(description: unknown, successCallback?: unknown, failureCallback?: unknown): Promise<void> {
155
+ spyFunctions.setRemoteDescriptionSpy?.(description as RTCSessionDescriptionInit);
156
+ return Promise.resolve();
157
+ }
158
+ addEventListener<K extends keyof RTCPeerConnectionEventMap>(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void;
159
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void;
160
+ addEventListener(type: unknown, listener: unknown, options?: unknown): void {
161
+ throw new Error("Method not implemented.");
162
+ }
163
+ removeEventListener<K extends keyof RTCPeerConnectionEventMap>(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void;
164
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void;
165
+ removeEventListener(type: unknown, listener: unknown, options?: unknown): void {
166
+ throw new Error("Method not implemented.");
167
+ }
168
+ dispatchEvent(event: Event): boolean {
169
+ throw new Error("Method not implemented.");
170
+ }
171
+ static generateCertificate(keygenAlgorithm: AlgorithmIdentifier): Promise<RTCCertificate> {
172
+ throw new Error("Method not implemented.");
173
+ }
174
+
175
+ close(): void {
176
+ this.connectionState = "closed";
177
+ this.iceConnectionState = "closed";
178
+ this.onconnectionstatechange?.(new Event(this.connectionState));
179
+ this.oniceconnectionstatechange?.(new Event(this.iceConnectionState));
180
+ this._dataChannels.forEach((channel) => channel.close());
181
+ spyFunctions.closeSpy?.();
182
+ }
183
+
184
+ triggerIceConnectionStateChange(state: RTCIceConnectionState) {
185
+ this.iceConnectionState = state;
186
+ const event = new Event(state);
187
+ this.oniceconnectionstatechange?.(event);
188
+ }
189
+
190
+ triggerOnTrack(data: RTCTrackEventInit) {
191
+ const event = new RTCTrackEvent('track', data);
192
+ this.ontrack?.(event);
193
+ }
194
+
195
+ triggerOnIceCandidate(data: RTCPeerConnectionIceEventInit) {
196
+ const event = new RTCPeerConnectionIceEvent('icecandidate', data);
197
+ this.onicecandidate?.(event);
198
+ }
199
+
200
+ triggerOnDataChannel(data: RTCDataChannelEventInit) {
201
+ this._dataChannels.push(data.channel);
202
+ const event = new RTCDataChannelEvent('datachannel', data);
203
+ this.ondatachannel?.(event);
204
+ }
205
+ }
206
+
207
+ export class MockRTCIceCandidateImpl implements RTCIceCandidate {
208
+ address: string | null;
209
+ candidate: string;
210
+ component: RTCIceComponent | null;
211
+ foundation: string | null;
212
+ port: number | null;
213
+ priority: number | null;
214
+ protocol: RTCIceProtocol | null;
215
+ relatedAddress: string | null;
216
+ relatedPort: number | null;
217
+ sdpMLineIndex: number | null;
218
+ sdpMid: string | null;
219
+ tcpType: RTCIceTcpCandidateType | null;
220
+ type: RTCIceCandidateType | null;
221
+ usernameFragment: string | null;
222
+
223
+ constructor(options?: RTCIceCandidateInit) {
224
+ this.candidate = options?.candidate || "";
225
+ this.sdpMid = options?.sdpMid || null;
226
+ this.sdpMLineIndex = options?.sdpMLineIndex || null;
227
+ this.usernameFragment = options?.usernameFragment || null;
228
+ }
229
+
230
+ toJSON(): RTCIceCandidateInit {
231
+ throw new Error("Method not implemented.");
232
+ }
233
+ }
234
+
235
+ export class MockRTCDataChannelImpl implements RTCDataChannel {
236
+ binaryType: BinaryType;
237
+ bufferedAmount: number;
238
+ bufferedAmountLowThreshold: number;
239
+ id: number | null;
240
+ label: string;
241
+ maxPacketLifeTime: number | null;
242
+ maxRetransmits: number | null;
243
+ negotiated: boolean;
244
+ ordered: boolean;
245
+ protocol: string;
246
+ readyState: RTCDataChannelState;
247
+
248
+ constructor() {
249
+ this.readyState = "open";
250
+ }
251
+
252
+ onbufferedamountlow: ((this: RTCDataChannel, ev: Event) => any) | null;
253
+ onclose: ((this: RTCDataChannel, ev: Event) => any) | null;
254
+ onclosing: ((this: RTCDataChannel, ev: Event) => any) | null;
255
+ onerror: ((this: RTCDataChannel, ev: Event) => any) | null;
256
+ onmessage: ((this: RTCDataChannel, ev: MessageEvent<any>) => any) | null;
257
+ onopen: ((this: RTCDataChannel, ev: Event) => any) | null;
258
+ close(): void {
259
+ this.onclose?.(new Event('close'));
260
+ }
261
+ send(data: string): void;
262
+ send(data: Blob): void;
263
+ send(data: ArrayBuffer): void;
264
+ send(data: ArrayBufferView): void;
265
+ send(data: unknown): void {
266
+ spyFunctions.sendDataSpy?.(data as ArrayBuffer);
267
+ }
268
+ addEventListener<K extends keyof RTCDataChannelEventMap>(type: K, listener: (this: RTCDataChannel, ev: RTCDataChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void;
269
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void;
270
+ addEventListener(type: unknown, listener: unknown, options?: unknown): void {
271
+ throw new Error("Method not implemented.");
272
+ }
273
+ removeEventListener<K extends keyof RTCDataChannelEventMap>(type: K, listener: (this: RTCDataChannel, ev: RTCDataChannelEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void;
274
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void;
275
+ removeEventListener(type: unknown, listener: unknown, options?: unknown): void {
276
+ throw new Error("Method not implemented.");
277
+ }
278
+ dispatchEvent(event: Event): boolean {
279
+ if (event.type === 'message') {
280
+ this.onmessage?.(event as MessageEvent);
281
+ }
282
+ return true;
283
+ }
284
+ }
285
+
286
+ export class MockRTCDataChannelEventImpl extends Event implements RTCDataChannelEvent {
287
+ channel: RTCDataChannel;
288
+ constructor(name: string, data: RTCDataChannelEventInit) {
289
+ super(name, data);
290
+ this.channel = data.channel;
291
+ }
292
+ }
293
+
294
+ export class MockRTCTrackEventImpl extends Event implements RTCTrackEvent {
295
+ receiver: RTCRtpReceiver;
296
+ streams: readonly MediaStream[];
297
+ track: MediaStreamTrack;
298
+ transceiver: RTCRtpTransceiver;
299
+ constructor(name: string, data: RTCTrackEventInit) {
300
+ super(name, data);
301
+ this.receiver = data.receiver;
302
+ this.streams = data.streams || [];
303
+ this.track = data.track;
304
+ this.transceiver = data.transceiver;
305
+ }
306
+ }
307
+
308
+ const originalRTCPeerConnection = global.RTCPeerConnection;
309
+ const originalRTCIceCandidate = global.RTCIceCandidate;
310
+ const originalRTCDataChannel = global.RTCDataChannel;
311
+ const originalRTCDataChannelEvent = global.RTCDataChannelEvent;
312
+ const originalRTCTrackEvent = global.RTCTrackEvent;
313
+ export const mockRTCPeerConnection = (): [
314
+ MockRTCPeerConnectionSpyFunctions,
315
+ MockRTCPeerConnectionTriggerFunctions
316
+ ] => {
317
+ spyFunctions.constructorSpy = jest.fn();
318
+ spyFunctions.closeSpy = jest.fn();
319
+ spyFunctions.setRemoteDescriptionSpy = jest.fn();
320
+ spyFunctions.setLocalDescriptionSpy = jest.fn();
321
+ spyFunctions.createAnswerSpy = jest.fn();
322
+ spyFunctions.addTransceiverSpy = jest.fn();
323
+ spyFunctions.addIceCandidateSpy = jest.fn();
324
+ spyFunctions.sendDataSpy = jest.fn();
325
+ global.RTCPeerConnection = MockRTCPeerConnectionImpl;
326
+ global.RTCIceCandidate = MockRTCIceCandidateImpl;
327
+ global.RTCDataChannel = MockRTCDataChannelImpl;
328
+ global.RTCDataChannelEvent = MockRTCDataChannelEventImpl;
329
+ global.RTCTrackEvent = MockRTCTrackEventImpl;
330
+ return [spyFunctions, triggerFunctions];
331
+ };
332
+
333
+ export const unmockRTCPeerConnection = () => {
334
+ global.RTCPeerConnection = originalRTCPeerConnection;
335
+ global.RTCIceCandidate = originalRTCIceCandidate;
336
+ global.RTCDataChannel = originalRTCDataChannel;
337
+ global.RTCDataChannelEvent = originalRTCDataChannelEvent;
338
+ global.RTCTrackEvent = originalRTCTrackEvent;
339
+ spyFunctions.constructorSpy = null;
340
+ spyFunctions.closeSpy = null;
341
+ spyFunctions.setRemoteDescriptionSpy = null;
342
+ spyFunctions.setLocalDescriptionSpy = null;
343
+ spyFunctions.createAnswerSpy = null;
344
+ spyFunctions.addTransceiverSpy = null;
345
+ spyFunctions.addIceCandidateSpy = null;
346
+ spyFunctions.sendDataSpy = null;
347
+ };
@@ -0,0 +1,22 @@
1
+ export const mockRTCRtpReceiverImpl = {
2
+ prototype: jest.fn(),
3
+ getCapabilities: () => ({
4
+ codecs: [
5
+ {
6
+ clockRate: 60,
7
+ mimeType: "testMimeType",
8
+ sdpFmtpLine: "AV1"
9
+ }
10
+ ] as RTCRtpCodecCapability[],
11
+ headerExtensions: [] as RTCRtpHeaderExtensionCapability[]
12
+ })
13
+ } as any as typeof global.RTCRtpReceiver;
14
+
15
+ const originalRTCRtpReceiver = global.RTCRtpReceiver;
16
+ export const mockRTCRtpReceiver = () => {
17
+ global.RTCRtpReceiver = mockRTCRtpReceiverImpl;
18
+ }
19
+
20
+ export const unmockRTCRtpReceiver = () => {
21
+ global.RTCRtpReceiver = originalRTCRtpReceiver;
22
+ }
@@ -0,0 +1,136 @@
1
+ export interface MockWebSocketSpyFunctions {
2
+ constructorSpy: null | ((url: string) => void);
3
+ openSpy: null | ((event: Event) => void);
4
+ errorSpy: null | ((event: Event) => void);
5
+ closeSpy: null | ((event: CloseEvent) => void);
6
+ messageSpy: null | ((event: MessageEvent) => void);
7
+ messageBinarySpy: null | ((event: MessageEvent) => void);
8
+ sendSpy: null | ((data: string | Blob | ArrayBufferView | ArrayBufferLike) => void);
9
+ }
10
+
11
+ export interface MockWebSocketTriggerFunctions {
12
+ triggerOnOpen: null | (() => void);
13
+ triggerOnError: null | (() => void);
14
+ triggerOnClose: null | ((closeReason?: CloseEventInit) => void);
15
+ triggerOnMessage: null | ((message?: object) => void);
16
+ triggerOnMessageBinary: null | ((message?: Blob) => void);
17
+ triggerRemoteClose: null | ((code?: number, reason?: string) => void);
18
+ }
19
+
20
+ const spyFunctions: MockWebSocketSpyFunctions = {
21
+ constructorSpy: null,
22
+ openSpy: null,
23
+ errorSpy: null,
24
+ closeSpy: null,
25
+ messageSpy: null,
26
+ messageBinarySpy: null,
27
+ sendSpy: null
28
+ };
29
+
30
+ const triggerFunctions: MockWebSocketTriggerFunctions = {
31
+ triggerOnOpen: null,
32
+ triggerOnError: null,
33
+ triggerOnClose: null,
34
+ triggerOnMessage: null,
35
+ triggerOnMessageBinary: null,
36
+ triggerRemoteClose: null
37
+ };
38
+
39
+ export class MockWebSocketImpl extends WebSocket {
40
+ _readyState: number;
41
+
42
+ constructor(url: string | URL, protocols?: string | string[]) {
43
+ super(url, protocols);
44
+ this._readyState = this.OPEN;
45
+ spyFunctions.constructorSpy?.(this.url);
46
+ triggerFunctions.triggerOnOpen = this.triggerOnOpen.bind(this);
47
+ triggerFunctions.triggerOnError = this.triggerOnError.bind(this);
48
+ triggerFunctions.triggerOnClose = this.triggerOnClose.bind(this);
49
+ triggerFunctions.triggerOnMessage = this.triggerOnMessage.bind(this);
50
+ triggerFunctions.triggerOnMessageBinary = this.triggerOnMessageBinary.bind(this);
51
+ triggerFunctions.triggerRemoteClose = this.triggerRemoteClose.bind(this);
52
+ }
53
+
54
+ get readyState() {
55
+ return this._readyState;
56
+ }
57
+
58
+ close(code?: number | undefined, reason?: string | undefined): void {
59
+ super.close(code, reason);
60
+ this._readyState = this.CLOSED;
61
+ this.triggerOnClose({ code, reason });
62
+ }
63
+
64
+ send(data: string | Blob | ArrayBufferView | ArrayBufferLike): void {
65
+ spyFunctions.sendSpy?.(data);
66
+ }
67
+
68
+ triggerOnOpen() {
69
+ const event = new Event('open');
70
+ this.onopen?.(event);
71
+ spyFunctions.openSpy?.(event);
72
+ }
73
+
74
+ triggerOnError() {
75
+ const event = new Event('error');
76
+ this.onerror?.(event);
77
+ spyFunctions.errorSpy?.(event);
78
+ }
79
+
80
+ triggerOnClose(closeReason?: CloseEventInit) {
81
+ const reason = closeReason ?? { code: 1, reason: 'mock reason' };
82
+ const event = new CloseEvent('close', reason);
83
+ this.onclose?.(event);
84
+ spyFunctions.closeSpy?.(event);
85
+ }
86
+
87
+ triggerRemoteClose(code?: number, reason?: string) {
88
+ this.close(code, reason);
89
+ }
90
+
91
+ triggerOnMessage(message?: object) {
92
+ const data = message
93
+ ? JSON.stringify(message)
94
+ : JSON.stringify({ type: 'test' });
95
+ const event = new MessageEvent('message', { data });
96
+ this.onmessage?.(event);
97
+ spyFunctions.messageSpy?.(event);
98
+ }
99
+
100
+ triggerOnMessageBinary(message?: Blob) {
101
+ const data =
102
+ message ??
103
+ new Blob([JSON.stringify({ type: 'test' })], {
104
+ type: 'application/json'
105
+ });
106
+ const event = new MessageEvent('messagebinary', { data });
107
+ this.onmessagebinary?.(event);
108
+ spyFunctions.messageBinarySpy?.(event);
109
+ }
110
+ }
111
+
112
+ const originalWebSocket = WebSocket;
113
+ export const mockWebSocket = (): [
114
+ MockWebSocketSpyFunctions,
115
+ MockWebSocketTriggerFunctions
116
+ ] => {
117
+ spyFunctions.constructorSpy = jest.fn();
118
+ spyFunctions.openSpy = jest.fn();
119
+ spyFunctions.errorSpy = jest.fn();
120
+ spyFunctions.closeSpy = jest.fn();
121
+ spyFunctions.messageSpy = jest.fn();
122
+ spyFunctions.messageBinarySpy = jest.fn();
123
+ spyFunctions.sendSpy = jest.fn();
124
+ global.WebSocket = MockWebSocketImpl;
125
+ return [spyFunctions, triggerFunctions];
126
+ };
127
+
128
+ export const unmockWebSocket = () => {
129
+ global.WebSocket = originalWebSocket;
130
+ spyFunctions.constructorSpy = null;
131
+ spyFunctions.openSpy = null;
132
+ spyFunctions.errorSpy = null;
133
+ spyFunctions.closeSpy = null;
134
+ spyFunctions.messageSpy = null;
135
+ spyFunctions.messageBinarySpy = null;
136
+ };
@@ -0,0 +1,46 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ export { WebRtcPlayerController } from './WebRtcPlayer/WebRtcPlayerController';
4
+ export { WebXRController } from './WebXR/WebXRController';
5
+ export {
6
+ Config,
7
+ ControlSchemeType,
8
+ Flags,
9
+ NumericParameters,
10
+ TextParameters,
11
+ OptionParameters,
12
+ FlagsIds,
13
+ NumericParametersIds,
14
+ TextParametersIds,
15
+ OptionParametersIds,
16
+ AllSettings
17
+ } from './Config/Config';
18
+ export { SettingBase } from './Config/SettingBase';
19
+ export { SettingFlag } from './Config/SettingFlag';
20
+ export { SettingNumber } from './Config/SettingNumber';
21
+ export { SettingOption } from './Config/SettingOption';
22
+ export { SettingText } from './Config/SettingText';
23
+ export { PixelStreaming } from './PixelStreaming/PixelStreaming';
24
+
25
+ export { AFKController as AfkLogic } from './AFK/AFKController';
26
+
27
+ export { LatencyTestResults } from './DataChannel/LatencyTestResults';
28
+ export {
29
+ EncoderSettings,
30
+ InitialSettings,
31
+ WebRTCSettings
32
+ } from './DataChannel/InitialSettings';
33
+ export { AggregatedStats } from './PeerConnectionController/AggregatedStats';
34
+ export { UnquantizedDenormalizedUnsignedCoord as UnquantizedAndDenormalizeUnsigned } from './Util/CoordinateConverter';
35
+ export { MessageDirection } from './UeInstanceMessage/StreamMessageController';
36
+
37
+ export { CandidatePairStats } from './PeerConnectionController/CandidatePairStats';
38
+ export { CandidateStat } from './PeerConnectionController/CandidateStat';
39
+ export { DataChannelStats } from './PeerConnectionController/DataChannelStats';
40
+ export {
41
+ InboundAudioStats,
42
+ InboundVideoStats
43
+ } from './PeerConnectionController/InboundRTPStats';
44
+ export { OutBoundVideoStats } from './PeerConnectionController/OutBoundRTPStats';
45
+ export * from './Util/EventEmitter';
46
+ export * from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["./src/**/*.ts"],
4
+ "exclude": [],
5
+ "compilerOptions": {
6
+ "module": "CommonJS"
7
+ }
8
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./types",
4
+ "noImplicitAny": true,
5
+ "module": "es6",
6
+ "esModuleInterop": true,
7
+ "target": "ES6",
8
+ "moduleResolution": "node",
9
+ "sourceMap": true,
10
+ "allowJs": true,
11
+ "declaration": true
12
+ },
13
+ "lib": ["es2015"],
14
+ "include": ["./src/*.ts"],
15
+ "exclude": ["./src/**/*.test.ts"],
16
+ "typedocOptions": {
17
+ "exclude": "src/index.*",
18
+ "entryPoints": ["src/pixelstreamingfrontend.ts"],
19
+ "sort": ["enum-value-ascending", "required-first", "source-order"],
20
+ "out": "docs",
21
+ "theme": "default",
22
+ "hideGenerator": "true"
23
+ }
24
+ }
@@ -0,0 +1,39 @@
1
+ import { Config } from '../Config/Config';
2
+ import { PixelStreaming } from '../PixelStreaming/PixelStreaming';
3
+ export declare class AFKController {
4
+ closeTimeout: number;
5
+ active: boolean;
6
+ countdownActive: boolean;
7
+ warnTimer: ReturnType<typeof setTimeout>;
8
+ countDown: number;
9
+ countDownTimer: ReturnType<typeof setInterval>;
10
+ config: Config;
11
+ pixelStreaming: PixelStreaming;
12
+ onDismissAfk: () => void;
13
+ onAFKTimedOutCallback: () => void;
14
+ constructor(config: Config, pixelStreaming: PixelStreaming, onDismissAfk: () => void);
15
+ /**
16
+ * The methods that occur when an afk event listener is clicked
17
+ */
18
+ onAfkClick(): void;
19
+ /**
20
+ * Start the warning timer if a timeout is set greater that 0 seconds
21
+ */
22
+ startAfkWarningTimer(): void;
23
+ /**
24
+ * Stop the afk warning timer
25
+ */
26
+ stopAfkWarningTimer(): void;
27
+ /**
28
+ * Pause the timer which when elapsed will warn the user they are inactive.
29
+ */
30
+ pauseAfkWarningTimer(): void;
31
+ /**
32
+ * If the user interacts then reset the warning timer.
33
+ */
34
+ resetAfkWarningTimer(): void;
35
+ /**
36
+ * Show the AFK overlay and begin the countDown
37
+ */
38
+ activateAfkEvent(): void;
39
+ }