@epicgames-ps/lib-pixelstreamingfrontend-ue5.5 0.1.3 → 0.2.1

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 (94) hide show
  1. package/.eslintrc.js +1 -1
  2. package/.prettierrc.json +1 -0
  3. package/dist/lib-pixelstreamingfrontend.esm.js +1 -1
  4. package/dist/lib-pixelstreamingfrontend.js +1 -1
  5. package/package.json +6 -5
  6. package/src/AFK/AFKController.ts +10 -32
  7. package/src/Config/Config.ts +179 -201
  8. package/src/Config/SettingBase.ts +61 -2
  9. package/src/Config/SettingFlag.ts +10 -48
  10. package/src/Config/SettingNumber.ts +10 -28
  11. package/src/Config/SettingOption.ts +13 -46
  12. package/src/Config/SettingText.ts +9 -37
  13. package/src/DataChannel/DataChannelController.ts +6 -26
  14. package/src/DataChannel/DataChannelLatencyTestController.ts +38 -33
  15. package/src/DataChannel/DataChannelLatencyTestResults.ts +8 -10
  16. package/src/DataChannel/DataChannelSender.ts +5 -15
  17. package/src/DataChannel/LatencyTestResults.ts +5 -15
  18. package/src/FreezeFrame/FreezeFrame.ts +7 -19
  19. package/src/FreezeFrame/FreezeFrameController.ts +3 -14
  20. package/src/Inputs/GamepadController.ts +123 -221
  21. package/src/Inputs/GamepadTypes.ts +23 -0
  22. package/src/Inputs/IInputController.ts +17 -0
  23. package/src/Inputs/InputClassesFactory.ts +38 -45
  24. package/src/Inputs/KeyCodes.ts +114 -0
  25. package/src/Inputs/KeyboardController.ts +49 -232
  26. package/src/Inputs/MouseController.ts +71 -297
  27. package/src/Inputs/MouseControllerHovering.ts +118 -0
  28. package/src/Inputs/MouseControllerLocked.ts +194 -0
  29. package/src/Inputs/TouchController.ts +49 -105
  30. package/src/Inputs/TouchControllerFake.ts +132 -0
  31. package/src/Inputs/XRGamepadController.ts +35 -44
  32. package/src/PeerConnectionController/AggregatedStats.ts +26 -54
  33. package/src/PeerConnectionController/CandidatePairStats.ts +1 -1
  34. package/src/PeerConnectionController/CandidateStat.ts +1 -1
  35. package/src/PeerConnectionController/PeerConnectionController.ts +217 -164
  36. package/src/PixelStreaming/PixelStreaming.ts +174 -226
  37. package/src/UI/OnScreenKeyboard.ts +14 -9
  38. package/src/UeInstanceMessage/ResponseController.ts +6 -15
  39. package/src/UeInstanceMessage/SendMessageController.ts +16 -18
  40. package/src/UeInstanceMessage/StreamMessageController.ts +3 -12
  41. package/src/UeInstanceMessage/ToStreamerMessagesController.ts +3 -9
  42. package/src/Util/EventEmitter.ts +17 -22
  43. package/src/Util/FileUtil.ts +11 -34
  44. package/src/Util/IURLSearchParams.ts +25 -0
  45. package/src/Util/InputCoordTranslator.ts +73 -0
  46. package/src/Util/RTCUtils.ts +23 -15
  47. package/src/VideoPlayer/StreamController.ts +6 -23
  48. package/src/VideoPlayer/VideoPlayer.ts +9 -30
  49. package/src/WebRtcPlayer/WebRtcPlayerController.ts +328 -690
  50. package/src/WebXR/WebXRController.ts +82 -94
  51. package/src/pixelstreamingfrontend.ts +6 -10
  52. package/types/AFK/AFKController.d.ts +0 -1
  53. package/types/Config/Config.d.ts +6 -5
  54. package/types/Config/SettingBase.d.ts +13 -0
  55. package/types/Config/SettingFlag.d.ts +1 -10
  56. package/types/Config/SettingNumber.d.ts +1 -5
  57. package/types/Config/SettingOption.d.ts +1 -10
  58. package/types/Config/SettingText.d.ts +1 -9
  59. package/types/DataChannel/DataChannelLatencyTestController.d.ts +1 -1
  60. package/types/Inputs/GamepadController.d.ts +22 -46
  61. package/types/Inputs/GamepadTypes.d.ts +7 -0
  62. package/types/Inputs/IInputController.d.ts +16 -0
  63. package/types/Inputs/InputClassesFactory.d.ts +7 -8
  64. package/types/Inputs/KeyCodes.d.ts +5 -0
  65. package/types/Inputs/KeyboardController.d.ts +17 -45
  66. package/types/Inputs/MouseController.d.ts +33 -68
  67. package/types/Inputs/MouseControllerHovering.d.ts +26 -0
  68. package/types/Inputs/MouseControllerLocked.d.ts +31 -0
  69. package/types/Inputs/TouchController.d.ts +19 -44
  70. package/types/Inputs/TouchControllerFake.d.ts +29 -0
  71. package/types/Inputs/XRGamepadController.d.ts +0 -7
  72. package/types/PeerConnectionController/PeerConnectionController.d.ts +10 -1
  73. package/types/PixelStreaming/PixelStreaming.d.ts +14 -2
  74. package/types/UI/OnScreenKeyboard.d.ts +2 -2
  75. package/types/Util/EventEmitter.d.ts +1 -1
  76. package/types/Util/IURLSearchParams.d.ts +9 -0
  77. package/types/Util/InputCoordTranslator.d.ts +29 -0
  78. package/types/VideoPlayer/StreamController.d.ts +0 -2
  79. package/types/WebRtcPlayer/WebRtcPlayerController.d.ts +19 -17
  80. package/types/pixelstreamingfrontend.d.ts +1 -1
  81. package/src/Inputs/FakeTouchController.ts +0 -199
  82. package/src/Inputs/HoveringMouseEvents.ts +0 -192
  83. package/src/Inputs/IMouseEvents.ts +0 -64
  84. package/src/Inputs/ITouchController.ts +0 -29
  85. package/src/Inputs/LockedMouseEvents.ts +0 -287
  86. package/src/Util/CoordinateConverter.ts +0 -290
  87. package/src/Util/EventListenerTracker.ts +0 -29
  88. package/types/Inputs/FakeTouchController.d.ts +0 -61
  89. package/types/Inputs/HoveringMouseEvents.d.ts +0 -56
  90. package/types/Inputs/IMouseEvents.d.ts +0 -53
  91. package/types/Inputs/ITouchController.d.ts +0 -24
  92. package/types/Inputs/LockedMouseEvents.d.ts +0 -80
  93. package/types/Util/CoordinateConverter.d.ts +0 -100
  94. package/types/Util/EventListenerTracker.d.ts +0 -14
@@ -16,7 +16,6 @@ export class Flags {
16
16
  static AutoConnect = 'AutoConnect' as const;
17
17
  static AutoPlayVideo = 'AutoPlayVideo' as const;
18
18
  static AFKDetection = 'TimeoutIfIdle' as const;
19
- static BrowserSendOffer = 'OfferToReceive' as const;
20
19
  static HoveringMouseMode = 'HoveringMouse' as const;
21
20
  static ForceMonoAudio = 'ForceMonoAudio' as const;
22
21
  static ForceTURN = 'ForceTURN' as const;
@@ -26,6 +25,7 @@ export class Flags {
26
25
  static StartVideoMuted = 'StartVideoMuted' as const;
27
26
  static SuppressBrowserKeys = 'SuppressBrowserKeys' as const;
28
27
  static UseMic = 'UseMic' as const;
28
+ static UseCamera = 'UseCamera' as const;
29
29
  static KeyboardInput = 'KeyboardInput' as const;
30
30
  static MouseInput = 'MouseInput' as const;
31
31
  static TouchInput = 'TouchInput' as const;
@@ -36,12 +36,10 @@ export class Flags {
36
36
  }
37
37
 
38
38
  export type FlagsKeys = Exclude<keyof typeof Flags, 'prototype'>;
39
- export type FlagsIds = typeof Flags[FlagsKeys];
39
+ export type FlagsIds = (typeof Flags)[FlagsKeys];
40
40
 
41
41
  const isFlagId = (id: string): id is FlagsIds =>
42
- Object.getOwnPropertyNames(Flags).some(
43
- (name: FlagsKeys) => Flags[name] === id
44
- );
42
+ Object.getOwnPropertyNames(Flags).some((name: FlagsKeys) => Flags[name] === id);
45
43
 
46
44
  /**
47
45
  * A collection of numeric parameters that are core to all Pixel Streaming experiences.
@@ -49,6 +47,7 @@ const isFlagId = (id: string): id is FlagsIds =>
49
47
  */
50
48
  export class NumericParameters {
51
49
  static AFKTimeoutSecs = 'AFKTimeout' as const;
50
+ static AFKCountdownSecs = 'AFKCountdown' as const;
52
51
  static MinQP = 'MinQP' as const;
53
52
  static MaxQP = 'MaxQP' as const;
54
53
  static WebRTCFPS = 'WebRTCFPS' as const;
@@ -58,12 +57,8 @@ export class NumericParameters {
58
57
  static StreamerAutoJoinInterval = 'StreamerAutoJoinInterval' as const;
59
58
  }
60
59
 
61
- export type NumericParametersKeys = Exclude<
62
- keyof typeof NumericParameters,
63
- 'prototype'
64
- >;
65
- export type NumericParametersIds =
66
- typeof NumericParameters[NumericParametersKeys];
60
+ export type NumericParametersKeys = Exclude<keyof typeof NumericParameters, 'prototype'>;
61
+ export type NumericParametersIds = (typeof NumericParameters)[NumericParametersKeys];
67
62
 
68
63
  const isNumericId = (id: string): id is NumericParametersIds =>
69
64
  Object.getOwnPropertyNames(NumericParameters).some(
@@ -78,11 +73,8 @@ export class TextParameters {
78
73
  static SignallingServerUrl = 'ss' as const;
79
74
  }
80
75
 
81
- export type TextParametersKeys = Exclude<
82
- keyof typeof TextParameters,
83
- 'prototype'
84
- >;
85
- export type TextParametersIds = typeof TextParameters[TextParametersKeys];
76
+ export type TextParametersKeys = Exclude<keyof typeof TextParameters, 'prototype'>;
77
+ export type TextParametersIds = (typeof TextParameters)[TextParametersKeys];
86
78
 
87
79
  const isTextId = (id: string): id is TextParametersIds =>
88
80
  Object.getOwnPropertyNames(TextParameters).some(
@@ -98,11 +90,8 @@ export class OptionParameters {
98
90
  static StreamerId = 'StreamerId' as const;
99
91
  }
100
92
 
101
- export type OptionParametersKeys = Exclude<
102
- keyof typeof OptionParameters,
103
- 'prototype'
104
- >;
105
- export type OptionParametersIds = typeof OptionParameters[OptionParametersKeys];
93
+ export type OptionParametersKeys = Exclude<keyof typeof OptionParameters, 'prototype'>;
94
+ export type OptionParametersIds = (typeof OptionParameters)[OptionParametersKeys];
106
95
 
107
96
  const isOptionId = (id: string): id is OptionParametersIds =>
108
97
  Object.getOwnPropertyNames(OptionParameters).some(
@@ -112,20 +101,16 @@ const isOptionId = (id: string): id is OptionParametersIds =>
112
101
  /**
113
102
  * Utility types for inferring data type based on setting ID
114
103
  */
115
- export type OptionIds =
116
- | FlagsIds
117
- | NumericParametersIds
118
- | TextParametersIds
119
- | OptionParametersIds;
104
+ export type OptionIds = FlagsIds | NumericParametersIds | TextParametersIds | OptionParametersIds;
120
105
  export type OptionKeys<T> = T extends FlagsIds
121
106
  ? boolean
122
107
  : T extends NumericParametersIds
123
- ? number
124
- : T extends TextParametersIds
125
- ? string
126
- : T extends OptionParametersIds
127
- ? string
128
- : never;
108
+ ? number
109
+ : T extends TextParametersIds
110
+ ? string
111
+ : T extends OptionParametersIds
112
+ ? string
113
+ : never;
129
114
 
130
115
  export type AllSettings = {
131
116
  [K in OptionIds]: OptionKeys<K>;
@@ -182,15 +167,14 @@ export class Config {
182
167
  TextParameters.SignallingServerUrl,
183
168
  'Signalling url',
184
169
  'Url of the signalling server',
185
- settings && Object.prototype.hasOwnProperty.call(settings, TextParameters.SignallingServerUrl) ?
186
- settings[TextParameters.SignallingServerUrl] :
187
- (location.protocol === 'https:' ? 'wss://' : 'ws://') +
188
- window.location.hostname +
189
- // for readability, we omit the port if it's 80
190
- (window.location.port === '80' ||
191
- window.location.port === ''
192
- ? ''
193
- : `:${window.location.port}`),
170
+ settings && Object.prototype.hasOwnProperty.call(settings, TextParameters.SignallingServerUrl)
171
+ ? settings[TextParameters.SignallingServerUrl]
172
+ : (location.protocol === 'https:' ? 'wss://' : 'ws://') +
173
+ window.location.hostname +
174
+ // for readability, we omit the port if it's 80
175
+ (window.location.port === '80' || window.location.port === ''
176
+ ? ''
177
+ : `:${window.location.port}`),
194
178
  useUrlParams
195
179
  )
196
180
  );
@@ -201,9 +185,9 @@ export class Config {
201
185
  OptionParameters.StreamerId,
202
186
  'Streamer ID',
203
187
  'The ID of the streamer to stream.',
204
- settings && Object.prototype.hasOwnProperty.call(settings, OptionParameters.StreamerId) ?
205
- settings[OptionParameters.StreamerId] :
206
- '',
188
+ settings && Object.prototype.hasOwnProperty.call(settings, OptionParameters.StreamerId)
189
+ ? settings[OptionParameters.StreamerId]
190
+ : '',
207
191
  [],
208
192
  useUrlParams
209
193
  )
@@ -219,34 +203,30 @@ export class Config {
219
203
  'Preferred Codec',
220
204
  'The preferred codec to be used during codec negotiation',
221
205
  'H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f',
222
- settings && Object.prototype.hasOwnProperty.call(settings, OptionParameters.PreferredCodec) ?
223
- [settings[OptionParameters.PreferredCodec]] :
224
- (function (): Array<string> {
225
- const browserSupportedCodecs: Array<string> = [];
226
- // Try get the info needed from the RTCRtpReceiver. This is only available on chrome
227
- if (!RTCRtpReceiver.getCapabilities) {
228
- browserSupportedCodecs.push('Only available on Chrome');
229
- return browserSupportedCodecs;
230
- }
231
-
232
- const matcher = /(VP\d|H26\d|AV1).*/;
233
- const codecs =
234
- RTCRtpReceiver.getCapabilities('video').codecs;
235
- codecs.forEach((codec) => {
236
- const str =
237
- codec.mimeType.split('/')[1] +
238
- ' ' +
239
- (codec.sdpFmtpLine || '');
240
- const match = matcher.exec(str);
241
- if (match !== null) {
242
- browserSupportedCodecs.push(str);
243
- }
244
- });
245
- return browserSupportedCodecs;
246
- })(),
206
+ settings && Object.prototype.hasOwnProperty.call(settings, OptionParameters.PreferredCodec)
207
+ ? [settings[OptionParameters.PreferredCodec]]
208
+ : (function (): Array<string> {
209
+ const browserSupportedCodecs: Array<string> = [];
210
+ // Try get the info needed from the RTCRtpReceiver. This is only available on chrome
211
+ if (!RTCRtpReceiver.getCapabilities) {
212
+ browserSupportedCodecs.push('Only available on Chrome');
213
+ return browserSupportedCodecs;
214
+ }
215
+
216
+ const matcher = /(VP\d|H26\d|AV1).*/;
217
+ const codecs = RTCRtpReceiver.getCapabilities('video').codecs;
218
+ codecs.forEach((codec) => {
219
+ const str = codec.mimeType.split('/')[1] + ' ' + (codec.sdpFmtpLine || '');
220
+ const match = matcher.exec(str);
221
+ if (match !== null) {
222
+ browserSupportedCodecs.push(str);
223
+ }
224
+ });
225
+ return browserSupportedCodecs;
226
+ })(),
247
227
  useUrlParams
248
228
  )
249
- );
229
+ );
250
230
 
251
231
  /**
252
232
  * Boolean parameters
@@ -258,9 +238,9 @@ export class Config {
258
238
  Flags.AutoConnect,
259
239
  'Auto connect to stream',
260
240
  'Whether we should attempt to auto connect to the signalling server or show a click to start prompt.',
261
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.AutoConnect) ?
262
- settings[Flags.AutoConnect] :
263
- false,
241
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.AutoConnect)
242
+ ? settings[Flags.AutoConnect]
243
+ : false,
264
244
  useUrlParams
265
245
  )
266
246
  );
@@ -271,35 +251,35 @@ export class Config {
271
251
  Flags.AutoPlayVideo,
272
252
  'Auto play video',
273
253
  'When video is ready automatically start playing it as opposed to showing a play button.',
274
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.AutoPlayVideo) ?
275
- settings[Flags.AutoPlayVideo] :
276
- true,
254
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.AutoPlayVideo)
255
+ ? settings[Flags.AutoPlayVideo]
256
+ : true,
277
257
  useUrlParams
278
258
  )
279
259
  );
280
260
 
281
261
  this.flags.set(
282
- Flags.BrowserSendOffer,
262
+ Flags.UseMic,
283
263
  new SettingFlag(
284
- Flags.BrowserSendOffer,
285
- 'Browser send offer',
286
- 'Browser will initiate the WebRTC handshake by sending the offer to the streamer',
287
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.BrowserSendOffer) ?
288
- settings[Flags.BrowserSendOffer] :
289
- false,
264
+ Flags.UseMic,
265
+ 'Use microphone',
266
+ 'Make browser request microphone access and open an input audio track.',
267
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.UseMic)
268
+ ? settings[Flags.UseMic]
269
+ : false,
290
270
  useUrlParams
291
271
  )
292
272
  );
293
273
 
294
274
  this.flags.set(
295
- Flags.UseMic,
275
+ Flags.UseCamera,
296
276
  new SettingFlag(
297
- Flags.UseMic,
298
- 'Use microphone',
299
- 'Make browser request microphone access and open an input audio track.',
300
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.UseMic) ?
301
- settings[Flags.UseMic] :
302
- false,
277
+ Flags.UseCamera,
278
+ 'Use webcam',
279
+ 'Make browser request webcam access and open a input video track.',
280
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.UseCamera)
281
+ ? settings[Flags.UseCamera]
282
+ : false,
303
283
  useUrlParams
304
284
  )
305
285
  );
@@ -310,9 +290,9 @@ export class Config {
310
290
  Flags.StartVideoMuted,
311
291
  'Start video muted',
312
292
  'Video will start muted if true.',
313
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.StartVideoMuted) ?
314
- settings[Flags.StartVideoMuted] :
315
- false,
293
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.StartVideoMuted)
294
+ ? settings[Flags.StartVideoMuted]
295
+ : false,
316
296
  useUrlParams
317
297
  )
318
298
  );
@@ -323,9 +303,9 @@ export class Config {
323
303
  Flags.SuppressBrowserKeys,
324
304
  'Suppress browser keys',
325
305
  'Suppress certain browser keys that we use in UE, for example F5 to show shader complexity instead of refresh the page.',
326
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.SuppressBrowserKeys) ?
327
- settings[Flags.SuppressBrowserKeys] :
328
- true,
306
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.SuppressBrowserKeys)
307
+ ? settings[Flags.SuppressBrowserKeys]
308
+ : true,
329
309
  useUrlParams
330
310
  )
331
311
  );
@@ -336,9 +316,9 @@ export class Config {
336
316
  Flags.IsQualityController,
337
317
  'Is quality controller?',
338
318
  'True if this peer controls stream quality',
339
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.IsQualityController) ?
340
- settings[Flags.IsQualityController] :
341
- true,
319
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.IsQualityController)
320
+ ? settings[Flags.IsQualityController]
321
+ : true,
342
322
  useUrlParams
343
323
  )
344
324
  );
@@ -349,9 +329,9 @@ export class Config {
349
329
  Flags.ForceMonoAudio,
350
330
  'Force mono audio',
351
331
  'Force browser to request mono audio in the SDP',
352
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.ForceMonoAudio) ?
353
- settings[Flags.ForceMonoAudio] :
354
- false,
332
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.ForceMonoAudio)
333
+ ? settings[Flags.ForceMonoAudio]
334
+ : false,
355
335
  useUrlParams
356
336
  )
357
337
  );
@@ -362,9 +342,9 @@ export class Config {
362
342
  Flags.ForceTURN,
363
343
  'Force TURN',
364
344
  'Only generate TURN/Relayed ICE candidates.',
365
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.ForceTURN) ?
366
- settings[Flags.ForceTURN] :
367
- false,
345
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.ForceTURN)
346
+ ? settings[Flags.ForceTURN]
347
+ : false,
368
348
  useUrlParams
369
349
  )
370
350
  );
@@ -375,9 +355,9 @@ export class Config {
375
355
  Flags.AFKDetection,
376
356
  'AFK if idle',
377
357
  'Timeout the experience if user is AFK for a period.',
378
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.AFKDetection) ?
379
- settings[Flags.AFKDetection] :
380
- false,
358
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.AFKDetection)
359
+ ? settings[Flags.AFKDetection]
360
+ : false,
381
361
  useUrlParams
382
362
  )
383
363
  );
@@ -388,9 +368,9 @@ export class Config {
388
368
  Flags.MatchViewportResolution,
389
369
  'Match viewport resolution',
390
370
  'Pixel Streaming will be instructed to dynamically resize the video stream to match the size of the video element.',
391
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.MatchViewportResolution) ?
392
- settings[Flags.MatchViewportResolution] :
393
- false,
371
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.MatchViewportResolution)
372
+ ? settings[Flags.MatchViewportResolution]
373
+ : false,
394
374
  useUrlParams
395
375
  )
396
376
  );
@@ -401,9 +381,9 @@ export class Config {
401
381
  Flags.HoveringMouseMode,
402
382
  'Control Scheme: Locked Mouse',
403
383
  'Either locked mouse, where the pointer is consumed by the video and locked to it, or hovering mouse, where the mouse is not consumed.',
404
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.HoveringMouseMode) ?
405
- settings[Flags.HoveringMouseMode] :
406
- false,
384
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.HoveringMouseMode)
385
+ ? settings[Flags.HoveringMouseMode]
386
+ : false,
407
387
  useUrlParams,
408
388
  (isHoveringMouse: boolean, setting: SettingBase) => {
409
389
  setting.label = `Control Scheme: ${isHoveringMouse ? 'Hovering' : 'Locked'} Mouse`;
@@ -417,9 +397,9 @@ export class Config {
417
397
  Flags.FakeMouseWithTouches,
418
398
  'Fake mouse with touches',
419
399
  'A single finger touch is converted into a mouse event. This allows a non-touch application to be controlled partially via a touch device.',
420
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.FakeMouseWithTouches) ?
421
- settings[Flags.FakeMouseWithTouches] :
422
- true,
400
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.FakeMouseWithTouches)
401
+ ? settings[Flags.FakeMouseWithTouches]
402
+ : false,
423
403
  useUrlParams
424
404
  )
425
405
  );
@@ -430,9 +410,9 @@ export class Config {
430
410
  Flags.KeyboardInput,
431
411
  'Keyboard input',
432
412
  'If enabled, send keyboard events to streamer',
433
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.KeyboardInput) ?
434
- settings[Flags.KeyboardInput] :
435
- true,
413
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.KeyboardInput)
414
+ ? settings[Flags.KeyboardInput]
415
+ : true,
436
416
  useUrlParams
437
417
  )
438
418
  );
@@ -443,9 +423,9 @@ export class Config {
443
423
  Flags.MouseInput,
444
424
  'Mouse input',
445
425
  'If enabled, send mouse events to streamer',
446
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.MouseInput) ?
447
- settings[Flags.MouseInput] :
448
- true,
426
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.MouseInput)
427
+ ? settings[Flags.MouseInput]
428
+ : true,
449
429
  useUrlParams
450
430
  )
451
431
  );
@@ -456,9 +436,9 @@ export class Config {
456
436
  Flags.TouchInput,
457
437
  'Touch input',
458
438
  'If enabled, send touch events to streamer',
459
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.TouchInput) ?
460
- settings[Flags.TouchInput] :
461
- true,
439
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.TouchInput)
440
+ ? settings[Flags.TouchInput]
441
+ : true,
462
442
  useUrlParams
463
443
  )
464
444
  );
@@ -469,9 +449,9 @@ export class Config {
469
449
  Flags.GamepadInput,
470
450
  'Gamepad input',
471
451
  'If enabled, send gamepad events to streamer',
472
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.GamepadInput) ?
473
- settings[Flags.GamepadInput] :
474
- true,
452
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.GamepadInput)
453
+ ? settings[Flags.GamepadInput]
454
+ : true,
475
455
  useUrlParams
476
456
  )
477
457
  );
@@ -482,9 +462,9 @@ export class Config {
482
462
  Flags.XRControllerInput,
483
463
  'XR controller input',
484
464
  'If enabled, send XR controller events to streamer',
485
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.XRControllerInput) ?
486
- settings[Flags.XRControllerInput] :
487
- true,
465
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.XRControllerInput)
466
+ ? settings[Flags.XRControllerInput]
467
+ : true,
488
468
  useUrlParams
489
469
  )
490
470
  );
@@ -495,22 +475,22 @@ export class Config {
495
475
  Flags.WaitForStreamer,
496
476
  'Wait for streamer',
497
477
  'Will continue trying to connect to the first streamer available.',
498
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.WaitForStreamer) ?
499
- settings[Flags.WaitForStreamer] :
500
- true,
478
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.WaitForStreamer)
479
+ ? settings[Flags.WaitForStreamer]
480
+ : true,
501
481
  useUrlParams
502
482
  )
503
483
  );
504
-
484
+
505
485
  this.flags.set(
506
486
  Flags.HideUI,
507
487
  new SettingFlag(
508
488
  Flags.HideUI,
509
489
  'Hide the UI overlay',
510
490
  'Will hide all UI overlay details',
511
- settings && Object.prototype.hasOwnProperty.call(settings, Flags.HideUI) ?
512
- settings[Flags.HideUI] :
513
- false,
491
+ settings && Object.prototype.hasOwnProperty.call(settings, Flags.HideUI)
492
+ ? settings[Flags.HideUI]
493
+ : false,
514
494
  useUrlParams
515
495
  )
516
496
  );
@@ -527,9 +507,22 @@ export class Config {
527
507
  'The time (in seconds) it takes for the application to time out if AFK timeout is enabled.',
528
508
  0 /*min*/,
529
509
  600 /*max*/,
530
- settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.AFKTimeoutSecs) ?
531
- settings[NumericParameters.AFKTimeoutSecs] :
532
- 120, /*value*/
510
+ settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.AFKTimeoutSecs)
511
+ ? settings[NumericParameters.AFKTimeoutSecs]
512
+ : 120 /*value*/,
513
+ useUrlParams
514
+ )
515
+ );
516
+
517
+ this.numericParameters.set(
518
+ NumericParameters.AFKCountdownSecs,
519
+ new SettingNumber(
520
+ NumericParameters.AFKCountdownSecs,
521
+ 'AFK countdown',
522
+ 'The time (in seconds) for a user to respond before the stream is ended after an AFK timeout.',
523
+ 10 /*min*/,
524
+ 180 /*max*/,
525
+ 10 /*value*/,
533
526
  useUrlParams
534
527
  )
535
528
  );
@@ -542,9 +535,10 @@ export class Config {
542
535
  'Maximum number of reconnects the application will attempt when a streamer disconnects.',
543
536
  0 /*min*/,
544
537
  999 /*max*/,
545
- settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.MaxReconnectAttempts) ?
546
- settings[NumericParameters.MaxReconnectAttempts] :
547
- 3, /*value*/
538
+ settings &&
539
+ Object.prototype.hasOwnProperty.call(settings, NumericParameters.MaxReconnectAttempts)
540
+ ? settings[NumericParameters.MaxReconnectAttempts]
541
+ : 3 /*value*/,
548
542
  useUrlParams
549
543
  )
550
544
  );
@@ -557,9 +551,9 @@ export class Config {
557
551
  'The lower bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.',
558
552
  0 /*min*/,
559
553
  51 /*max*/,
560
- settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.MinQP) ?
561
- settings[NumericParameters.MinQP] :
562
- 0, /*value*/
554
+ settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.MinQP)
555
+ ? settings[NumericParameters.MinQP]
556
+ : 0 /*value*/,
563
557
  useUrlParams
564
558
  )
565
559
  );
@@ -572,9 +566,9 @@ export class Config {
572
566
  'The upper bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.',
573
567
  0 /*min*/,
574
568
  51 /*max*/,
575
- settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.MaxQP) ?
576
- settings[NumericParameters.MaxQP] :
577
- 51, /*value*/
569
+ settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.MaxQP)
570
+ ? settings[NumericParameters.MaxQP]
571
+ : 51 /*value*/,
578
572
  useUrlParams
579
573
  )
580
574
  );
@@ -587,9 +581,9 @@ export class Config {
587
581
  'The maximum FPS that WebRTC will try to transmit frames at.',
588
582
  1 /*min*/,
589
583
  999 /*max*/,
590
- settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.WebRTCFPS) ?
591
- settings[NumericParameters.WebRTCFPS] :
592
- 60, /*value*/
584
+ settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.WebRTCFPS)
585
+ ? settings[NumericParameters.WebRTCFPS]
586
+ : 60 /*value*/,
593
587
  useUrlParams
594
588
  )
595
589
  );
@@ -602,9 +596,9 @@ export class Config {
602
596
  'The minimum bitrate that WebRTC should use.',
603
597
  0 /*min*/,
604
598
  500000 /*max*/,
605
- settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.WebRTCMinBitrate) ?
606
- settings[NumericParameters.WebRTCMinBitrate] :
607
- 0, /*value*/
599
+ settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.WebRTCMinBitrate)
600
+ ? settings[NumericParameters.WebRTCMinBitrate]
601
+ : 0 /*value*/,
608
602
  useUrlParams
609
603
  )
610
604
  );
@@ -617,9 +611,9 @@ export class Config {
617
611
  'The maximum bitrate that WebRTC should use.',
618
612
  0 /*min*/,
619
613
  500000 /*max*/,
620
- settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.WebRTCMaxBitrate) ?
621
- settings[NumericParameters.WebRTCMaxBitrate] :
622
- 0, /*value*/
614
+ settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.WebRTCMaxBitrate)
615
+ ? settings[NumericParameters.WebRTCMaxBitrate]
616
+ : 0 /*value*/,
623
617
  useUrlParams
624
618
  )
625
619
  );
@@ -632,9 +626,10 @@ export class Config {
632
626
  'Delay between retries when waiting for an available streamer.',
633
627
  500 /*min*/,
634
628
  900000 /*max*/,
635
- settings && Object.prototype.hasOwnProperty.call(settings, NumericParameters.StreamerAutoJoinInterval) ?
636
- settings[NumericParameters.StreamerAutoJoinInterval] :
637
- 3000, /*value*/
629
+ settings &&
630
+ Object.prototype.hasOwnProperty.call(settings, NumericParameters.StreamerAutoJoinInterval)
631
+ ? settings[NumericParameters.StreamerAutoJoinInterval]
632
+ : 3000 /*value*/,
638
633
  useUrlParams
639
634
  )
640
635
  );
@@ -650,9 +645,7 @@ export class Config {
650
645
  onChangedListener: (newValue: number) => void
651
646
  ): void {
652
647
  if (this.numericParameters.has(id)) {
653
- this.numericParameters
654
- .get(id)
655
- .addOnChangedListener(onChangedListener);
648
+ this.numericParameters.get(id).addOnChangedListener(onChangedListener);
656
649
  }
657
650
  }
658
651
 
@@ -661,9 +654,7 @@ export class Config {
661
654
  onChangedListener: (newValue: string) => void
662
655
  ): void {
663
656
  if (this.optionParameters.has(id)) {
664
- this.optionParameters
665
- .get(id)
666
- .addOnChangedListener(onChangedListener);
657
+ this.optionParameters.get(id).addOnChangedListener(onChangedListener);
667
658
  }
668
659
  }
669
660
 
@@ -709,10 +700,7 @@ export class Config {
709
700
  * @param id The id of the flag.
710
701
  * @param onChangeListener The callback to fire when the value changes.
711
702
  */
712
- _addOnSettingChangedListener(
713
- id: FlagsIds,
714
- onChangeListener: (newFlagValue: boolean) => void
715
- ): void {
703
+ _addOnSettingChangedListener(id: FlagsIds, onChangeListener: (newFlagValue: boolean) => void): void {
716
704
  if (this.flags.has(id)) {
717
705
  this.flags.get(id).onChange = onChangeListener;
718
706
  }
@@ -757,10 +745,7 @@ export class Config {
757
745
  */
758
746
  setFlagEnabled(id: FlagsIds, flagEnabled: boolean) {
759
747
  if (!this.flags.has(id)) {
760
- Logger.Warning(
761
- Logger.GetStackTrace(),
762
- `Cannot toggle flag called ${id} - it does not exist in the Config.flags map.`
763
- );
748
+ Logger.Warning(`Cannot toggle flag called ${id} - it does not exist in the Config.flags map.`);
764
749
  } else {
765
750
  this.flags.get(id).flag = flagEnabled;
766
751
  }
@@ -774,7 +759,6 @@ export class Config {
774
759
  setTextSetting(id: TextParametersIds, settingValue: string) {
775
760
  if (!this.textParameters.has(id)) {
776
761
  Logger.Warning(
777
- Logger.GetStackTrace(),
778
762
  `Cannot set text setting called ${id} - it does not exist in the Config.textParameters map.`
779
763
  );
780
764
  } else {
@@ -787,13 +771,9 @@ export class Config {
787
771
  * @param id The id of the setting
788
772
  * @param settingOptions The values the setting could take
789
773
  */
790
- setOptionSettingOptions(
791
- id: OptionParametersIds,
792
- settingOptions: Array<string>
793
- ) {
774
+ setOptionSettingOptions(id: OptionParametersIds, settingOptions: Array<string>) {
794
775
  if (!this.optionParameters.has(id)) {
795
776
  Logger.Warning(
796
- Logger.GetStackTrace(),
797
777
  `Cannot set text setting called ${id} - it does not exist in the Config.optionParameters map.`
798
778
  );
799
779
  } else {
@@ -809,7 +789,6 @@ export class Config {
809
789
  setOptionSettingValue(id: OptionParametersIds, settingValue: string) {
810
790
  if (!this.optionParameters.has(id)) {
811
791
  Logger.Warning(
812
- Logger.GetStackTrace(),
813
792
  `Cannot set text setting called ${id} - it does not exist in the Config.enumParameters map.`
814
793
  );
815
794
  } else {
@@ -831,7 +810,6 @@ export class Config {
831
810
  setFlagLabel(id: FlagsIds, label: string) {
832
811
  if (!this.flags.has(id)) {
833
812
  Logger.Warning(
834
- Logger.GetStackTrace(),
835
813
  `Cannot set label for flag called ${id} - it does not exist in the Config.flags map.`
836
814
  );
837
815
  } else {
@@ -839,24 +817,24 @@ export class Config {
839
817
  }
840
818
  }
841
819
 
842
- /**
843
- * Set a subset of all settings in one function call.
844
- *
845
- * @param settings A (partial) list of settings to set
846
- */
847
- setSettings(settings: Partial<AllSettings>) {
848
- for (const key of Object.keys(settings)) {
849
- if (isFlagId(key)) {
850
- this.setFlagEnabled(key, settings[key]);
851
- } else if (isNumericId(key)) {
852
- this.setNumericSetting(key, settings[key]);
853
- } else if (isTextId(key)) {
854
- this.setTextSetting(key, settings[key]);
855
- } else if (isOptionId(key)) {
856
- this.setOptionSettingValue(key, settings[key]);
857
- }
820
+ /**
821
+ * Set a subset of all settings in one function call.
822
+ *
823
+ * @param settings A (partial) list of settings to set
824
+ */
825
+ setSettings(settings: Partial<AllSettings>) {
826
+ for (const key of Object.keys(settings)) {
827
+ if (isFlagId(key)) {
828
+ this.setFlagEnabled(key, settings[key]);
829
+ } else if (isNumericId(key)) {
830
+ this.setNumericSetting(key, settings[key]);
831
+ } else if (isTextId(key)) {
832
+ this.setTextSetting(key, settings[key]);
833
+ } else if (isOptionId(key)) {
834
+ this.setOptionSettingValue(key, settings[key]);
858
835
  }
859
836
  }
837
+ }
860
838
 
861
839
  /**
862
840
  * Get all settings