@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.
- package/.eslintrc.js +1 -1
- package/.prettierrc.json +1 -0
- package/dist/lib-pixelstreamingfrontend.esm.js +1 -1
- package/dist/lib-pixelstreamingfrontend.js +1 -1
- package/package.json +6 -5
- package/src/AFK/AFKController.ts +10 -32
- package/src/Config/Config.ts +179 -201
- package/src/Config/SettingBase.ts +61 -2
- package/src/Config/SettingFlag.ts +10 -48
- package/src/Config/SettingNumber.ts +10 -28
- package/src/Config/SettingOption.ts +13 -46
- package/src/Config/SettingText.ts +9 -37
- package/src/DataChannel/DataChannelController.ts +6 -26
- package/src/DataChannel/DataChannelLatencyTestController.ts +38 -33
- package/src/DataChannel/DataChannelLatencyTestResults.ts +8 -10
- package/src/DataChannel/DataChannelSender.ts +5 -15
- package/src/DataChannel/LatencyTestResults.ts +5 -15
- package/src/FreezeFrame/FreezeFrame.ts +7 -19
- package/src/FreezeFrame/FreezeFrameController.ts +3 -14
- package/src/Inputs/GamepadController.ts +123 -221
- package/src/Inputs/GamepadTypes.ts +23 -0
- package/src/Inputs/IInputController.ts +17 -0
- package/src/Inputs/InputClassesFactory.ts +38 -45
- package/src/Inputs/KeyCodes.ts +114 -0
- package/src/Inputs/KeyboardController.ts +49 -232
- package/src/Inputs/MouseController.ts +71 -297
- package/src/Inputs/MouseControllerHovering.ts +118 -0
- package/src/Inputs/MouseControllerLocked.ts +194 -0
- package/src/Inputs/TouchController.ts +49 -105
- package/src/Inputs/TouchControllerFake.ts +132 -0
- package/src/Inputs/XRGamepadController.ts +35 -44
- package/src/PeerConnectionController/AggregatedStats.ts +26 -54
- package/src/PeerConnectionController/CandidatePairStats.ts +1 -1
- package/src/PeerConnectionController/CandidateStat.ts +1 -1
- package/src/PeerConnectionController/PeerConnectionController.ts +217 -164
- package/src/PixelStreaming/PixelStreaming.ts +174 -226
- package/src/UI/OnScreenKeyboard.ts +14 -9
- package/src/UeInstanceMessage/ResponseController.ts +6 -15
- package/src/UeInstanceMessage/SendMessageController.ts +16 -18
- package/src/UeInstanceMessage/StreamMessageController.ts +3 -12
- package/src/UeInstanceMessage/ToStreamerMessagesController.ts +3 -9
- package/src/Util/EventEmitter.ts +17 -22
- package/src/Util/FileUtil.ts +11 -34
- package/src/Util/IURLSearchParams.ts +25 -0
- package/src/Util/InputCoordTranslator.ts +73 -0
- package/src/Util/RTCUtils.ts +23 -15
- package/src/VideoPlayer/StreamController.ts +6 -23
- package/src/VideoPlayer/VideoPlayer.ts +9 -30
- package/src/WebRtcPlayer/WebRtcPlayerController.ts +328 -690
- package/src/WebXR/WebXRController.ts +82 -94
- package/src/pixelstreamingfrontend.ts +6 -10
- package/types/AFK/AFKController.d.ts +0 -1
- package/types/Config/Config.d.ts +6 -5
- package/types/Config/SettingBase.d.ts +13 -0
- package/types/Config/SettingFlag.d.ts +1 -10
- package/types/Config/SettingNumber.d.ts +1 -5
- package/types/Config/SettingOption.d.ts +1 -10
- package/types/Config/SettingText.d.ts +1 -9
- package/types/DataChannel/DataChannelLatencyTestController.d.ts +1 -1
- package/types/Inputs/GamepadController.d.ts +22 -46
- package/types/Inputs/GamepadTypes.d.ts +7 -0
- package/types/Inputs/IInputController.d.ts +16 -0
- package/types/Inputs/InputClassesFactory.d.ts +7 -8
- package/types/Inputs/KeyCodes.d.ts +5 -0
- package/types/Inputs/KeyboardController.d.ts +17 -45
- package/types/Inputs/MouseController.d.ts +33 -68
- package/types/Inputs/MouseControllerHovering.d.ts +26 -0
- package/types/Inputs/MouseControllerLocked.d.ts +31 -0
- package/types/Inputs/TouchController.d.ts +19 -44
- package/types/Inputs/TouchControllerFake.d.ts +29 -0
- package/types/Inputs/XRGamepadController.d.ts +0 -7
- package/types/PeerConnectionController/PeerConnectionController.d.ts +10 -1
- package/types/PixelStreaming/PixelStreaming.d.ts +14 -2
- package/types/UI/OnScreenKeyboard.d.ts +2 -2
- package/types/Util/EventEmitter.d.ts +1 -1
- package/types/Util/IURLSearchParams.d.ts +9 -0
- package/types/Util/InputCoordTranslator.d.ts +29 -0
- package/types/VideoPlayer/StreamController.d.ts +0 -2
- package/types/WebRtcPlayer/WebRtcPlayerController.d.ts +19 -17
- package/types/pixelstreamingfrontend.d.ts +1 -1
- package/src/Inputs/FakeTouchController.ts +0 -199
- package/src/Inputs/HoveringMouseEvents.ts +0 -192
- package/src/Inputs/IMouseEvents.ts +0 -64
- package/src/Inputs/ITouchController.ts +0 -29
- package/src/Inputs/LockedMouseEvents.ts +0 -287
- package/src/Util/CoordinateConverter.ts +0 -290
- package/src/Util/EventListenerTracker.ts +0 -29
- package/types/Inputs/FakeTouchController.d.ts +0 -61
- package/types/Inputs/HoveringMouseEvents.d.ts +0 -56
- package/types/Inputs/IMouseEvents.d.ts +0 -53
- package/types/Inputs/ITouchController.d.ts +0 -24
- package/types/Inputs/LockedMouseEvents.d.ts +0 -80
- package/types/Util/CoordinateConverter.d.ts +0 -100
- package/types/Util/EventListenerTracker.d.ts +0 -14
|
@@ -36,13 +36,13 @@ import { MessageDirection } from '../UeInstanceMessage/StreamMessageController';
|
|
|
36
36
|
import {
|
|
37
37
|
DataChannelLatencyTestConfig,
|
|
38
38
|
DataChannelLatencyTestController
|
|
39
|
-
} from
|
|
39
|
+
} from '../DataChannel/DataChannelLatencyTestController';
|
|
40
40
|
import {
|
|
41
41
|
DataChannelLatencyTestResponse,
|
|
42
42
|
DataChannelLatencyTestResult
|
|
43
|
-
} from
|
|
43
|
+
} from '../DataChannel/DataChannelLatencyTestResults';
|
|
44
44
|
import { RTCUtils } from '../Util/RTCUtils';
|
|
45
|
-
|
|
45
|
+
import { IURLSearchParams } from '../Util/IURLSearchParams';
|
|
46
46
|
|
|
47
47
|
export interface PixelStreamingOverrides {
|
|
48
48
|
/** The DOM element where Pixel Streaming video and user input event handlers are attached to.
|
|
@@ -55,7 +55,7 @@ export interface PixelStreamingOverrides {
|
|
|
55
55
|
/**
|
|
56
56
|
* The key class for the browser side of a Pixel Streaming application, it includes:
|
|
57
57
|
* WebRTC handling, XR support, input handling, and emitters for lifetime and state change events.
|
|
58
|
-
* Users are encouraged to use this class as is, through composition, or extend it. In any case,
|
|
58
|
+
* Users are encouraged to use this class as is, through composition, or extend it. In any case,
|
|
59
59
|
* this will likely be the core of your Pixel Streaming experience in terms of functionality.
|
|
60
60
|
*/
|
|
61
61
|
export class PixelStreaming {
|
|
@@ -97,34 +97,23 @@ export class PixelStreaming {
|
|
|
97
97
|
this.configureSettings();
|
|
98
98
|
|
|
99
99
|
// setup WebRTC
|
|
100
|
-
this.setWebRtcPlayerController(
|
|
101
|
-
new WebRtcPlayerController(this.config, this)
|
|
102
|
-
);
|
|
100
|
+
this.setWebRtcPlayerController(new WebRtcPlayerController(this.config, this));
|
|
103
101
|
|
|
104
102
|
// Onscreen keyboard
|
|
105
|
-
this.onScreenKeyboardHelper = new OnScreenKeyboard(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.onScreenKeyboardHelper.unquantizeAndDenormalizeUnsigned = (
|
|
109
|
-
x: number,
|
|
110
|
-
y: number
|
|
111
|
-
) =>
|
|
112
|
-
this._webRtcController.requestUnquantizedAndDenormalizeUnsigned(
|
|
113
|
-
x,
|
|
114
|
-
y
|
|
115
|
-
);
|
|
103
|
+
this.onScreenKeyboardHelper = new OnScreenKeyboard(this.videoElementParent);
|
|
104
|
+
this.onScreenKeyboardHelper.unquantizeAndDenormalizeUnsigned = (x: number, y: number) =>
|
|
105
|
+
this._webRtcController.requestUnquantizedAndDenormalizeUnsigned(x, y);
|
|
116
106
|
this._activateOnScreenKeyboard = (command: any) =>
|
|
117
107
|
this.onScreenKeyboardHelper.showOnScreenKeyboard(command);
|
|
118
108
|
|
|
119
109
|
this._webXrController = new WebXRController(this._webRtcController);
|
|
120
110
|
|
|
121
|
-
this._setupWebRtcTCPRelayDetection = this._setupWebRtcTCPRelayDetection.bind(this)
|
|
111
|
+
this._setupWebRtcTCPRelayDetection = this._setupWebRtcTCPRelayDetection.bind(this);
|
|
122
112
|
|
|
123
113
|
// Add event listener for the webRtcConnected event
|
|
124
|
-
this._eventEmitter.addEventListener(
|
|
125
|
-
|
|
114
|
+
this._eventEmitter.addEventListener('webRtcConnected', (_: WebRtcConnectedEvent) => {
|
|
126
115
|
// Bind to the stats received event
|
|
127
|
-
this._eventEmitter.addEventListener(
|
|
116
|
+
this._eventEmitter.addEventListener('statsReceived', this._setupWebRtcTCPRelayDetection);
|
|
128
117
|
});
|
|
129
118
|
}
|
|
130
119
|
|
|
@@ -148,157 +137,89 @@ export class PixelStreaming {
|
|
|
148
137
|
(wantsQualityController: boolean) => {
|
|
149
138
|
// If the setting has been set to true (either programmatically or the user has flicked the toggle)
|
|
150
139
|
// and we aren't currently quality controller, send the request
|
|
151
|
-
if (
|
|
152
|
-
wantsQualityController === true &&
|
|
153
|
-
!this._webRtcController.isQualityController
|
|
154
|
-
) {
|
|
140
|
+
if (wantsQualityController === true && !this._webRtcController.isQualityController) {
|
|
155
141
|
this._webRtcController.sendRequestQualityControlOwnership();
|
|
156
142
|
}
|
|
157
143
|
}
|
|
158
144
|
);
|
|
159
145
|
|
|
160
|
-
this.config._addOnSettingChangedListener(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
this._webRtcController.setAfkEnabled(isAFKEnabled);
|
|
164
|
-
}
|
|
165
|
-
);
|
|
146
|
+
this.config._addOnSettingChangedListener(Flags.AFKDetection, (isAFKEnabled: boolean) => {
|
|
147
|
+
this._webRtcController.setAfkEnabled(isAFKEnabled);
|
|
148
|
+
});
|
|
166
149
|
|
|
167
|
-
this.config._addOnSettingChangedListener(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this._webRtcController.videoPlayer.updateVideoStreamSize();
|
|
171
|
-
}
|
|
172
|
-
);
|
|
150
|
+
this.config._addOnSettingChangedListener(Flags.MatchViewportResolution, () => {
|
|
151
|
+
this._webRtcController.videoPlayer.updateVideoStreamSize();
|
|
152
|
+
});
|
|
173
153
|
|
|
174
|
-
this.config._addOnSettingChangedListener(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
} Mouse`
|
|
182
|
-
);
|
|
183
|
-
this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(Flags.MouseInput));
|
|
184
|
-
}
|
|
185
|
-
);
|
|
154
|
+
this.config._addOnSettingChangedListener(Flags.HoveringMouseMode, (isHoveringMouse: boolean) => {
|
|
155
|
+
this.config.setFlagLabel(
|
|
156
|
+
Flags.HoveringMouseMode,
|
|
157
|
+
`Control Scheme: ${isHoveringMouse ? 'Hovering' : 'Locked'} Mouse`
|
|
158
|
+
);
|
|
159
|
+
this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(Flags.MouseInput));
|
|
160
|
+
});
|
|
186
161
|
|
|
187
162
|
// user input
|
|
188
|
-
this.config._addOnSettingChangedListener(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
this._webRtcController.setKeyboardInputEnabled(isEnabled);
|
|
192
|
-
}
|
|
193
|
-
);
|
|
163
|
+
this.config._addOnSettingChangedListener(Flags.KeyboardInput, (isEnabled: boolean) => {
|
|
164
|
+
this._webRtcController.setKeyboardInputEnabled(isEnabled);
|
|
165
|
+
});
|
|
194
166
|
|
|
195
|
-
this.config._addOnSettingChangedListener(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
this._webRtcController.setMouseInputEnabled(isEnabled);
|
|
199
|
-
}
|
|
200
|
-
);
|
|
167
|
+
this.config._addOnSettingChangedListener(Flags.MouseInput, (isEnabled: boolean) => {
|
|
168
|
+
this._webRtcController.setMouseInputEnabled(isEnabled);
|
|
169
|
+
});
|
|
201
170
|
|
|
202
171
|
this.config._addOnSettingChangedListener(
|
|
203
|
-
Flags.
|
|
204
|
-
(
|
|
205
|
-
this._webRtcController.setTouchInputEnabled(
|
|
172
|
+
Flags.FakeMouseWithTouches,
|
|
173
|
+
(_isFakeMouseEnabled: boolean) => {
|
|
174
|
+
this._webRtcController.setTouchInputEnabled(this.config.isFlagEnabled(Flags.TouchInput));
|
|
206
175
|
}
|
|
207
176
|
);
|
|
208
177
|
|
|
209
|
-
this.config._addOnSettingChangedListener(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
178
|
+
this.config._addOnSettingChangedListener(Flags.TouchInput, (isEnabled: boolean) => {
|
|
179
|
+
this._webRtcController.setTouchInputEnabled(isEnabled);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
this.config._addOnSettingChangedListener(Flags.GamepadInput, (isEnabled: boolean) => {
|
|
183
|
+
this._webRtcController.setGamePadInputEnabled(isEnabled);
|
|
184
|
+
});
|
|
215
185
|
|
|
216
186
|
// encoder settings
|
|
217
|
-
this.config._addOnNumericSettingChangedListener(
|
|
218
|
-
|
|
219
|
-
(newValue
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
'-------- Sending MinQP --------',
|
|
223
|
-
7
|
|
224
|
-
);
|
|
225
|
-
this._webRtcController.sendEncoderMinQP(newValue);
|
|
226
|
-
Logger.Log(
|
|
227
|
-
Logger.GetStackTrace(),
|
|
228
|
-
'-------------------------------------------',
|
|
229
|
-
7
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
);
|
|
187
|
+
this.config._addOnNumericSettingChangedListener(NumericParameters.MinQP, (newValue: number) => {
|
|
188
|
+
Logger.Info('-------- Sending MinQP --------');
|
|
189
|
+
this._webRtcController.sendEncoderMinQP(newValue);
|
|
190
|
+
Logger.Info('-------------------------------------------');
|
|
191
|
+
});
|
|
233
192
|
|
|
234
|
-
this.config._addOnNumericSettingChangedListener(
|
|
235
|
-
|
|
236
|
-
(newValue
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
'-------- Sending encoder settings --------',
|
|
240
|
-
7
|
|
241
|
-
);
|
|
242
|
-
this._webRtcController.sendEncoderMaxQP(newValue);
|
|
243
|
-
Logger.Log(
|
|
244
|
-
Logger.GetStackTrace(),
|
|
245
|
-
'-------------------------------------------',
|
|
246
|
-
7
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
);
|
|
193
|
+
this.config._addOnNumericSettingChangedListener(NumericParameters.MaxQP, (newValue: number) => {
|
|
194
|
+
Logger.Info('-------- Sending encoder settings --------');
|
|
195
|
+
this._webRtcController.sendEncoderMaxQP(newValue);
|
|
196
|
+
Logger.Info('-------------------------------------------');
|
|
197
|
+
});
|
|
250
198
|
|
|
251
199
|
// WebRTC settings
|
|
252
200
|
this.config._addOnNumericSettingChangedListener(
|
|
253
201
|
NumericParameters.WebRTCMinBitrate,
|
|
254
202
|
(newValue: number) => {
|
|
255
|
-
Logger.
|
|
256
|
-
Logger.GetStackTrace(),
|
|
257
|
-
'-------- Sending web rtc settings --------',
|
|
258
|
-
7
|
|
259
|
-
);
|
|
203
|
+
Logger.Info('-------- Sending web rtc settings --------');
|
|
260
204
|
this._webRtcController.sendWebRTCMinBitrate(newValue * 1000 /* kbps to bps */);
|
|
261
|
-
Logger.
|
|
262
|
-
Logger.GetStackTrace(),
|
|
263
|
-
'-------------------------------------------',
|
|
264
|
-
7
|
|
265
|
-
);
|
|
205
|
+
Logger.Info('-------------------------------------------');
|
|
266
206
|
}
|
|
267
207
|
);
|
|
268
208
|
|
|
269
209
|
this.config._addOnNumericSettingChangedListener(
|
|
270
210
|
NumericParameters.WebRTCMaxBitrate,
|
|
271
211
|
(newValue: number) => {
|
|
272
|
-
Logger.
|
|
273
|
-
Logger.GetStackTrace(),
|
|
274
|
-
'-------- Sending web rtc settings --------',
|
|
275
|
-
7
|
|
276
|
-
);
|
|
212
|
+
Logger.Info('-------- Sending web rtc settings --------');
|
|
277
213
|
this._webRtcController.sendWebRTCMaxBitrate(newValue * 1000 /* kbps to bps */);
|
|
278
|
-
Logger.
|
|
279
|
-
Logger.GetStackTrace(),
|
|
280
|
-
'-------------------------------------------',
|
|
281
|
-
7
|
|
282
|
-
);
|
|
214
|
+
Logger.Info('-------------------------------------------');
|
|
283
215
|
}
|
|
284
216
|
);
|
|
285
217
|
|
|
286
|
-
this.config._addOnNumericSettingChangedListener(
|
|
287
|
-
|
|
288
|
-
(newValue
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
'-------- Sending web rtc settings --------',
|
|
292
|
-
7
|
|
293
|
-
);
|
|
294
|
-
this._webRtcController.sendWebRTCFps(newValue);
|
|
295
|
-
Logger.Log(
|
|
296
|
-
Logger.GetStackTrace(),
|
|
297
|
-
'-------------------------------------------',
|
|
298
|
-
7
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
);
|
|
218
|
+
this.config._addOnNumericSettingChangedListener(NumericParameters.WebRTCFPS, (newValue: number) => {
|
|
219
|
+
Logger.Info('-------- Sending web rtc settings --------');
|
|
220
|
+
this._webRtcController.sendWebRTCFps(newValue);
|
|
221
|
+
Logger.Info('-------------------------------------------');
|
|
222
|
+
});
|
|
302
223
|
|
|
303
224
|
this.config._addOnOptionSettingChangedListener(
|
|
304
225
|
OptionParameters.PreferredCodec,
|
|
@@ -333,14 +254,11 @@ export class PixelStreaming {
|
|
|
333
254
|
* Instantiate the WebRTCPlayerController interface to provide WebRTCPlayerController functionality within this class and set up anything that requires it
|
|
334
255
|
* @param webRtcPlayerController - a WebRtcPlayerController controller instance
|
|
335
256
|
*/
|
|
336
|
-
private setWebRtcPlayerController(
|
|
337
|
-
webRtcPlayerController: WebRtcPlayerController
|
|
338
|
-
) {
|
|
257
|
+
private setWebRtcPlayerController(webRtcPlayerController: WebRtcPlayerController) {
|
|
339
258
|
this._webRtcController = webRtcPlayerController;
|
|
340
259
|
|
|
341
260
|
this._webRtcController.setPreferredCodec(
|
|
342
|
-
this.config.getSettingOption(OptionParameters.PreferredCodec)
|
|
343
|
-
.selected
|
|
261
|
+
this.config.getSettingOption(OptionParameters.PreferredCodec).selected
|
|
344
262
|
);
|
|
345
263
|
this._webRtcController.resizePlayerStyle();
|
|
346
264
|
|
|
@@ -362,7 +280,7 @@ export class PixelStreaming {
|
|
|
362
280
|
*/
|
|
363
281
|
public reconnect() {
|
|
364
282
|
this._eventEmitter.dispatchEvent(new StreamReconnectEvent());
|
|
365
|
-
this._webRtcController.tryReconnect(
|
|
283
|
+
this._webRtcController.tryReconnect('Reconnecting...');
|
|
366
284
|
}
|
|
367
285
|
|
|
368
286
|
/**
|
|
@@ -393,36 +311,35 @@ export class PixelStreaming {
|
|
|
393
311
|
}
|
|
394
312
|
}
|
|
395
313
|
|
|
396
|
-
/**
|
|
314
|
+
/**
|
|
397
315
|
* Will unmute the microphone track which is sent to Unreal Engine.
|
|
398
316
|
* By default, will only unmute an existing mic track.
|
|
399
|
-
*
|
|
317
|
+
*
|
|
400
318
|
* @param forceEnable Can be used for cases when this object wasn't initialized with a mic track.
|
|
401
319
|
* If this parameter is true, the connection will be restarted with a microphone.
|
|
402
320
|
* Warning: this takes some time, as a full renegotiation and reconnection will happen.
|
|
403
321
|
*/
|
|
404
|
-
public unmuteMicrophone(forceEnable = false)
|
|
322
|
+
public unmuteMicrophone(forceEnable = false): void {
|
|
405
323
|
// If there's an existing mic track, we just set muted state
|
|
406
324
|
if (this.config.isFlagEnabled('UseMic')) {
|
|
407
325
|
this.setMicrophoneMuted(false);
|
|
408
326
|
return;
|
|
409
327
|
}
|
|
410
|
-
|
|
328
|
+
|
|
411
329
|
// If there's no pre-existing mic track, and caller is ok with full reset, we enable and reset
|
|
412
330
|
if (forceEnable) {
|
|
413
|
-
this.config.setFlagEnabled(
|
|
331
|
+
this.config.setFlagEnabled('UseMic', true);
|
|
414
332
|
this.reconnect();
|
|
415
333
|
return;
|
|
416
334
|
}
|
|
417
|
-
|
|
335
|
+
|
|
418
336
|
// If we prefer not to force a reconnection, just warn the user that this operation didn't happen
|
|
419
337
|
Logger.Warning(
|
|
420
|
-
Logger.GetStackTrace(),
|
|
421
338
|
'Trying to unmute mic, but PixelStreaming was initialized with no microphone track. Call with forceEnable == true to re-connect with a mic track.'
|
|
422
339
|
);
|
|
423
340
|
}
|
|
424
341
|
|
|
425
|
-
public muteMicrophone()
|
|
342
|
+
public muteMicrophone(): void {
|
|
426
343
|
if (this.config.isFlagEnabled('UseMic')) {
|
|
427
344
|
this.setMicrophoneMuted(true);
|
|
428
345
|
return;
|
|
@@ -430,20 +347,68 @@ export class PixelStreaming {
|
|
|
430
347
|
|
|
431
348
|
// If there wasn't a mic track, just let user know there's nothing to mute
|
|
432
349
|
Logger.Info(
|
|
433
|
-
Logger.GetStackTrace(),
|
|
434
350
|
'Trying to mute mic, but PixelStreaming has no microphone track, so sending sound is already disabled.'
|
|
435
351
|
);
|
|
436
352
|
}
|
|
437
353
|
|
|
438
|
-
private setMicrophoneMuted(mute: boolean)
|
|
439
|
-
|
|
440
|
-
|
|
354
|
+
private setMicrophoneMuted(mute: boolean): void {
|
|
355
|
+
for (const transceiver of this._webRtcController?.peerConnectionController?.peerConnection?.getTransceivers() ??
|
|
356
|
+
[]) {
|
|
441
357
|
if (RTCUtils.canTransceiverSendAudio(transceiver)) {
|
|
442
358
|
transceiver.sender.track.enabled = !mute;
|
|
443
359
|
}
|
|
444
360
|
}
|
|
445
361
|
}
|
|
446
362
|
|
|
363
|
+
/**
|
|
364
|
+
* Will unmute the video track which is sent to Unreal Engine.
|
|
365
|
+
* By default, will only unmute an existing video track.
|
|
366
|
+
*
|
|
367
|
+
* @param forceEnable Can be used for cases when this object wasn't initialized with a video track.
|
|
368
|
+
* If this parameter is true, the connection will be restarted with a camera.
|
|
369
|
+
* Warning: this takes some time, as a full renegotiation and reconnection will happen.
|
|
370
|
+
*/
|
|
371
|
+
public unmuteCamera(forceEnable = false): void {
|
|
372
|
+
// If there's an existing video track, we just set muted state
|
|
373
|
+
if (this.config.isFlagEnabled('UseCamera')) {
|
|
374
|
+
this.setCameraMuted(false);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// If there's no pre-existing video track, and caller is ok with full reset, we enable and reset
|
|
379
|
+
if (forceEnable) {
|
|
380
|
+
this.config.setFlagEnabled('UseCamera', true);
|
|
381
|
+
this.reconnect();
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// If we prefer not to force a reconnection, just warn the user that this operation didn't happen
|
|
386
|
+
Logger.Warning(
|
|
387
|
+
'Trying to unmute video, but PixelStreaming was initialized with no video track. Call with forceEnable == true to re-connect with a video track.'
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
public muteCamera(): void {
|
|
392
|
+
if (this.config.isFlagEnabled('UseCamera')) {
|
|
393
|
+
this.setCameraMuted(true);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// If there wasn't a mic track, just let user know there's nothing to mute
|
|
398
|
+
Logger.Info(
|
|
399
|
+
'Trying to mute camera, but PixelStreaming has no video track, so sending video is already disabled.'
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
private setCameraMuted(mute: boolean): void {
|
|
404
|
+
for (const transceiver of this._webRtcController?.peerConnectionController?.peerConnection?.getTransceivers() ??
|
|
405
|
+
[]) {
|
|
406
|
+
if (RTCUtils.canTransceiverSendVideo(transceiver)) {
|
|
407
|
+
transceiver.sender.track.enabled = !mute;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
447
412
|
/**
|
|
448
413
|
* Emit an event on auto connecting
|
|
449
414
|
*/
|
|
@@ -514,15 +479,11 @@ export class PixelStreaming {
|
|
|
514
479
|
* @param latency - latency test results object
|
|
515
480
|
*/
|
|
516
481
|
_onLatencyTestResult(latencyTimings: LatencyTestResults) {
|
|
517
|
-
this._eventEmitter.dispatchEvent(
|
|
518
|
-
new LatencyTestResultEvent({ latencyTimings })
|
|
519
|
-
);
|
|
482
|
+
this._eventEmitter.dispatchEvent(new LatencyTestResultEvent({ latencyTimings }));
|
|
520
483
|
}
|
|
521
484
|
|
|
522
485
|
_onDataChannelLatencyTestResponse(response: DataChannelLatencyTestResponse) {
|
|
523
|
-
this._eventEmitter.dispatchEvent(
|
|
524
|
-
new DataChannelLatencyTestResponseEvent({ response })
|
|
525
|
-
);
|
|
486
|
+
this._eventEmitter.dispatchEvent(new DataChannelLatencyTestResponseEvent({ response }));
|
|
526
487
|
}
|
|
527
488
|
|
|
528
489
|
/**
|
|
@@ -540,9 +501,7 @@ export class PixelStreaming {
|
|
|
540
501
|
this._webRtcController.videoAvgQp
|
|
541
502
|
);
|
|
542
503
|
|
|
543
|
-
this._eventEmitter.dispatchEvent(
|
|
544
|
-
new StatsReceivedEvent({ aggregatedStats: videoStats })
|
|
545
|
-
);
|
|
504
|
+
this._eventEmitter.dispatchEvent(new StatsReceivedEvent({ aggregatedStats: videoStats }));
|
|
546
505
|
}
|
|
547
506
|
|
|
548
507
|
/**
|
|
@@ -550,9 +509,7 @@ export class PixelStreaming {
|
|
|
550
509
|
* @param QP - the quality number of the stream
|
|
551
510
|
*/
|
|
552
511
|
_onVideoEncoderAvgQP(QP: number) {
|
|
553
|
-
this._eventEmitter.dispatchEvent(
|
|
554
|
-
new VideoEncoderAvgQPEvent({ avgQP: QP })
|
|
555
|
-
);
|
|
512
|
+
this._eventEmitter.dispatchEvent(new VideoEncoderAvgQPEvent({ avgQP: QP }));
|
|
556
513
|
}
|
|
557
514
|
|
|
558
515
|
/**
|
|
@@ -560,60 +517,51 @@ export class PixelStreaming {
|
|
|
560
517
|
* @param settings - initial UE app settings
|
|
561
518
|
*/
|
|
562
519
|
_onInitialSettings(settings: InitialSettings) {
|
|
563
|
-
this._eventEmitter.dispatchEvent(
|
|
564
|
-
new InitialSettingsEvent({ settings })
|
|
565
|
-
);
|
|
520
|
+
this._eventEmitter.dispatchEvent(new InitialSettingsEvent({ settings }));
|
|
566
521
|
if (settings.PixelStreamingSettings) {
|
|
567
|
-
this.allowConsoleCommands =
|
|
568
|
-
settings.PixelStreamingSettings.AllowPixelStreamingCommands ?? false;
|
|
522
|
+
this.allowConsoleCommands = settings.PixelStreamingSettings.AllowPixelStreamingCommands ?? false;
|
|
569
523
|
if (this.allowConsoleCommands === false) {
|
|
570
524
|
Logger.Info(
|
|
571
|
-
Logger.GetStackTrace(),
|
|
572
525
|
'-AllowPixelStreamingCommands=false, sending arbitrary console commands from browser to UE is disabled.'
|
|
573
526
|
);
|
|
574
527
|
}
|
|
575
528
|
}
|
|
576
529
|
|
|
577
530
|
const useUrlParams = this.config.useUrlParams;
|
|
578
|
-
const urlParams = new
|
|
579
|
-
Logger.Info(
|
|
580
|
-
Logger.GetStackTrace(),
|
|
581
|
-
`using URL parameters ${useUrlParams}`
|
|
582
|
-
);
|
|
531
|
+
const urlParams = new IURLSearchParams(window.location.search);
|
|
532
|
+
Logger.Info(`using URL parameters ${useUrlParams}`);
|
|
583
533
|
if (settings.EncoderSettings) {
|
|
584
534
|
this.config.setNumericSetting(
|
|
585
535
|
NumericParameters.MinQP,
|
|
586
536
|
// If a setting is set in the URL, make sure we respect that value as opposed to what the application sends us
|
|
587
|
-
|
|
588
|
-
? Number.parseFloat(urlParams.get(NumericParameters.MinQP))
|
|
537
|
+
useUrlParams && urlParams.has(NumericParameters.MinQP)
|
|
538
|
+
? Number.parseFloat(urlParams.get(NumericParameters.MinQP))
|
|
589
539
|
: settings.EncoderSettings.MinQP
|
|
590
540
|
);
|
|
591
541
|
|
|
592
|
-
|
|
593
542
|
this.config.setNumericSetting(
|
|
594
543
|
NumericParameters.MaxQP,
|
|
595
|
-
|
|
596
|
-
? Number.parseFloat(urlParams.get(NumericParameters.MaxQP))
|
|
544
|
+
useUrlParams && urlParams.has(NumericParameters.MaxQP)
|
|
545
|
+
? Number.parseFloat(urlParams.get(NumericParameters.MaxQP))
|
|
597
546
|
: settings.EncoderSettings.MaxQP
|
|
598
547
|
);
|
|
599
548
|
}
|
|
600
549
|
if (settings.WebRTCSettings) {
|
|
601
550
|
this.config.setNumericSetting(
|
|
602
551
|
NumericParameters.WebRTCMinBitrate,
|
|
603
|
-
|
|
552
|
+
useUrlParams && urlParams.has(NumericParameters.WebRTCMinBitrate)
|
|
604
553
|
? Number.parseFloat(urlParams.get(NumericParameters.WebRTCMinBitrate))
|
|
605
|
-
:
|
|
554
|
+
: settings.WebRTCSettings.MinBitrate / 1000 /* bps to kbps */
|
|
606
555
|
);
|
|
607
556
|
this.config.setNumericSetting(
|
|
608
557
|
NumericParameters.WebRTCMaxBitrate,
|
|
609
|
-
|
|
558
|
+
useUrlParams && urlParams.has(NumericParameters.WebRTCMaxBitrate)
|
|
610
559
|
? Number.parseFloat(urlParams.get(NumericParameters.WebRTCMaxBitrate))
|
|
611
|
-
:
|
|
612
|
-
|
|
560
|
+
: settings.WebRTCSettings.MaxBitrate / 1000 /* bps to kbps */
|
|
613
561
|
);
|
|
614
562
|
this.config.setNumericSetting(
|
|
615
563
|
NumericParameters.WebRTCFPS,
|
|
616
|
-
|
|
564
|
+
useUrlParams && urlParams.has(NumericParameters.WebRTCFPS)
|
|
617
565
|
? Number.parseFloat(urlParams.get(NumericParameters.WebRTCFPS))
|
|
618
566
|
: settings.WebRTCSettings.FPS
|
|
619
567
|
);
|
|
@@ -625,37 +573,37 @@ export class PixelStreaming {
|
|
|
625
573
|
* @param hasQualityOwnership - does this user have quality ownership of the stream true / false
|
|
626
574
|
*/
|
|
627
575
|
_onQualityControlOwnership(hasQualityOwnership: boolean) {
|
|
628
|
-
this.config.setFlagEnabled(
|
|
629
|
-
Flags.IsQualityController,
|
|
630
|
-
hasQualityOwnership
|
|
631
|
-
);
|
|
576
|
+
this.config.setFlagEnabled(Flags.IsQualityController, hasQualityOwnership);
|
|
632
577
|
}
|
|
633
578
|
|
|
634
579
|
_onPlayerCount(playerCount: number) {
|
|
635
|
-
this._eventEmitter.dispatchEvent(
|
|
636
|
-
new PlayerCountEvent({ count: playerCount })
|
|
637
|
-
);
|
|
580
|
+
this._eventEmitter.dispatchEvent(new PlayerCountEvent({ count: playerCount }));
|
|
638
581
|
}
|
|
639
582
|
|
|
640
|
-
// Sets up to emit the webrtc tcp relay detect event
|
|
583
|
+
// Sets up to emit the webrtc tcp relay detect event
|
|
641
584
|
_setupWebRtcTCPRelayDetection(statsReceivedEvent: StatsReceivedEvent) {
|
|
642
585
|
// Get the active candidate pair
|
|
643
586
|
const activeCandidatePair = statsReceivedEvent.data.aggregatedStats.getActiveCandidatePair();
|
|
644
|
-
|
|
587
|
+
|
|
645
588
|
// Check if the active candidate pair is not null
|
|
646
589
|
if (activeCandidatePair != null) {
|
|
647
|
-
|
|
648
590
|
// Get the local candidate assigned to the active candidate pair
|
|
649
|
-
const localCandidate = statsReceivedEvent.data.aggregatedStats.localCandidates.find(
|
|
591
|
+
const localCandidate = statsReceivedEvent.data.aggregatedStats.localCandidates.find(
|
|
592
|
+
(candidate) => candidate.id == activeCandidatePair.localCandidateId,
|
|
593
|
+
null
|
|
594
|
+
);
|
|
650
595
|
|
|
651
596
|
// Check if the local candidate is not null, candidate type is relay and the relay protocol is tcp
|
|
652
|
-
if (
|
|
653
|
-
|
|
597
|
+
if (
|
|
598
|
+
localCandidate != null &&
|
|
599
|
+
localCandidate.candidateType == 'relay' &&
|
|
600
|
+
localCandidate.relayProtocol == 'tcp'
|
|
601
|
+
) {
|
|
654
602
|
// Send the web rtc tcp relay detected event
|
|
655
603
|
this._eventEmitter.dispatchEvent(new WebRtcTCPRelayDetectedEvent());
|
|
656
604
|
}
|
|
657
605
|
// The check is completed and the stats listen event can be removed
|
|
658
|
-
this._eventEmitter.removeEventListener(
|
|
606
|
+
this._eventEmitter.removeEventListener('statsReceived', this._setupWebRtcTCPRelayDetection);
|
|
659
607
|
}
|
|
660
608
|
}
|
|
661
609
|
|
|
@@ -684,14 +632,12 @@ export class PixelStreaming {
|
|
|
684
632
|
this._dataChannelLatencyTestController = new DataChannelLatencyTestController(
|
|
685
633
|
this._webRtcController.sendDataChannelLatencyTest.bind(this._webRtcController),
|
|
686
634
|
(result: DataChannelLatencyTestResult) => {
|
|
687
|
-
this._eventEmitter.dispatchEvent(new DataChannelLatencyTestResultEvent(
|
|
688
|
-
});
|
|
689
|
-
this.addEventListener(
|
|
690
|
-
"dataChannelLatencyTestResponse",
|
|
691
|
-
({data: {response} }) => {
|
|
692
|
-
this._dataChannelLatencyTestController.receive(response);
|
|
635
|
+
this._eventEmitter.dispatchEvent(new DataChannelLatencyTestResultEvent({ result }));
|
|
693
636
|
}
|
|
694
|
-
)
|
|
637
|
+
);
|
|
638
|
+
this.addEventListener('dataChannelLatencyTestResponse', ({ data: { response } }) => {
|
|
639
|
+
this._dataChannelLatencyTestController.receive(response);
|
|
640
|
+
});
|
|
695
641
|
}
|
|
696
642
|
return this._dataChannelLatencyTestController.start(config);
|
|
697
643
|
}
|
|
@@ -769,10 +715,7 @@ export class PixelStreaming {
|
|
|
769
715
|
* @param name - The name of the response handler
|
|
770
716
|
* @param listener - The method to be activated when a message is received
|
|
771
717
|
*/
|
|
772
|
-
public addResponseEventListener(
|
|
773
|
-
name: string,
|
|
774
|
-
listener: (response: string) => void
|
|
775
|
-
) {
|
|
718
|
+
public addResponseEventListener(name: string, listener: (response: string) => void) {
|
|
776
719
|
this._webRtcController.responseController.addResponseEventListener(name, listener);
|
|
777
720
|
}
|
|
778
721
|
|
|
@@ -792,7 +735,7 @@ export class PixelStreaming {
|
|
|
792
735
|
public dispatchEvent(e: PixelStreamingEvent): boolean {
|
|
793
736
|
return this._eventEmitter.dispatchEvent(e);
|
|
794
737
|
}
|
|
795
|
-
|
|
738
|
+
|
|
796
739
|
/**
|
|
797
740
|
* Register an event handler.
|
|
798
741
|
* @param type event name
|
|
@@ -829,10 +772,14 @@ export class PixelStreaming {
|
|
|
829
772
|
* This function is useful if you need to programmatically construct your signalling server URL.
|
|
830
773
|
* @param signallingUrlBuilderFunc A function that generates a signalling server url.
|
|
831
774
|
*/
|
|
832
|
-
public setSignallingUrlBuilder(signallingUrlBuilderFunc: ()=>string) {
|
|
775
|
+
public setSignallingUrlBuilder(signallingUrlBuilderFunc: () => string) {
|
|
833
776
|
this._webRtcController.signallingUrlBuilder = signallingUrlBuilderFunc;
|
|
834
777
|
}
|
|
835
778
|
|
|
779
|
+
public get webRtcController() {
|
|
780
|
+
return this._webRtcController;
|
|
781
|
+
}
|
|
782
|
+
|
|
836
783
|
/**
|
|
837
784
|
* Public getter for the websocket controller. Access to this property allows you to send
|
|
838
785
|
* custom websocket messages.
|
|
@@ -848,21 +795,22 @@ export class PixelStreaming {
|
|
|
848
795
|
return this._webXrController;
|
|
849
796
|
}
|
|
850
797
|
|
|
851
|
-
public registerMessageHandler(
|
|
852
|
-
|
|
853
|
-
|
|
798
|
+
public registerMessageHandler(
|
|
799
|
+
name: string,
|
|
800
|
+
direction: MessageDirection,
|
|
801
|
+
handler?: (data: ArrayBuffer | Array<number | string>) => void
|
|
802
|
+
) {
|
|
803
|
+
if (direction === MessageDirection.FromStreamer && typeof handler === 'undefined') {
|
|
804
|
+
Logger.Warning(`Unable to register an undefined handler for ${name}`);
|
|
854
805
|
return;
|
|
855
806
|
}
|
|
856
807
|
|
|
857
|
-
if(direction === MessageDirection.ToStreamer && typeof handler === 'undefined') {
|
|
808
|
+
if (direction === MessageDirection.ToStreamer && typeof handler === 'undefined') {
|
|
858
809
|
this._webRtcController.streamMessageController.registerMessageHandler(
|
|
859
810
|
direction,
|
|
860
811
|
name,
|
|
861
812
|
(data: Array<number | string>) =>
|
|
862
|
-
|
|
863
|
-
name,
|
|
864
|
-
data
|
|
865
|
-
)
|
|
813
|
+
this._webRtcController.sendMessageController.sendMessageToStreamer(name, data)
|
|
866
814
|
);
|
|
867
815
|
} else {
|
|
868
816
|
this._webRtcController.streamMessageController.registerMessageHandler(
|