@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,97 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { UnquantizedDenormalizedUnsignedCoord } from '../Util/CoordinateConverter';
4
+ import { MessageReceive } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
5
+
6
+ /**
7
+ * Class for handling on screen keyboard usage
8
+ */
9
+ export class OnScreenKeyboard {
10
+ // If the user focuses on a UE input widget then we show them a button to open
11
+ // the on-screen keyboard. JavaScript security means we can only show the
12
+ // on-screen keyboard in response to a user interaction.
13
+ editTextButton: HTMLButtonElement;
14
+
15
+ // A hidden input text box which is used only for focusing and opening the
16
+ // on-screen keyboard.
17
+ hiddenInput: HTMLInputElement;
18
+
19
+ /**
20
+ *
21
+ * @param videoElementParent The div element the video player is injected into
22
+ */
23
+ constructor(videoElementParent: HTMLElement) {
24
+ this.editTextButton = null;
25
+ this.hiddenInput = null;
26
+
27
+ if ('ontouchstart' in document.documentElement) {
28
+ this.createOnScreenKeyboardHelpers(videoElementParent);
29
+ }
30
+ }
31
+
32
+ /**
33
+ * An override for unquantizeAndDenormalizeUnsigned
34
+ * @param x the x axis point
35
+ * @param y the y axis point
36
+ * @returns unquantizeAndDenormalizeUnsigned object
37
+ */
38
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
+ unquantizeAndDenormalizeUnsigned(
40
+ x: number,
41
+ y: number
42
+ ): UnquantizedDenormalizedUnsignedCoord {
43
+ return null;
44
+ }
45
+
46
+ /**
47
+ * Creates on screen keyboard helpers
48
+ * @param videoElementParent The div element the video player i injected into
49
+ */
50
+ createOnScreenKeyboardHelpers(videoElementParent: HTMLElement) {
51
+ if (!this.hiddenInput) {
52
+ this.hiddenInput = document.createElement('input');
53
+ this.hiddenInput.id = 'hiddenInput';
54
+ this.hiddenInput.maxLength = 0;
55
+ videoElementParent.appendChild(this.hiddenInput);
56
+ }
57
+
58
+ if (!this.editTextButton) {
59
+ this.editTextButton = document.createElement('button');
60
+ this.editTextButton.id = 'editTextButton';
61
+ this.editTextButton.innerHTML = 'edit text';
62
+ videoElementParent.appendChild(this.editTextButton);
63
+
64
+ // Hide the 'edit text' button.
65
+ this.editTextButton.classList.add('hiddenState');
66
+
67
+ this.editTextButton.addEventListener('touchend', (event: Event) => {
68
+ // Show the on-screen keyboard.
69
+ this.hiddenInput.focus();
70
+ event.preventDefault();
71
+ });
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Shows the on screen keyboard
77
+ * @param command the command received via the data channel containing keyboard positions
78
+ */
79
+ showOnScreenKeyboard(command: MessageReceive.MessageOnScreenKeyboard) {
80
+ if (command.showOnScreenKeyboard) {
81
+ // Show the 'edit text' button.
82
+ this.editTextButton.classList.remove('hiddenState');
83
+ // Place the 'edit text' button near the UE input widget.
84
+ const pos = this.unquantizeAndDenormalizeUnsigned(
85
+ command.x,
86
+ command.y
87
+ );
88
+ this.editTextButton.style.top = pos.y.toString() + 'px';
89
+ this.editTextButton.style.left = (pos.x - 40).toString() + 'px';
90
+ } else {
91
+ // Hide the 'edit text' button.
92
+ this.editTextButton.classList.add('hiddenState');
93
+ // Hide the on-screen keyboard.
94
+ this.hiddenInput.blur();
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,47 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { Logger } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
4
+
5
+ export class ResponseController {
6
+ responseEventListeners: Map<string, (response: string) => void> = new Map();
7
+
8
+ /**
9
+ * Add a response event listener to the response map
10
+ * @param name - The name of the response
11
+ * @param listener - The method to be activated when the response is selected
12
+ */
13
+ addResponseEventListener(
14
+ name: string,
15
+ listener: (response: string) => void
16
+ ) {
17
+ this.responseEventListeners.set(name, listener);
18
+ }
19
+
20
+ /**
21
+ * Remove a response event listener to the response map
22
+ * @param name - The name of the response
23
+ */
24
+ removeResponseEventListener(name: string) {
25
+ this.responseEventListeners.delete(name);
26
+ }
27
+
28
+ /**
29
+ * Handle a response when receiving one form the streamer
30
+ * @param message - Data received from the data channel with the command in question
31
+ */
32
+ onResponse(message: ArrayBuffer) {
33
+ Logger.Log(
34
+ Logger.GetStackTrace(),
35
+ 'DataChannelReceiveMessageType.Response',
36
+ 6
37
+ );
38
+ const responses = new TextDecoder('utf-16').decode(message.slice(1));
39
+
40
+ Logger.Log(Logger.GetStackTrace(), responses, 6);
41
+ this.responseEventListeners.forEach(
42
+ (listener: (response: string) => void) => {
43
+ listener(responses);
44
+ }
45
+ );
46
+ }
47
+ }
@@ -0,0 +1,154 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { DataChannelSender } from '../DataChannel/DataChannelSender';
4
+ import { Logger } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
5
+ import { StreamMessageController } from './StreamMessageController';
6
+
7
+ export class SendMessageController {
8
+ toStreamerMessagesMapProvider: StreamMessageController;
9
+ dataChannelSender: DataChannelSender;
10
+
11
+ /**
12
+ * @param dataChannelSender - Data channel instance
13
+ * @param toStreamerMessagesMapProvider - Stream Messages instance
14
+ */
15
+ constructor(
16
+ dataChannelSender: DataChannelSender,
17
+ toStreamerMessagesMapProvider: StreamMessageController
18
+ ) {
19
+ this.dataChannelSender = dataChannelSender;
20
+ this.toStreamerMessagesMapProvider = toStreamerMessagesMapProvider;
21
+ }
22
+
23
+ /**
24
+ * Send a message to the streamer through the data channel
25
+ * @param messageType - the type of message we are sending
26
+ * @param messageData - the message data we are sending over the data channel
27
+ * @returns - nil
28
+ */
29
+ sendMessageToStreamer(messageType: string, messageData?: Array<number | string>) {
30
+ if (messageData === undefined) {
31
+ messageData = [];
32
+ }
33
+
34
+ const toStreamerMessages =
35
+ this.toStreamerMessagesMapProvider.toStreamerMessages;
36
+ const messageFormat = toStreamerMessages.get(messageType);
37
+ if (messageFormat === undefined) {
38
+ Logger.Error(
39
+ Logger.GetStackTrace(),
40
+ `Attempted to send a message to the streamer with message type: ${messageType}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`
41
+ );
42
+ return;
43
+ }
44
+
45
+ if(messageFormat.structure && messageData && messageFormat.structure.length !== messageData.length) {
46
+ Logger.Error(
47
+ Logger.GetStackTrace(),
48
+ `Provided message data doesn't match expected layout. Expected [ ${messageFormat.structure.map((element: string) => {
49
+ switch (element) {
50
+ case 'uint8':
51
+ case 'uint16':
52
+ case 'int16':
53
+ case 'float':
54
+ case 'double':
55
+ return 'number';
56
+ case 'string':
57
+ return 'string';
58
+ }
59
+ }).toString() } ] but received [ ${messageData.map((element: number | string) => typeof element).toString()} ]`
60
+ );
61
+ return;
62
+ }
63
+
64
+ let byteLength = 0;
65
+ const textEncoder = new TextEncoder();
66
+ // One loop to calculate the length in bytes of all of the provided data
67
+ messageData.forEach((element: number | string, idx: number) => {
68
+ const type = messageFormat.structure[idx];
69
+ switch (type) {
70
+ case 'uint8':
71
+ byteLength += 1;
72
+ break;
73
+
74
+ case 'uint16':
75
+ byteLength += 2;
76
+ break;
77
+
78
+ case 'int16':
79
+ byteLength += 2;
80
+ break;
81
+
82
+ case 'float':
83
+ byteLength += 4;
84
+ break;
85
+
86
+ case 'double':
87
+ byteLength += 8;
88
+ break;
89
+
90
+ case 'string':
91
+ // 2 bytes for string length
92
+ byteLength += 2;
93
+ // 2 bytes per characters
94
+ byteLength += 2 * textEncoder.encode(element as string).length;
95
+ break;
96
+ }
97
+ });
98
+
99
+ const data = new DataView(new ArrayBuffer(byteLength + 1));
100
+ data.setUint8(0, messageFormat.id);
101
+ let byteOffset = 1;
102
+
103
+ messageData.forEach((element: number | string, idx: number) => {
104
+ const type = messageFormat.structure[idx];
105
+ switch (type) {
106
+ case 'uint8':
107
+ data.setUint8(byteOffset, element as number);
108
+ byteOffset += 1;
109
+ break;
110
+
111
+ case 'uint16':
112
+ data.setUint16(byteOffset, element as number, true);
113
+ byteOffset += 2;
114
+ break;
115
+
116
+ case 'int16':
117
+ data.setInt16(byteOffset, element as number, true);
118
+ byteOffset += 2;
119
+ break;
120
+
121
+ case 'float':
122
+ data.setFloat32(byteOffset, element as number, true);
123
+ byteOffset += 4;
124
+ break;
125
+
126
+ case 'double':
127
+ data.setFloat64(byteOffset, element as number, true);
128
+ byteOffset += 8;
129
+ break;
130
+
131
+ case 'string':
132
+ data.setUint16(byteOffset, (element as string).length, true);
133
+ byteOffset += 2;
134
+ for (let i = 0; i < (element as string).length; i++) {
135
+ data.setUint16(byteOffset, (element as string).charCodeAt(i), true);
136
+ byteOffset += 2;
137
+ }
138
+ break;
139
+ }
140
+ });
141
+
142
+ if (!this.dataChannelSender.canSend()) {
143
+ Logger.Info(
144
+ Logger.GetStackTrace(),
145
+ `Data channel cannot send yet, skipping sending message: ${messageType} - ${new Uint8Array(
146
+ data.buffer
147
+ )}`
148
+ );
149
+ return;
150
+ }
151
+
152
+ this.dataChannelSender.sendData(data.buffer);
153
+ }
154
+ }
@@ -0,0 +1,233 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { Logger } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
4
+
5
+ export class ToStreamerMessage {
6
+ id: number;
7
+ structure?: Array<string>;
8
+ }
9
+
10
+ export class StreamMessageController {
11
+ toStreamerHandlers: Map<
12
+ string,
13
+ (messageData?: Array<number | string> | undefined) => void
14
+ >;
15
+ fromStreamerHandlers: Map<
16
+ string,
17
+ (messageType: string, messageData?: ArrayBuffer | undefined) => void
18
+ >;
19
+ // Type Format
20
+ toStreamerMessages: Map<string, ToStreamerMessage>;
21
+ // ID Type
22
+ fromStreamerMessages: Map<number, string>;
23
+
24
+ constructor() {
25
+ this.toStreamerHandlers = new Map();
26
+ this.fromStreamerHandlers = new Map();
27
+ this.toStreamerMessages = new Map();
28
+ this.fromStreamerMessages = new Map();
29
+ }
30
+
31
+ /**
32
+ * Populate the Default message protocol
33
+ */
34
+ populateDefaultProtocol() {
35
+ /*
36
+ * Control Messages. Range = 0..49.
37
+ */
38
+ this.toStreamerMessages.set('IFrameRequest', {
39
+ id: 0,
40
+ structure: []
41
+ });
42
+ this.toStreamerMessages.set('RequestQualityControl', {
43
+ id: 1,
44
+ structure: []
45
+ });
46
+ this.toStreamerMessages.set('FpsRequest', {
47
+ id: 2,
48
+ structure: []
49
+ });
50
+ this.toStreamerMessages.set('AverageBitrateRequest', {
51
+ id: 3,
52
+ structure: []
53
+ });
54
+ this.toStreamerMessages.set('StartStreaming', {
55
+ id: 4,
56
+ structure: []
57
+ });
58
+ this.toStreamerMessages.set('StopStreaming', {
59
+ id: 5,
60
+ structure: []
61
+ });
62
+ this.toStreamerMessages.set('LatencyTest', {
63
+ id: 6,
64
+ structure: ['string']
65
+ });
66
+ this.toStreamerMessages.set('RequestInitialSettings', {
67
+ id: 7,
68
+ structure: []
69
+ });
70
+ this.toStreamerMessages.set('TestEcho', {
71
+ id: 8,
72
+ structure: []
73
+ });
74
+ this.toStreamerMessages.set('DataChannelLatencyTest', {
75
+ id: 9,
76
+ structure: []
77
+ });
78
+ /*
79
+ * Input Messages. Range = 50..89.
80
+ */
81
+ // Generic Input Messages. Range = 50..59.
82
+ this.toStreamerMessages.set('UIInteraction', {
83
+ id: 50,
84
+ structure: ['string']
85
+ });
86
+ this.toStreamerMessages.set('Command', {
87
+ id: 51,
88
+ structure: ['string']
89
+ });
90
+ // Keyboard Input Message. Range = 60..69.
91
+ this.toStreamerMessages.set('KeyDown', {
92
+ id: 60,
93
+ // keyCode isRepeat
94
+ structure: ['uint8', 'uint8']
95
+ });
96
+ this.toStreamerMessages.set('KeyUp', {
97
+ id: 61,
98
+ // keyCode
99
+ structure: ['uint8']
100
+ });
101
+ this.toStreamerMessages.set('KeyPress', {
102
+ id: 62,
103
+ // charcode
104
+ structure: ['uint16']
105
+ });
106
+ // Mouse Input Messages. Range = 70..79.
107
+ this.toStreamerMessages.set('MouseEnter', {
108
+ id: 70,
109
+ structure: []
110
+ });
111
+ this.toStreamerMessages.set('MouseLeave', {
112
+ id: 71,
113
+ structure: []
114
+ });
115
+ this.toStreamerMessages.set('MouseDown', {
116
+ id: 72,
117
+ // button x y
118
+ structure: ['uint8', 'uint16', 'uint16']
119
+ });
120
+ this.toStreamerMessages.set('MouseUp', {
121
+ id: 73,
122
+ // button x y
123
+ structure: ['uint8', 'uint16', 'uint16']
124
+ });
125
+ this.toStreamerMessages.set('MouseMove', {
126
+ id: 74,
127
+ // x y deltaX deltaY
128
+ structure: ['uint16', 'uint16', 'int16', 'int16']
129
+ });
130
+ this.toStreamerMessages.set('MouseWheel', {
131
+ id: 75,
132
+ // delta x y
133
+ structure: ['int16', 'uint16', 'uint16']
134
+ });
135
+ this.toStreamerMessages.set('MouseDouble', {
136
+ id: 76,
137
+ // button x y
138
+ structure: ['uint8', 'uint16', 'uint16']
139
+ });
140
+ // Touch Input Messages. Range = 80..89.
141
+ this.toStreamerMessages.set('TouchStart', {
142
+ id: 80,
143
+ // numtouches(1) x y idx force valid
144
+ structure: ['uint8', 'uint16', 'uint16', 'uint8', 'uint8', 'uint8']
145
+ });
146
+ this.toStreamerMessages.set('TouchEnd', {
147
+ id: 81,
148
+ // numtouches(1) x y idx force valid
149
+ structure: ['uint8', 'uint16', 'uint16', 'uint8', 'uint8', 'uint8']
150
+ });
151
+ this.toStreamerMessages.set('TouchMove', {
152
+ id: 82,
153
+ // numtouches(1) x y idx force valid
154
+ structure: ['uint8', 'uint16', 'uint16', 'uint8', 'uint8', 'uint8']
155
+ });
156
+ // Gamepad Input Messages. Range = 90..99
157
+ this.toStreamerMessages.set('GamepadConnected', {
158
+ id: 93,
159
+ structure: []
160
+ });
161
+ this.toStreamerMessages.set('GamepadButtonPressed', {
162
+ id: 90,
163
+ // ctrlerId button isRepeat
164
+ structure: ['uint8', 'uint8', 'uint8']
165
+ });
166
+ this.toStreamerMessages.set('GamepadButtonReleased', {
167
+ id: 91,
168
+ // ctrlerId button isRepeat(0)
169
+ structure: ['uint8', 'uint8', 'uint8']
170
+ });
171
+ this.toStreamerMessages.set('GamepadAnalog', {
172
+ id: 92,
173
+ // ctrlerId button analogValue
174
+ structure: ['uint8', 'uint8', 'double']
175
+ });
176
+ this.toStreamerMessages.set('GamepadDisconnected', {
177
+ id: 94,
178
+ // ctrlerId
179
+ structure: ['uint8']
180
+ });
181
+
182
+ this.fromStreamerMessages.set(0, 'QualityControlOwnership');
183
+ this.fromStreamerMessages.set(1, 'Response');
184
+ this.fromStreamerMessages.set(2, 'Command');
185
+ this.fromStreamerMessages.set(3, 'FreezeFrame');
186
+ this.fromStreamerMessages.set(4, 'UnfreezeFrame');
187
+ this.fromStreamerMessages.set(5, 'VideoEncoderAvgQP');
188
+ this.fromStreamerMessages.set(6, 'LatencyTest');
189
+ this.fromStreamerMessages.set(7, 'InitialSettings');
190
+ this.fromStreamerMessages.set(8, 'FileExtension');
191
+ this.fromStreamerMessages.set(9, 'FileMimeType');
192
+ this.fromStreamerMessages.set(10, 'FileContents');
193
+ this.fromStreamerMessages.set(11, 'TestEcho');
194
+ this.fromStreamerMessages.set(12, 'InputControlOwnership');
195
+ this.fromStreamerMessages.set(13, 'GamepadResponse');
196
+ this.fromStreamerMessages.set(14, 'DataChannelLatencyTest');
197
+ this.fromStreamerMessages.set(255, 'Protocol');
198
+ }
199
+
200
+ /**
201
+ * Register a message handler
202
+ * @param messageDirection - the direction of the message; toStreamer or fromStreamer
203
+ * @param messageType - the type of the message
204
+ * @param messageHandler - the function or method to be executed when this handler is called
205
+ */
206
+ registerMessageHandler(
207
+ messageDirection: MessageDirection,
208
+ messageType: string,
209
+ messageHandler: (messageData?: unknown | undefined) => void
210
+ ) {
211
+ switch (messageDirection) {
212
+ case MessageDirection.ToStreamer:
213
+ this.toStreamerHandlers.set(messageType, messageHandler);
214
+ break;
215
+ case MessageDirection.FromStreamer:
216
+ this.fromStreamerHandlers.set(messageType, messageHandler);
217
+ break;
218
+ default:
219
+ Logger.Log(
220
+ Logger.GetStackTrace(),
221
+ `Unknown message direction ${messageDirection}`
222
+ );
223
+ }
224
+ }
225
+ }
226
+
227
+ /**
228
+ * The enum for message directions
229
+ */
230
+ export enum MessageDirection {
231
+ ToStreamer = 0,
232
+ FromStreamer = 1
233
+ }
@@ -0,0 +1,62 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { SendMessageController } from './SendMessageController';
4
+
5
+ export class ToStreamerMessagesController {
6
+ sendMessageController: SendMessageController;
7
+
8
+ /**
9
+ * @param sendMessageController - Stream message controller instance
10
+ */
11
+ constructor(sendMessageController: SendMessageController) {
12
+ this.sendMessageController = sendMessageController;
13
+ }
14
+
15
+ /**
16
+ * Send Request to Take Quality Control to the UE Instance
17
+ */
18
+ SendRequestQualityControl() {
19
+ this.sendMessageController.sendMessageToStreamer(
20
+ 'RequestQualityControl'
21
+ );
22
+ }
23
+
24
+ /**
25
+ * Send Max FPS Request to the UE Instance
26
+ */
27
+ SendMaxFpsRequest() {
28
+ this.sendMessageController.sendMessageToStreamer('FpsRequest');
29
+ }
30
+
31
+ /**
32
+ * Send Average Bitrate Request to the UE Instance
33
+ */
34
+ SendAverageBitrateRequest() {
35
+ this.sendMessageController.sendMessageToStreamer(
36
+ 'AverageBitrateRequest'
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Send a Start Streaming Message to the UE Instance
42
+ */
43
+ SendStartStreaming() {
44
+ this.sendMessageController.sendMessageToStreamer('StartStreaming');
45
+ }
46
+
47
+ /**
48
+ * Send a Stop Streaming Message to the UE Instance
49
+ */
50
+ SendStopStreaming() {
51
+ this.sendMessageController.sendMessageToStreamer('StopStreaming');
52
+ }
53
+
54
+ /**
55
+ * Send a Request Initial Settings to the UE Instance
56
+ */
57
+ SendRequestInitialSettings() {
58
+ this.sendMessageController.sendMessageToStreamer(
59
+ 'RequestInitialSettings'
60
+ );
61
+ }
62
+ }