@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,65 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ /**
4
+ * Base class for a setting that has a text label and an arbitrary setting value it stores.
5
+ */
6
+ export class SettingBase {
7
+ id: string;
8
+ description: string;
9
+ _label: string;
10
+ _value: unknown;
11
+ onChange: (changedValue: unknown, setting: SettingBase) => void;
12
+ onChangeEmit: (changedValue: unknown) => void;
13
+
14
+ constructor(
15
+ id: string,
16
+ label: string,
17
+ description: string,
18
+ defaultSettingValue: unknown,
19
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
20
+ defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => { /* Do nothing, to be overridden. */ }
21
+ ) {
22
+ this.onChange = defaultOnChangeListener;
23
+
24
+ this.onChangeEmit = () => {
25
+ /* Do nothing, to be overridden. */
26
+ };
27
+ this.id = id;
28
+ this.description = description;
29
+ this.label = label;
30
+ this.value = defaultSettingValue;
31
+ }
32
+
33
+ /**
34
+ * Set the label text for the setting.
35
+ * @param label setting label.
36
+ */
37
+ public set label(inLabel: string) {
38
+ this._label = inLabel;
39
+ this.onChangeEmit(this._value);
40
+ }
41
+
42
+ /**
43
+ * @returns The label text for the setting.
44
+ */
45
+ public get label(): string {
46
+ return this._label;
47
+ }
48
+
49
+ /**
50
+ * @return The setting's value.
51
+ */
52
+ public get value(): unknown {
53
+ return this._value;
54
+ }
55
+
56
+ /**
57
+ * Update the setting's stored value.
58
+ * @param inValue The new value for the setting.
59
+ */
60
+ public set value(inValue: unknown) {
61
+ this._value = inValue;
62
+ this.onChange(this._value, this);
63
+ this.onChangeEmit(this._value);
64
+ }
65
+ }
@@ -0,0 +1,99 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import type { FlagsIds } from './Config';
4
+ import { SettingBase } from './SettingBase';
5
+
6
+ /**
7
+ * A boolean flag setting object with a text label.
8
+ */
9
+ export class SettingFlag<
10
+ CustomIds extends string = FlagsIds
11
+ > extends SettingBase {
12
+ id: FlagsIds | CustomIds;
13
+ onChangeEmit: (changedValue: boolean) => void;
14
+ useUrlParams: boolean;
15
+
16
+ constructor(
17
+ id: FlagsIds | CustomIds,
18
+ label: string,
19
+ description: string,
20
+ defaultFlagValue: boolean,
21
+ useUrlParams: boolean,
22
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
23
+ defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => { /* Do nothing, to be overridden. */ }
24
+ ) {
25
+ super(id, label, description, defaultFlagValue, defaultOnChangeListener);
26
+
27
+ const urlParams = new URLSearchParams(window.location.search);
28
+ if (!useUrlParams || !urlParams.has(this.id)) {
29
+ this.flag = defaultFlagValue;
30
+ } else {
31
+ // parse flag from url parameters
32
+ const urlParamFlag = this.getUrlParamFlag();
33
+ this.flag = urlParamFlag;
34
+ }
35
+ this.useUrlParams = useUrlParams;
36
+ }
37
+
38
+ /**
39
+ * Parse the flag value from the url parameters.
40
+ * @returns True if the url parameters contains /?id, but False if /?id=false
41
+ */
42
+ getUrlParamFlag(): boolean {
43
+ const urlParams = new URLSearchParams(window.location.search);
44
+ if (urlParams.has(this.id)) {
45
+ if (
46
+ urlParams.get(this.id) === 'false' ||
47
+ urlParams.get(this.id) === 'False'
48
+ ) {
49
+ return false;
50
+ }
51
+ return true;
52
+ }
53
+ return false;
54
+ }
55
+
56
+ /**
57
+ * Persist the setting value in URL.
58
+ */
59
+ public updateURLParams() {
60
+ if (this.useUrlParams) {
61
+ // set url params
62
+ const urlParams = new URLSearchParams(window.location.search);
63
+ if (this.flag === true) {
64
+ urlParams.set(this.id, 'true');
65
+ } else {
66
+ urlParams.set(this.id, 'false');
67
+ }
68
+ window.history.replaceState(
69
+ {},
70
+ '',
71
+ urlParams.toString() !== ''
72
+ ? `${location.pathname}?${urlParams}`
73
+ : `${location.pathname}`
74
+ );
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Enables this flag.
80
+ */
81
+ public enable(): void {
82
+ this.flag = true;
83
+ }
84
+
85
+ /**
86
+ * @return The setting's value.
87
+ */
88
+ public get flag(): boolean {
89
+ return !!this.value;
90
+ }
91
+
92
+ /**
93
+ * Update the setting's stored value.
94
+ * @param inValue The new value for the setting.
95
+ */
96
+ public set flag(inValue: boolean) {
97
+ this.value = inValue;
98
+ }
99
+ }
@@ -0,0 +1,111 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import type { NumericParametersIds } from './Config';
4
+ import { SettingBase } from './SettingBase';
5
+
6
+ /**
7
+ * A number setting object with a text label. Min and max limit the range of allowed values.
8
+ */
9
+ export class SettingNumber<
10
+ CustomIds extends string = NumericParametersIds
11
+ > extends SettingBase {
12
+ _min: number;
13
+ _max: number;
14
+
15
+ id: NumericParametersIds | CustomIds;
16
+ onChangeEmit: (changedValue: number) => void;
17
+ useUrlParams: boolean;
18
+
19
+ constructor(
20
+ id: NumericParametersIds | CustomIds,
21
+ label: string,
22
+ description: string,
23
+ min: number,
24
+ max: number,
25
+ defaultNumber: number,
26
+ useUrlParams: boolean,
27
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
28
+ defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => { /* Do nothing, to be overridden. */ }
29
+ ) {
30
+ super(id, label, description, defaultNumber, defaultOnChangeListener);
31
+
32
+ this._min = min;
33
+ this._max = max;
34
+
35
+ // attempt to read the number from the url params
36
+ const urlParams = new URLSearchParams(window.location.search);
37
+ if (!useUrlParams || !urlParams.has(this.id)) {
38
+ this.number = defaultNumber;
39
+ } else {
40
+ const parsedValue = Number.parseFloat(urlParams.get(this.id));
41
+ this.number = Number.isNaN(parsedValue)
42
+ ? defaultNumber
43
+ : parsedValue;
44
+ }
45
+ this.useUrlParams = useUrlParams;
46
+ }
47
+
48
+ /**
49
+ * Persist the setting value in URL.
50
+ */
51
+ public updateURLParams(): void {
52
+ if (this.useUrlParams) {
53
+ // set url params like ?id=number
54
+ const urlParams = new URLSearchParams(window.location.search);
55
+ urlParams.set(this.id, this.number.toString());
56
+ window.history.replaceState(
57
+ {},
58
+ '',
59
+ urlParams.toString() !== ''
60
+ ? `${location.pathname}?${urlParams}`
61
+ : `${location.pathname}`
62
+ );
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Set the number value (will be clamped within range).
68
+ */
69
+ public set number(newNumber: number) {
70
+ this.value = this.clamp(newNumber);
71
+ }
72
+
73
+ /**
74
+ * @returns The number stored.
75
+ */
76
+ public get number(): number {
77
+ return this.value as number;
78
+ }
79
+
80
+ /**
81
+ * Clamps a number between the min and max values (inclusive).
82
+ * @param inNumber The number to clamp.
83
+ * @returns The clamped number.
84
+ */
85
+ public clamp(inNumber: number): number {
86
+ return Math.max(Math.min(this._max, inNumber), this._min);
87
+ }
88
+
89
+ /**
90
+ * Returns the minimum value
91
+ * @returns The minimum value
92
+ */
93
+ public get min(): number {
94
+ return this._min;
95
+ }
96
+
97
+ /**
98
+ * Returns the maximum value
99
+ * @returns The maximum value
100
+ */
101
+ public get max(): number {
102
+ return this._max;
103
+ }
104
+
105
+ /**
106
+ * Add a change listener to the number object.
107
+ */
108
+ public addOnChangedListener(onChangedFunc: (newNumber: number) => void) {
109
+ this.onChange = onChangedFunc;
110
+ }
111
+ }
@@ -0,0 +1,124 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import type { OptionParametersIds } from './Config';
4
+ import { SettingBase } from './SettingBase';
5
+
6
+ /**
7
+ * An Option setting object with a text label. Allows you to specify an array of options and select one of them.
8
+ */
9
+ export class SettingOption<
10
+ CustomIds extends string = OptionParametersIds
11
+ > extends SettingBase {
12
+ id: OptionParametersIds | CustomIds;
13
+ onChangeEmit: (changedValue: string) => void;
14
+ _options: Array<string>;
15
+ useUrlParams: boolean;
16
+
17
+ constructor(
18
+ id: OptionParametersIds | CustomIds,
19
+ label: string,
20
+ description: string,
21
+ defaultTextValue: string,
22
+ options: Array<string>,
23
+ useUrlParams: boolean,
24
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
25
+ defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => { /* Do nothing, to be overridden. */ }
26
+ ) {
27
+ super(id, label, description, [defaultTextValue], defaultOnChangeListener);
28
+
29
+ this.options = options;
30
+ const urlParams = new URLSearchParams(window.location.search);
31
+ const stringToMatch: string =
32
+ useUrlParams && urlParams.has(this.id)
33
+ ? this.getUrlParamText()
34
+ : defaultTextValue;
35
+ this.selected = stringToMatch;
36
+ this.useUrlParams = useUrlParams;
37
+ }
38
+
39
+ /**
40
+ * Parse the text value from the url parameters.
41
+ * @returns The text value parsed from the url if the url parameters contains /?id=value, but empty string if just /?id or no url param found.
42
+ */
43
+ getUrlParamText(): string {
44
+ const urlParams = new URLSearchParams(window.location.search);
45
+ if (urlParams.has(this.id)) {
46
+ return urlParams.get(this.id) ?? '';
47
+ }
48
+ return '';
49
+ }
50
+
51
+ /**
52
+ * Persist the setting value in URL.
53
+ */
54
+ public updateURLParams() {
55
+ if (this.useUrlParams) {
56
+ // set url params
57
+ const urlParams = new URLSearchParams(window.location.search);
58
+ urlParams.set(this.id, this.selected);
59
+ window.history.replaceState(
60
+ {},
61
+ '',
62
+ urlParams.toString() !== ''
63
+ ? `${location.pathname}?${urlParams}`
64
+ : `${location.pathname}`
65
+ );
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Add a change listener to the select element.
71
+ */
72
+ public addOnChangedListener(onChangedFunc: (newValue: string) => void) {
73
+ this.onChange = onChangedFunc;
74
+ }
75
+
76
+ /**
77
+ * @returns All available options as an array
78
+ */
79
+ public get options(): Array<string> {
80
+ return this._options;
81
+ }
82
+
83
+ /**
84
+ * Set options
85
+ * @param values Array of options
86
+ */
87
+ public set options(values: Array<string>) {
88
+ this._options = values;
89
+ this.onChangeEmit(this.selected);
90
+ }
91
+
92
+ /**
93
+ * @returns Selected option as a string
94
+ */
95
+ public get selected(): string {
96
+ return this.value as string;
97
+ }
98
+
99
+ /**
100
+ * Set selected option if it matches one of the available options
101
+ * @param value Selected option
102
+ */
103
+ public set selected(value: string) {
104
+ // A user may not specify the full possible value so we instead use the closest match.
105
+ // eg ?xxx=H264 would select 'H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f'
106
+ let filteredList = this.options.filter(
107
+ (option: string) => option.indexOf(value) !== -1
108
+ );
109
+ if (filteredList.length) {
110
+ this.value = filteredList[0];
111
+ return;
112
+ }
113
+
114
+ // A user has specified a codec with a fmtp string but this codec + fmtp line isn't available.
115
+ // in that case, just use the codec
116
+ filteredList = this.options.filter(
117
+ (option: string) => option.indexOf(value.split(' ')[0]) !== -1
118
+ );
119
+ if (filteredList.length) {
120
+ this.value = filteredList[0];
121
+ return;
122
+ }
123
+ }
124
+ }
@@ -0,0 +1,82 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import type { TextParametersIds } from './Config';
4
+ import { SettingBase } from './SettingBase';
5
+
6
+ /**
7
+ * A text setting object with a text label.
8
+ */
9
+ export class SettingText<
10
+ CustomIds extends string = TextParametersIds
11
+ > extends SettingBase {
12
+ id: TextParametersIds | CustomIds;
13
+ onChangeEmit: (changedValue: string) => void;
14
+ useUrlParams: boolean;
15
+
16
+ constructor(
17
+ id: TextParametersIds | CustomIds,
18
+ label: string,
19
+ description: string,
20
+ defaultTextValue: string,
21
+ useUrlParams: boolean,
22
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
23
+ defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => { /* Do nothing, to be overridden. */ }
24
+ ) {
25
+ super(id, label, description, defaultTextValue, defaultOnChangeListener);
26
+
27
+ const urlParams = new URLSearchParams(window.location.search);
28
+ if (!useUrlParams || !urlParams.has(this.id)) {
29
+ this.text = defaultTextValue;
30
+ } else {
31
+ // parse flag from url parameters
32
+ const urlParamFlag = this.getUrlParamText();
33
+ this.text = urlParamFlag;
34
+ }
35
+ this.useUrlParams = useUrlParams;
36
+ }
37
+
38
+ /**
39
+ * Parse the text value from the url parameters.
40
+ * @returns The text value parsed from the url if the url parameters contains /?id=value, but empty string if just /?id or no url param found.
41
+ */
42
+ getUrlParamText(): string {
43
+ const urlParams = new URLSearchParams(window.location.search);
44
+ if (urlParams.has(this.id)) {
45
+ return urlParams.get(this.id) ?? '';
46
+ }
47
+ return '';
48
+ }
49
+
50
+ /**
51
+ * Persist the setting value in URL.
52
+ */
53
+ public updateURLParams() {
54
+ if (this.useUrlParams) {
55
+ // set url params
56
+ const urlParams = new URLSearchParams(window.location.search);
57
+ urlParams.set(this.id, this.text);
58
+ window.history.replaceState(
59
+ {},
60
+ '',
61
+ urlParams.toString() !== ''
62
+ ? `${location.pathname}?${urlParams}`
63
+ : `${location.pathname}`
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ * @return The setting's value.
70
+ */
71
+ public get text(): string {
72
+ return this.value as string;
73
+ }
74
+
75
+ /**
76
+ * Update the setting's stored value.
77
+ * @param inValue The new value for the setting.
78
+ */
79
+ public set text(inValue: string) {
80
+ this.value = inValue;
81
+ }
82
+ }
@@ -0,0 +1,138 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ import { Logger } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
4
+
5
+ /**
6
+ * Handles the Sending and Receiving of messages to the UE Instance via the Data Channel
7
+ */
8
+ export class DataChannelController {
9
+ dataChannel: RTCDataChannel;
10
+ peerConnection: RTCPeerConnection;
11
+ datachannelOptions: RTCDataChannelInit;
12
+ label: string;
13
+ isReceivingFreezeFrame = false;
14
+
15
+ /**
16
+ * return the current state of a datachannel controller instance
17
+ * @returns the current DataChannelController instance
18
+ */
19
+ getDataChannelInstance(): DataChannelController {
20
+ return this;
21
+ }
22
+
23
+ /**
24
+ * To Create and Set up a Data Channel
25
+ * @param peerConnection - The RTC Peer Connection
26
+ * @param label - Label of the Data Channel
27
+ * @param datachannelOptions - Optional RTC DataChannel options
28
+ */
29
+ createDataChannel(
30
+ peerConnection: RTCPeerConnection,
31
+ label: string,
32
+ datachannelOptions?: RTCDataChannelInit
33
+ ) {
34
+ this.peerConnection = peerConnection;
35
+ this.label = label;
36
+ this.datachannelOptions = datachannelOptions;
37
+ if (datachannelOptions == null) {
38
+ this.datachannelOptions = {} as RTCDataChannelInit;
39
+ this.datachannelOptions.ordered = true;
40
+ }
41
+
42
+ this.dataChannel = this.peerConnection.createDataChannel(
43
+ this.label,
44
+ this.datachannelOptions
45
+ );
46
+ this.setupDataChannel();
47
+ }
48
+
49
+ setupDataChannel() {
50
+ //We Want an Array Buffer not a blob
51
+ this.dataChannel.binaryType = 'arraybuffer';
52
+ this.dataChannel.onopen = (ev: Event) => this.handleOnOpen(ev);
53
+ this.dataChannel.onclose = (ev: Event) => this.handleOnClose(ev);
54
+ this.dataChannel.onmessage = (ev: MessageEvent) =>
55
+ this.handleOnMessage(ev);
56
+ this.dataChannel.onerror = (ev: MessageEvent) => this.handleOnError(ev);
57
+ }
58
+
59
+ /**
60
+ * Handles when the Data Channel is opened
61
+ */
62
+ handleOnOpen(ev: Event) {
63
+ Logger.Log(
64
+ Logger.GetStackTrace(),
65
+ `Data Channel (${this.label}) opened.`,
66
+ 7
67
+ );
68
+ this.onOpen(this.dataChannel?.label, ev);
69
+ }
70
+
71
+ /**
72
+ * Handles when the Data Channel is closed
73
+ */
74
+ handleOnClose(ev: Event) {
75
+ Logger.Log(
76
+ Logger.GetStackTrace(),
77
+ `Data Channel (${this.label}) closed.`,
78
+ 7
79
+ );
80
+ this.onClose(this.dataChannel?.label, ev);
81
+ }
82
+
83
+ /**
84
+ * Handles when a message is received
85
+ * @param event - Message Event
86
+ */
87
+ handleOnMessage(event: MessageEvent) {
88
+ // Higher log level to prevent log spam with messages received
89
+ Logger.Log(
90
+ Logger.GetStackTrace(),
91
+ `Data Channel (${this.label}) message: ${event}`,
92
+ 8
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Handles when an error is thrown
98
+ * @param event - Error Event
99
+ */
100
+ handleOnError(event: MessageEvent) {
101
+ Logger.Log(
102
+ Logger.GetStackTrace(),
103
+ `Data Channel (${this.label}) error: ${event}`,
104
+ 7
105
+ );
106
+ this.onError(this.dataChannel?.label, event);
107
+ }
108
+
109
+ /**
110
+ * Override to register onOpen handler
111
+ * @param label Data channel label ("datachannel", "send-datachannel", "recv-datachannel")
112
+ * @param ev event
113
+ */
114
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
115
+ onOpen(label: string, ev: Event) {
116
+ // empty default implementation
117
+ }
118
+
119
+ /**
120
+ * Override to register onClose handler
121
+ * @param label Data channel label ("datachannel", "send-datachannel", "recv-datachannel")
122
+ * @param ev event
123
+ */
124
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
125
+ onClose(label: string, ev: Event) {
126
+ // empty default implementation
127
+ }
128
+
129
+ /**
130
+ * Override to register onError handler
131
+ * @param label Data channel label ("datachannel", "send-datachannel", "recv-datachannel")
132
+ * @param ev event
133
+ */
134
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
135
+ onError(label: string, ev: Event) {
136
+ // empty default implementation
137
+ }
138
+ }