@epicgames-ps/lib-pixelstreamingfrontend-ue5.5 0.3.0 → 0.3.2
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/dist/commonjs/AFK/AFKController.js +109 -109
- package/dist/commonjs/Config/Config.js +559 -559
- package/dist/commonjs/Config/SettingBase.js +98 -98
- package/dist/commonjs/Config/SettingFlag.js +49 -49
- package/dist/commonjs/Config/SettingNumber.js +83 -83
- package/dist/commonjs/Config/SettingOption.js +84 -84
- package/dist/commonjs/Config/SettingText.js +42 -42
- package/dist/commonjs/DataChannel/DataChannelController.js +106 -106
- package/dist/commonjs/DataChannel/DataChannelLatencyTestController.js +94 -94
- package/dist/commonjs/DataChannel/DataChannelLatencyTestResults.js +18 -18
- package/dist/commonjs/DataChannel/DataChannelSender.js +43 -43
- package/dist/commonjs/DataChannel/InitialSettings.js +41 -41
- package/dist/commonjs/DataChannel/LatencyTestResults.js +60 -60
- package/dist/commonjs/FreezeFrame/FreezeFrame.js +93 -93
- package/dist/commonjs/FreezeFrame/FreezeFrameController.js +95 -95
- package/dist/commonjs/Inputs/GamepadController.js +188 -188
- package/dist/commonjs/Inputs/GamepadTypes.js +21 -21
- package/dist/commonjs/Inputs/IInputController.js +2 -2
- package/dist/commonjs/Inputs/InputClassesFactory.js +96 -96
- package/dist/commonjs/Inputs/KeyCodes.js +112 -112
- package/dist/commonjs/Inputs/KeyboardController.js +137 -137
- package/dist/commonjs/Inputs/MouseButtons.js +28 -28
- package/dist/commonjs/Inputs/MouseController.js +97 -97
- package/dist/commonjs/Inputs/MouseControllerHovering.js +93 -93
- package/dist/commonjs/Inputs/MouseControllerLocked.js +153 -153
- package/dist/commonjs/Inputs/SpecialKeyCodes.js +19 -19
- package/dist/commonjs/Inputs/TouchController.js +123 -123
- package/dist/commonjs/Inputs/TouchController.js.map +1 -1
- package/dist/commonjs/Inputs/TouchControllerFake.js +91 -91
- package/dist/commonjs/Inputs/XRGamepadController.js +124 -124
- package/dist/commonjs/PeerConnectionController/AggregatedStats.js +252 -252
- package/dist/commonjs/PeerConnectionController/CandidatePairStats.js +10 -10
- package/dist/commonjs/PeerConnectionController/CandidateStat.js +10 -10
- package/dist/commonjs/PeerConnectionController/CodecStats.js +10 -10
- package/dist/commonjs/PeerConnectionController/DataChannelStats.js +10 -10
- package/dist/commonjs/PeerConnectionController/InboundRTPStats.js +22 -22
- package/dist/commonjs/PeerConnectionController/InboundTrackStats.js +10 -10
- package/dist/commonjs/PeerConnectionController/OutBoundRTPStats.js +16 -16
- package/dist/commonjs/PeerConnectionController/PeerConnectionController.js +584 -584
- package/dist/commonjs/PeerConnectionController/SessionStats.js +10 -10
- package/dist/commonjs/PeerConnectionController/StreamStats.js +10 -10
- package/dist/commonjs/PixelStreaming/PixelStreaming.js +607 -607
- package/dist/commonjs/UI/OnScreenKeyboard.js +82 -82
- package/dist/commonjs/UeInstanceMessage/ResponseController.js +38 -38
- package/dist/commonjs/UeInstanceMessage/SendMessageController.js +120 -120
- package/dist/commonjs/UeInstanceMessage/StreamMessageController.js +210 -210
- package/dist/commonjs/UeInstanceMessage/ToStreamerMessagesController.js +49 -49
- package/dist/commonjs/Util/EventEmitter.js +386 -386
- package/dist/commonjs/Util/FileUtil.js +108 -108
- package/dist/commonjs/Util/IURLSearchParams.js +25 -25
- package/dist/commonjs/Util/InputCoordTranslator.js +49 -49
- package/dist/commonjs/Util/RTCUtils.js +40 -40
- package/dist/commonjs/VideoPlayer/StreamController.js +67 -67
- package/dist/commonjs/VideoPlayer/VideoPlayer.js +177 -177
- package/dist/commonjs/WebRtcPlayer/WebRtcPlayerController.js +1221 -1221
- package/dist/commonjs/WebXR/WebXRController.js +335 -335
- package/dist/commonjs/pixelstreamingfrontend.js +70 -70
- package/dist/esm/AFK/AFKController.js +105 -105
- package/dist/esm/Config/Config.js +551 -551
- package/dist/esm/Config/SettingBase.js +94 -94
- package/dist/esm/Config/SettingFlag.js +45 -45
- package/dist/esm/Config/SettingNumber.js +79 -79
- package/dist/esm/Config/SettingOption.js +80 -80
- package/dist/esm/Config/SettingText.js +38 -38
- package/dist/esm/DataChannel/DataChannelController.js +102 -102
- package/dist/esm/DataChannel/DataChannelLatencyTestController.js +90 -90
- package/dist/esm/DataChannel/DataChannelLatencyTestResults.js +14 -14
- package/dist/esm/DataChannel/DataChannelSender.js +39 -39
- package/dist/esm/DataChannel/InitialSettings.js +34 -34
- package/dist/esm/DataChannel/LatencyTestResults.js +56 -56
- package/dist/esm/FreezeFrame/FreezeFrame.js +89 -89
- package/dist/esm/FreezeFrame/FreezeFrameController.js +91 -91
- package/dist/esm/Inputs/GamepadController.js +184 -184
- package/dist/esm/Inputs/GamepadTypes.js +17 -17
- package/dist/esm/Inputs/IInputController.js +1 -1
- package/dist/esm/Inputs/InputClassesFactory.js +91 -91
- package/dist/esm/Inputs/KeyCodes.js +109 -109
- package/dist/esm/Inputs/KeyboardController.js +133 -133
- package/dist/esm/Inputs/MouseButtons.js +23 -23
- package/dist/esm/Inputs/MouseController.js +93 -93
- package/dist/esm/Inputs/MouseControllerHovering.js +89 -89
- package/dist/esm/Inputs/MouseControllerLocked.js +149 -149
- package/dist/esm/Inputs/SpecialKeyCodes.js +15 -15
- package/dist/esm/Inputs/TouchController.js +119 -119
- package/dist/esm/Inputs/TouchController.js.map +1 -1
- package/dist/esm/Inputs/TouchControllerFake.js +87 -87
- package/dist/esm/Inputs/XRGamepadController.js +120 -120
- package/dist/esm/PeerConnectionController/AggregatedStats.js +248 -248
- package/dist/esm/PeerConnectionController/CandidatePairStats.js +6 -6
- package/dist/esm/PeerConnectionController/CandidateStat.js +6 -6
- package/dist/esm/PeerConnectionController/CodecStats.js +6 -6
- package/dist/esm/PeerConnectionController/DataChannelStats.js +6 -6
- package/dist/esm/PeerConnectionController/InboundRTPStats.js +16 -16
- package/dist/esm/PeerConnectionController/InboundTrackStats.js +6 -6
- package/dist/esm/PeerConnectionController/OutBoundRTPStats.js +11 -11
- package/dist/esm/PeerConnectionController/PeerConnectionController.js +580 -580
- package/dist/esm/PeerConnectionController/SessionStats.js +6 -6
- package/dist/esm/PeerConnectionController/StreamStats.js +6 -6
- package/dist/esm/PixelStreaming/PixelStreaming.js +603 -603
- package/dist/esm/UI/OnScreenKeyboard.js +78 -78
- package/dist/esm/UeInstanceMessage/ResponseController.js +34 -34
- package/dist/esm/UeInstanceMessage/SendMessageController.js +116 -116
- package/dist/esm/UeInstanceMessage/StreamMessageController.js +205 -205
- package/dist/esm/UeInstanceMessage/ToStreamerMessagesController.js +45 -45
- package/dist/esm/Util/EventEmitter.js +345 -345
- package/dist/esm/Util/FileUtil.js +103 -103
- package/dist/esm/Util/IURLSearchParams.js +21 -21
- package/dist/esm/Util/InputCoordTranslator.js +45 -45
- package/dist/esm/Util/RTCUtils.js +36 -36
- package/dist/esm/VideoPlayer/StreamController.js +63 -63
- package/dist/esm/VideoPlayer/VideoPlayer.js +173 -173
- package/dist/esm/WebRtcPlayer/WebRtcPlayerController.js +1217 -1217
- package/dist/esm/WebXR/WebXRController.js +331 -331
- package/dist/esm/pixelstreamingfrontend.js +24 -24
- package/dist/types/AFK/AFKController.d.ts +38 -38
- package/dist/types/Config/Config.d.ts +220 -220
- package/dist/types/Config/SettingBase.d.ts +43 -43
- package/dist/types/Config/SettingFlag.d.ts +24 -24
- package/dist/types/Config/SettingNumber.d.ts +41 -41
- package/dist/types/Config/SettingOption.d.ts +41 -41
- package/dist/types/Config/SettingText.d.ts +21 -21
- package/dist/types/DataChannel/DataChannelController.d.ts +59 -59
- package/dist/types/DataChannel/DataChannelLatencyTestController.d.ts +25 -25
- package/dist/types/DataChannel/DataChannelLatencyTestResults.d.ts +46 -46
- package/dist/types/DataChannel/DataChannelSender.d.ts +21 -21
- package/dist/types/DataChannel/InitialSettings.d.ts +44 -44
- package/dist/types/DataChannel/LatencyTestResults.d.ts +31 -31
- package/dist/types/FreezeFrame/FreezeFrame.d.ts +36 -36
- package/dist/types/FreezeFrame/FreezeFrameController.d.ts +37 -37
- package/dist/types/Inputs/GamepadController.d.ts +61 -61
- package/dist/types/Inputs/GamepadTypes.d.ts +15 -15
- package/dist/types/Inputs/IInputController.d.ts +16 -16
- package/dist/types/Inputs/InputClassesFactory.d.ts +53 -53
- package/dist/types/Inputs/KeyCodes.d.ts +5 -5
- package/dist/types/Inputs/KeyboardController.d.ts +34 -34
- package/dist/types/Inputs/MouseButtons.d.ts +22 -22
- package/dist/types/Inputs/MouseController.d.ts +40 -40
- package/dist/types/Inputs/MouseControllerHovering.d.ts +26 -26
- package/dist/types/Inputs/MouseControllerLocked.d.ts +31 -31
- package/dist/types/Inputs/SpecialKeyCodes.d.ts +14 -14
- package/dist/types/Inputs/TouchController.d.ts +28 -28
- package/dist/types/Inputs/TouchControllerFake.d.ts +29 -29
- package/dist/types/Inputs/XRGamepadController.d.ts +15 -15
- package/dist/types/PeerConnectionController/AggregatedStats.d.ts +82 -82
- package/dist/types/PeerConnectionController/CandidatePairStats.d.ts +22 -22
- package/dist/types/PeerConnectionController/CandidateStat.d.ts +13 -13
- package/dist/types/PeerConnectionController/CodecStats.d.ts +14 -14
- package/dist/types/PeerConnectionController/DataChannelStats.d.ts +15 -15
- package/dist/types/PeerConnectionController/InboundRTPStats.d.ts +141 -141
- package/dist/types/PeerConnectionController/InboundTrackStats.d.ts +32 -32
- package/dist/types/PeerConnectionController/OutBoundRTPStats.d.ts +23 -23
- package/dist/types/PeerConnectionController/PeerConnectionController.d.ts +143 -143
- package/dist/types/PeerConnectionController/SessionStats.d.ts +8 -8
- package/dist/types/PeerConnectionController/StreamStats.d.ts +9 -9
- package/dist/types/PixelStreaming/PixelStreaming.d.ts +271 -271
- package/dist/types/UI/OnScreenKeyboard.d.ts +30 -30
- package/dist/types/UeInstanceMessage/ResponseController.d.ts +19 -19
- package/dist/types/UeInstanceMessage/SendMessageController.d.ts +18 -18
- package/dist/types/UeInstanceMessage/StreamMessageController.d.ts +29 -29
- package/dist/types/UeInstanceMessage/ToStreamerMessagesController.d.ts +32 -32
- package/dist/types/Util/EventEmitter.d.ts +429 -429
- package/dist/types/Util/FileUtil.d.ts +32 -32
- package/dist/types/Util/IURLSearchParams.d.ts +9 -9
- package/dist/types/Util/InputCoordTranslator.d.ts +29 -29
- package/dist/types/Util/RTCUtils.d.ts +8 -8
- package/dist/types/VideoPlayer/StreamController.d.ts +22 -22
- package/dist/types/VideoPlayer/VideoPlayer.d.ts +78 -78
- package/dist/types/WebRtcPlayer/WebRtcPlayerController.d.ts +379 -379
- package/dist/types/WebXR/WebXRController.d.ts +42 -42
- package/dist/types/pixelstreamingfrontend.d.ts +23 -23
- package/package.json +45 -45
- package/src/Inputs/TouchController.ts +3 -3
|
@@ -1,608 +1,608 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.PixelStreaming = void 0;
|
|
5
|
-
const Config_1 = require("../Config/Config");
|
|
6
|
-
const WebRtcPlayerController_1 = require("../WebRtcPlayer/WebRtcPlayerController");
|
|
7
|
-
const Config_2 = require("../Config/Config");
|
|
8
|
-
const lib_pixelstreamingcommon_ue5_5_1 = require("@epicgames-ps/lib-pixelstreamingcommon-ue5.5");
|
|
9
|
-
const OnScreenKeyboard_1 = require("../UI/OnScreenKeyboard");
|
|
10
|
-
const EventEmitter_1 = require("../Util/EventEmitter");
|
|
11
|
-
const WebXRController_1 = require("../WebXR/WebXRController");
|
|
12
|
-
const StreamMessageController_1 = require("../UeInstanceMessage/StreamMessageController");
|
|
13
|
-
const DataChannelLatencyTestController_1 = require("../DataChannel/DataChannelLatencyTestController");
|
|
14
|
-
const RTCUtils_1 = require("../Util/RTCUtils");
|
|
15
|
-
const IURLSearchParams_1 = require("../Util/IURLSearchParams");
|
|
16
|
-
/**
|
|
17
|
-
* The key class for the browser side of a Pixel Streaming application, it includes:
|
|
18
|
-
* WebRTC handling, XR support, input handling, and emitters for lifetime and state change events.
|
|
19
|
-
* Users are encouraged to use this class as is, through composition, or extend it. In any case,
|
|
20
|
-
* this will likely be the core of your Pixel Streaming experience in terms of functionality.
|
|
21
|
-
*/
|
|
22
|
-
class PixelStreaming {
|
|
23
|
-
/**
|
|
24
|
-
* @param config - A newly instantiated config object
|
|
25
|
-
* @param overrides - Parameters to override default behaviour
|
|
26
|
-
* returns the base Pixel streaming object
|
|
27
|
-
*/
|
|
28
|
-
constructor(config, overrides) {
|
|
29
|
-
this.allowConsoleCommands = false;
|
|
30
|
-
this.config = config;
|
|
31
|
-
if (overrides === null || overrides === void 0 ? void 0 : overrides.videoElementParent) {
|
|
32
|
-
this._videoElementParent = overrides.videoElementParent;
|
|
33
|
-
}
|
|
34
|
-
this._eventEmitter = new EventEmitter_1.EventEmitter();
|
|
35
|
-
this.configureSettings();
|
|
36
|
-
// setup WebRTC
|
|
37
|
-
this.setWebRtcPlayerController(new WebRtcPlayerController_1.WebRtcPlayerController(this.config, this));
|
|
38
|
-
// Onscreen keyboard
|
|
39
|
-
this.onScreenKeyboardHelper = new OnScreenKeyboard_1.OnScreenKeyboard(this.videoElementParent);
|
|
40
|
-
this.onScreenKeyboardHelper.unquantizeAndDenormalizeUnsigned = (x, y) => this._webRtcController.requestUnquantizedAndDenormalizeUnsigned(x, y);
|
|
41
|
-
this._activateOnScreenKeyboard = (command) => this.onScreenKeyboardHelper.showOnScreenKeyboard(command);
|
|
42
|
-
this._webXrController = new WebXRController_1.WebXRController(this._webRtcController);
|
|
43
|
-
this._setupWebRtcTCPRelayDetection = this._setupWebRtcTCPRelayDetection.bind(this);
|
|
44
|
-
// Add event listener for the webRtcConnected event
|
|
45
|
-
this._eventEmitter.addEventListener('webRtcConnected', (_) => {
|
|
46
|
-
// Bind to the stats received event
|
|
47
|
-
this._eventEmitter.addEventListener('statsReceived', this._setupWebRtcTCPRelayDetection);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Gets the element that contains the video stream element.
|
|
52
|
-
*/
|
|
53
|
-
get videoElementParent() {
|
|
54
|
-
if (!this._videoElementParent) {
|
|
55
|
-
this._videoElementParent = document.createElement('div');
|
|
56
|
-
this._videoElementParent.id = 'videoElementParent';
|
|
57
|
-
}
|
|
58
|
-
return this._videoElementParent;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Configure the settings with on change listeners and any additional per experience settings.
|
|
62
|
-
*/
|
|
63
|
-
configureSettings() {
|
|
64
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.IsQualityController, (wantsQualityController) => {
|
|
65
|
-
// If the setting has been set to true (either programmatically or the user has flicked the toggle)
|
|
66
|
-
// and we aren't currently quality controller, send the request
|
|
67
|
-
if (wantsQualityController === true && !this._webRtcController.isQualityController) {
|
|
68
|
-
this._webRtcController.sendRequestQualityControlOwnership();
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.AFKDetection, (isAFKEnabled) => {
|
|
72
|
-
this._webRtcController.setAfkEnabled(isAFKEnabled);
|
|
73
|
-
});
|
|
74
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.MatchViewportResolution, () => {
|
|
75
|
-
this._webRtcController.videoPlayer.updateVideoStreamSize();
|
|
76
|
-
});
|
|
77
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.HoveringMouseMode, (isHoveringMouse) => {
|
|
78
|
-
this.config.setFlagLabel(Config_2.Flags.HoveringMouseMode, `Control Scheme: ${isHoveringMouse ? 'Hovering' : 'Locked'} Mouse`);
|
|
79
|
-
this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(Config_2.Flags.MouseInput));
|
|
80
|
-
});
|
|
81
|
-
// user input
|
|
82
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.KeyboardInput, (isEnabled) => {
|
|
83
|
-
this._webRtcController.setKeyboardInputEnabled(isEnabled);
|
|
84
|
-
});
|
|
85
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.MouseInput, (isEnabled) => {
|
|
86
|
-
this._webRtcController.setMouseInputEnabled(isEnabled);
|
|
87
|
-
});
|
|
88
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.FakeMouseWithTouches, (_isFakeMouseEnabled) => {
|
|
89
|
-
this._webRtcController.setTouchInputEnabled(this.config.isFlagEnabled(Config_2.Flags.TouchInput));
|
|
90
|
-
});
|
|
91
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.TouchInput, (isEnabled) => {
|
|
92
|
-
this._webRtcController.setTouchInputEnabled(isEnabled);
|
|
93
|
-
});
|
|
94
|
-
this.config._addOnSettingChangedListener(Config_2.Flags.GamepadInput, (isEnabled) => {
|
|
95
|
-
this._webRtcController.setGamePadInputEnabled(isEnabled);
|
|
96
|
-
});
|
|
97
|
-
// encoder settings
|
|
98
|
-
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.MinQP, (newValue) => {
|
|
99
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending MinQP --------');
|
|
100
|
-
this._webRtcController.sendEncoderMinQP(newValue);
|
|
101
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
102
|
-
});
|
|
103
|
-
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.MaxQP, (newValue) => {
|
|
104
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending encoder settings --------');
|
|
105
|
-
this._webRtcController.sendEncoderMaxQP(newValue);
|
|
106
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
107
|
-
});
|
|
108
|
-
// WebRTC settings
|
|
109
|
-
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.WebRTCMinBitrate, (newValue) => {
|
|
110
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending web rtc settings --------');
|
|
111
|
-
this._webRtcController.sendWebRTCMinBitrate(newValue * 1000 /* kbps to bps */);
|
|
112
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
113
|
-
});
|
|
114
|
-
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.WebRTCMaxBitrate, (newValue) => {
|
|
115
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending web rtc settings --------');
|
|
116
|
-
this._webRtcController.sendWebRTCMaxBitrate(newValue * 1000 /* kbps to bps */);
|
|
117
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
118
|
-
});
|
|
119
|
-
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.WebRTCFPS, (newValue) => {
|
|
120
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending web rtc settings --------');
|
|
121
|
-
this._webRtcController.sendWebRTCFps(newValue);
|
|
122
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
123
|
-
});
|
|
124
|
-
this.config._addOnOptionSettingChangedListener(Config_1.OptionParameters.PreferredCodec, (newValue) => {
|
|
125
|
-
if (this._webRtcController) {
|
|
126
|
-
this._webRtcController.setPreferredCodec(newValue);
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
this.config._registerOnChangeEvents(this._eventEmitter);
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Activate the on screen keyboard when receiving the command from the streamer
|
|
133
|
-
* @param command - the keyboard command
|
|
134
|
-
*/
|
|
135
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
136
|
-
_activateOnScreenKeyboard(command) {
|
|
137
|
-
throw new Error('Method not implemented.');
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Set the input control ownership
|
|
141
|
-
* @param inputControlOwnership - does the user have input control ownership
|
|
142
|
-
*/
|
|
143
|
-
_onInputControlOwnership(inputControlOwnership) {
|
|
144
|
-
this._inputController = inputControlOwnership;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Instantiate the WebRTCPlayerController interface to provide WebRTCPlayerController functionality within this class and set up anything that requires it
|
|
148
|
-
* @param webRtcPlayerController - a WebRtcPlayerController controller instance
|
|
149
|
-
*/
|
|
150
|
-
setWebRtcPlayerController(webRtcPlayerController) {
|
|
151
|
-
this._webRtcController = webRtcPlayerController;
|
|
152
|
-
this._webRtcController.setPreferredCodec(this.config.getSettingOption(Config_1.OptionParameters.PreferredCodec).selected);
|
|
153
|
-
this._webRtcController.resizePlayerStyle();
|
|
154
|
-
// connect if auto connect flag is enabled
|
|
155
|
-
this.checkForAutoConnect();
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Connect to signaling server.
|
|
159
|
-
*/
|
|
160
|
-
connect() {
|
|
161
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.StreamPreConnectEvent());
|
|
162
|
-
this._webRtcController.connectToSignallingServer();
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Reconnects to the signaling server. If connection is up, disconnects first
|
|
166
|
-
* before establishing a new connection
|
|
167
|
-
*/
|
|
168
|
-
reconnect() {
|
|
169
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.StreamReconnectEvent());
|
|
170
|
-
this._webRtcController.tryReconnect('Reconnecting...');
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Disconnect from the signaling server and close open peer connections.
|
|
174
|
-
*/
|
|
175
|
-
disconnect() {
|
|
176
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.StreamPreDisconnectEvent());
|
|
177
|
-
this._webRtcController.close();
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Play the stream. Can be called only after a peer connection has been established.
|
|
181
|
-
*/
|
|
182
|
-
play() {
|
|
183
|
-
this._onStreamLoading();
|
|
184
|
-
this._webRtcController.playStream();
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Auto connect if AutoConnect flag is enabled
|
|
188
|
-
*/
|
|
189
|
-
checkForAutoConnect() {
|
|
190
|
-
// set up if the auto play will be used or regular click to start
|
|
191
|
-
if (this.config.isFlagEnabled(Config_2.Flags.AutoConnect)) {
|
|
192
|
-
// if autoplaying show an info overlay while while waiting for the connection to begin
|
|
193
|
-
this._onWebRtcAutoConnect();
|
|
194
|
-
this._webRtcController.connectToSignallingServer();
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Will unmute the microphone track which is sent to Unreal Engine.
|
|
199
|
-
* By default, will only unmute an existing mic track.
|
|
200
|
-
*
|
|
201
|
-
* @param forceEnable Can be used for cases when this object wasn't initialized with a mic track.
|
|
202
|
-
* If this parameter is true, the connection will be restarted with a microphone.
|
|
203
|
-
* Warning: this takes some time, as a full renegotiation and reconnection will happen.
|
|
204
|
-
*/
|
|
205
|
-
unmuteMicrophone(forceEnable = false) {
|
|
206
|
-
// If there's an existing mic track, we just set muted state
|
|
207
|
-
if (this.config.isFlagEnabled('UseMic')) {
|
|
208
|
-
this.setMicrophoneMuted(false);
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
// If there's no pre-existing mic track, and caller is ok with full reset, we enable and reset
|
|
212
|
-
if (forceEnable) {
|
|
213
|
-
this.config.setFlagEnabled('UseMic', true);
|
|
214
|
-
this.reconnect();
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
// If we prefer not to force a reconnection, just warn the user that this operation didn't happen
|
|
218
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Warning('Trying to unmute mic, but PixelStreaming was initialized with no microphone track. Call with forceEnable == true to re-connect with a mic track.');
|
|
219
|
-
}
|
|
220
|
-
muteMicrophone() {
|
|
221
|
-
if (this.config.isFlagEnabled('UseMic')) {
|
|
222
|
-
this.setMicrophoneMuted(true);
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
// If there wasn't a mic track, just let user know there's nothing to mute
|
|
226
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('Trying to mute mic, but PixelStreaming has no microphone track, so sending sound is already disabled.');
|
|
227
|
-
}
|
|
228
|
-
setMicrophoneMuted(mute) {
|
|
229
|
-
var _a, _b, _c, _d;
|
|
230
|
-
for (const transceiver of (_d = (_c = (_b = (_a = this._webRtcController) === null || _a === void 0 ? void 0 : _a.peerConnectionController) === null || _b === void 0 ? void 0 : _b.peerConnection) === null || _c === void 0 ? void 0 : _c.getTransceivers()) !== null && _d !== void 0 ? _d : []) {
|
|
231
|
-
if (RTCUtils_1.RTCUtils.canTransceiverSendAudio(transceiver)) {
|
|
232
|
-
transceiver.sender.track.enabled = !mute;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Will unmute the video track which is sent to Unreal Engine.
|
|
238
|
-
* By default, will only unmute an existing video track.
|
|
239
|
-
*
|
|
240
|
-
* @param forceEnable Can be used for cases when this object wasn't initialized with a video track.
|
|
241
|
-
* If this parameter is true, the connection will be restarted with a camera.
|
|
242
|
-
* Warning: this takes some time, as a full renegotiation and reconnection will happen.
|
|
243
|
-
*/
|
|
244
|
-
unmuteCamera(forceEnable = false) {
|
|
245
|
-
// If there's an existing video track, we just set muted state
|
|
246
|
-
if (this.config.isFlagEnabled('UseCamera')) {
|
|
247
|
-
this.setCameraMuted(false);
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
// If there's no pre-existing video track, and caller is ok with full reset, we enable and reset
|
|
251
|
-
if (forceEnable) {
|
|
252
|
-
this.config.setFlagEnabled('UseCamera', true);
|
|
253
|
-
this.reconnect();
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
// If we prefer not to force a reconnection, just warn the user that this operation didn't happen
|
|
257
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Warning('Trying to unmute video, but PixelStreaming was initialized with no video track. Call with forceEnable == true to re-connect with a video track.');
|
|
258
|
-
}
|
|
259
|
-
muteCamera() {
|
|
260
|
-
if (this.config.isFlagEnabled('UseCamera')) {
|
|
261
|
-
this.setCameraMuted(true);
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
// If there wasn't a mic track, just let user know there's nothing to mute
|
|
265
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('Trying to mute camera, but PixelStreaming has no video track, so sending video is already disabled.');
|
|
266
|
-
}
|
|
267
|
-
setCameraMuted(mute) {
|
|
268
|
-
var _a, _b, _c, _d;
|
|
269
|
-
for (const transceiver of (_d = (_c = (_b = (_a = this._webRtcController) === null || _a === void 0 ? void 0 : _a.peerConnectionController) === null || _b === void 0 ? void 0 : _b.peerConnection) === null || _c === void 0 ? void 0 : _c.getTransceivers()) !== null && _d !== void 0 ? _d : []) {
|
|
270
|
-
if (RTCUtils_1.RTCUtils.canTransceiverSendVideo(transceiver)) {
|
|
271
|
-
transceiver.sender.track.enabled = !mute;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Emit an event on auto connecting
|
|
277
|
-
*/
|
|
278
|
-
_onWebRtcAutoConnect() {
|
|
279
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcAutoConnectEvent());
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Set up functionality to happen when receiving a webRTC answer
|
|
283
|
-
*/
|
|
284
|
-
_onWebRtcSdp() {
|
|
285
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcSdpEvent());
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Emits a StreamLoading event
|
|
289
|
-
*/
|
|
290
|
-
_onStreamLoading() {
|
|
291
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.StreamLoadingEvent());
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Event fired when the video is disconnected - emits given eventString or an override
|
|
295
|
-
* message from webRtcController if one has been set
|
|
296
|
-
* @param eventString - a string describing why the connection closed
|
|
297
|
-
* @param allowClickToReconnect - true if we want to allow the user to retry the connection with a click
|
|
298
|
-
*/
|
|
299
|
-
_onDisconnect(eventString, allowClickToReconnect) {
|
|
300
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcDisconnectedEvent({
|
|
301
|
-
eventString: eventString,
|
|
302
|
-
allowClickToReconnect: allowClickToReconnect
|
|
303
|
-
}));
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Handles when Web Rtc is connecting
|
|
307
|
-
*/
|
|
308
|
-
_onWebRtcConnecting() {
|
|
309
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcConnectingEvent());
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Handles when Web Rtc has connected
|
|
313
|
-
*/
|
|
314
|
-
_onWebRtcConnected() {
|
|
315
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcConnectedEvent());
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Handles when Web Rtc fails to connect
|
|
319
|
-
*/
|
|
320
|
-
_onWebRtcFailed() {
|
|
321
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcFailedEvent());
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Handle when the Video has been Initialized
|
|
325
|
-
*/
|
|
326
|
-
_onVideoInitialized() {
|
|
327
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.VideoInitializedEvent());
|
|
328
|
-
this._videoStartTime = Date.now();
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Set up functionality to happen when receiving latency test results
|
|
332
|
-
* @param latency - latency test results object
|
|
333
|
-
*/
|
|
334
|
-
_onLatencyTestResult(latencyTimings) {
|
|
335
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.LatencyTestResultEvent({ latencyTimings }));
|
|
336
|
-
}
|
|
337
|
-
_onDataChannelLatencyTestResponse(response) {
|
|
338
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.DataChannelLatencyTestResponseEvent({ response }));
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Set up functionality to happen when receiving video statistics
|
|
342
|
-
* @param videoStats - video statistics as a aggregate stats object
|
|
343
|
-
*/
|
|
344
|
-
_onVideoStats(videoStats) {
|
|
345
|
-
// Duration
|
|
346
|
-
if (!this._videoStartTime || this._videoStartTime === undefined) {
|
|
347
|
-
this._videoStartTime = Date.now();
|
|
348
|
-
}
|
|
349
|
-
videoStats.handleSessionStatistics(this._videoStartTime, this._inputController, this._webRtcController.videoAvgQp);
|
|
350
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.StatsReceivedEvent({ aggregatedStats: videoStats }));
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Set up functionality to happen when calculating the average video encoder qp
|
|
354
|
-
* @param QP - the quality number of the stream
|
|
355
|
-
*/
|
|
356
|
-
_onVideoEncoderAvgQP(QP) {
|
|
357
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.VideoEncoderAvgQPEvent({ avgQP: QP }));
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Set up functionality to happen when receiving and handling initial settings for the UE app
|
|
361
|
-
* @param settings - initial UE app settings
|
|
362
|
-
*/
|
|
363
|
-
_onInitialSettings(settings) {
|
|
364
|
-
var _a;
|
|
365
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.InitialSettingsEvent({ settings }));
|
|
366
|
-
if (settings.PixelStreamingSettings) {
|
|
367
|
-
this.allowConsoleCommands = (_a = settings.PixelStreamingSettings.AllowPixelStreamingCommands) !== null && _a !== void 0 ? _a : false;
|
|
368
|
-
if (this.allowConsoleCommands === false) {
|
|
369
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-AllowPixelStreamingCommands=false, sending arbitrary console commands from browser to UE is disabled.');
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
const useUrlParams = this.config.useUrlParams;
|
|
373
|
-
const urlParams = new IURLSearchParams_1.IURLSearchParams(window.location.search);
|
|
374
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Info(`using URL parameters ${useUrlParams}`);
|
|
375
|
-
if (settings.EncoderSettings) {
|
|
376
|
-
this.config.setNumericSetting(Config_2.NumericParameters.MinQP,
|
|
377
|
-
// If a setting is set in the URL, make sure we respect that value as opposed to what the application sends us
|
|
378
|
-
useUrlParams && urlParams.has(Config_2.NumericParameters.MinQP)
|
|
379
|
-
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.MinQP))
|
|
380
|
-
: settings.EncoderSettings.MinQP);
|
|
381
|
-
this.config.setNumericSetting(Config_2.NumericParameters.MaxQP, useUrlParams && urlParams.has(Config_2.NumericParameters.MaxQP)
|
|
382
|
-
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.MaxQP))
|
|
383
|
-
: settings.EncoderSettings.MaxQP);
|
|
384
|
-
}
|
|
385
|
-
if (settings.WebRTCSettings) {
|
|
386
|
-
this.config.setNumericSetting(Config_2.NumericParameters.WebRTCMinBitrate, useUrlParams && urlParams.has(Config_2.NumericParameters.WebRTCMinBitrate)
|
|
387
|
-
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.WebRTCMinBitrate))
|
|
388
|
-
: settings.WebRTCSettings.MinBitrate / 1000 /* bps to kbps */);
|
|
389
|
-
this.config.setNumericSetting(Config_2.NumericParameters.WebRTCMaxBitrate, useUrlParams && urlParams.has(Config_2.NumericParameters.WebRTCMaxBitrate)
|
|
390
|
-
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.WebRTCMaxBitrate))
|
|
391
|
-
: settings.WebRTCSettings.MaxBitrate / 1000 /* bps to kbps */);
|
|
392
|
-
this.config.setNumericSetting(Config_2.NumericParameters.WebRTCFPS, useUrlParams && urlParams.has(Config_2.NumericParameters.WebRTCFPS)
|
|
393
|
-
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.WebRTCFPS))
|
|
394
|
-
: settings.WebRTCSettings.FPS);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* Set up functionality to happen when setting quality control ownership of a stream
|
|
399
|
-
* @param hasQualityOwnership - does this user have quality ownership of the stream true / false
|
|
400
|
-
*/
|
|
401
|
-
_onQualityControlOwnership(hasQualityOwnership) {
|
|
402
|
-
this.config.setFlagEnabled(Config_2.Flags.IsQualityController, hasQualityOwnership);
|
|
403
|
-
}
|
|
404
|
-
_onPlayerCount(playerCount) {
|
|
405
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.PlayerCountEvent({ count: playerCount }));
|
|
406
|
-
}
|
|
407
|
-
// Sets up to emit the webrtc tcp relay detect event
|
|
408
|
-
_setupWebRtcTCPRelayDetection(statsReceivedEvent) {
|
|
409
|
-
// Get the active candidate pair
|
|
410
|
-
const activeCandidatePair = statsReceivedEvent.data.aggregatedStats.getActiveCandidatePair();
|
|
411
|
-
// Check if the active candidate pair is not null
|
|
412
|
-
if (activeCandidatePair != null) {
|
|
413
|
-
// Get the local candidate assigned to the active candidate pair
|
|
414
|
-
const localCandidate = statsReceivedEvent.data.aggregatedStats.localCandidates.find((candidate) => candidate.id == activeCandidatePair.localCandidateId, null);
|
|
415
|
-
// Check if the local candidate is not null, candidate type is relay and the relay protocol is tcp
|
|
416
|
-
if (localCandidate != null &&
|
|
417
|
-
localCandidate.candidateType == 'relay' &&
|
|
418
|
-
localCandidate.relayProtocol == 'tcp') {
|
|
419
|
-
// Send the web rtc tcp relay detected event
|
|
420
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcTCPRelayDetectedEvent());
|
|
421
|
-
}
|
|
422
|
-
// The check is completed and the stats listen event can be removed
|
|
423
|
-
this._eventEmitter.removeEventListener('statsReceived', this._setupWebRtcTCPRelayDetection);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Request a connection latency test.
|
|
428
|
-
* NOTE: There are plans to refactor all request* functions. Expect changes if you use this!
|
|
429
|
-
* @returns
|
|
430
|
-
*/
|
|
431
|
-
requestLatencyTest() {
|
|
432
|
-
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
433
|
-
return false;
|
|
434
|
-
}
|
|
435
|
-
this._webRtcController.sendLatencyTest();
|
|
436
|
-
return true;
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Request a data channel latency test.
|
|
440
|
-
* NOTE: There are plans to refactor all request* functions. Expect changes if you use this!
|
|
441
|
-
*/
|
|
442
|
-
requestDataChannelLatencyTest(config) {
|
|
443
|
-
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
444
|
-
return false;
|
|
445
|
-
}
|
|
446
|
-
if (!this._dataChannelLatencyTestController) {
|
|
447
|
-
this._dataChannelLatencyTestController = new DataChannelLatencyTestController_1.DataChannelLatencyTestController(this._webRtcController.sendDataChannelLatencyTest.bind(this._webRtcController), (result) => {
|
|
448
|
-
this._eventEmitter.dispatchEvent(new EventEmitter_1.DataChannelLatencyTestResultEvent({ result }));
|
|
449
|
-
});
|
|
450
|
-
this.addEventListener('dataChannelLatencyTestResponse', ({ data: { response } }) => {
|
|
451
|
-
this._dataChannelLatencyTestController.receive(response);
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
return this._dataChannelLatencyTestController.start(config);
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* Request for the UE application to show FPS counter.
|
|
458
|
-
* NOTE: There are plans to refactor all request* functions. Expect changes if you use this!
|
|
459
|
-
* @returns
|
|
460
|
-
*/
|
|
461
|
-
requestShowFps() {
|
|
462
|
-
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
463
|
-
return false;
|
|
464
|
-
}
|
|
465
|
-
this._webRtcController.sendShowFps();
|
|
466
|
-
return true;
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Request for a new IFrame from the UE application.
|
|
470
|
-
* NOTE: There are plans to refactor all request* functions. Expect changes if you use this!
|
|
471
|
-
* @returns
|
|
472
|
-
*/
|
|
473
|
-
requestIframe() {
|
|
474
|
-
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
475
|
-
return false;
|
|
476
|
-
}
|
|
477
|
-
this._webRtcController.sendIframeRequest();
|
|
478
|
-
return true;
|
|
479
|
-
}
|
|
480
|
-
/**
|
|
481
|
-
* Send data to UE application. The data will be run through JSON.stringify() so e.g. strings
|
|
482
|
-
* and any serializable plain JSON objects with no recurrence can be sent.
|
|
483
|
-
* @returns true if succeeded, false if rejected
|
|
484
|
-
*/
|
|
485
|
-
emitUIInteraction(descriptor) {
|
|
486
|
-
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
489
|
-
this._webRtcController.emitUIInteraction(descriptor);
|
|
490
|
-
return true;
|
|
491
|
-
}
|
|
492
|
-
/**
|
|
493
|
-
* Send a command to UE application. Blocks ConsoleCommand descriptors unless UE
|
|
494
|
-
* has signaled that it allows console commands.
|
|
495
|
-
* @returns true if succeeded, false if rejected
|
|
496
|
-
*/
|
|
497
|
-
emitCommand(descriptor) {
|
|
498
|
-
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
499
|
-
return false;
|
|
500
|
-
}
|
|
501
|
-
if (!this.allowConsoleCommands && 'ConsoleCommand' in descriptor) {
|
|
502
|
-
return false;
|
|
503
|
-
}
|
|
504
|
-
this._webRtcController.emitCommand(descriptor);
|
|
505
|
-
return true;
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Send a console command to UE application. Only allowed if UE has signaled that it allows
|
|
509
|
-
* console commands.
|
|
510
|
-
* @returns true if succeeded, false if rejected
|
|
511
|
-
*/
|
|
512
|
-
emitConsoleCommand(command) {
|
|
513
|
-
if (!this.allowConsoleCommands || !this._webRtcController.videoPlayer.isVideoReady()) {
|
|
514
|
-
return false;
|
|
515
|
-
}
|
|
516
|
-
this._webRtcController.emitConsoleCommand(command);
|
|
517
|
-
return true;
|
|
518
|
-
}
|
|
519
|
-
/**
|
|
520
|
-
* Add a UE -> browser response event listener
|
|
521
|
-
* @param name - The name of the response handler
|
|
522
|
-
* @param listener - The method to be activated when a message is received
|
|
523
|
-
*/
|
|
524
|
-
addResponseEventListener(name, listener) {
|
|
525
|
-
this._webRtcController.responseController.addResponseEventListener(name, listener);
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Remove a UE -> browser response event listener
|
|
529
|
-
* @param name - The name of the response handler
|
|
530
|
-
*/
|
|
531
|
-
removeResponseEventListener(name) {
|
|
532
|
-
this._webRtcController.responseController.removeResponseEventListener(name);
|
|
533
|
-
}
|
|
534
|
-
/**
|
|
535
|
-
* Dispatch a new event.
|
|
536
|
-
* @param e event
|
|
537
|
-
* @returns
|
|
538
|
-
*/
|
|
539
|
-
dispatchEvent(e) {
|
|
540
|
-
return this._eventEmitter.dispatchEvent(e);
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* Register an event handler.
|
|
544
|
-
* @param type event name
|
|
545
|
-
* @param listener event handler function
|
|
546
|
-
*/
|
|
547
|
-
addEventListener(type, listener) {
|
|
548
|
-
this._eventEmitter.addEventListener(type, listener);
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* Remove an event handler.
|
|
552
|
-
* @param type event name
|
|
553
|
-
* @param listener event handler function
|
|
554
|
-
*/
|
|
555
|
-
removeEventListener(type, listener) {
|
|
556
|
-
this._eventEmitter.removeEventListener(type, listener);
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Enable/disable XR mode.
|
|
560
|
-
*/
|
|
561
|
-
toggleXR() {
|
|
562
|
-
this.webXrController.xrClicked();
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Pass in a function to generate a signalling server URL.
|
|
566
|
-
* This function is useful if you need to programmatically construct your signalling server URL.
|
|
567
|
-
* @param signallingUrlBuilderFunc A function that generates a signalling server url.
|
|
568
|
-
*/
|
|
569
|
-
setSignallingUrlBuilder(signallingUrlBuilderFunc) {
|
|
570
|
-
this._webRtcController.signallingUrlBuilder = signallingUrlBuilderFunc;
|
|
571
|
-
}
|
|
572
|
-
get webRtcController() {
|
|
573
|
-
return this._webRtcController;
|
|
574
|
-
}
|
|
575
|
-
/**
|
|
576
|
-
* Public getter for the websocket controller. Access to this property allows you to send
|
|
577
|
-
* custom websocket messages.
|
|
578
|
-
*/
|
|
579
|
-
get signallingProtocol() {
|
|
580
|
-
return this._webRtcController.protocol;
|
|
581
|
-
}
|
|
582
|
-
/**
|
|
583
|
-
* Public getter for the webXrController controller. Used for all XR features.
|
|
584
|
-
*/
|
|
585
|
-
get webXrController() {
|
|
586
|
-
return this._webXrController;
|
|
587
|
-
}
|
|
588
|
-
registerMessageHandler(name, direction, handler) {
|
|
589
|
-
if (direction === StreamMessageController_1.MessageDirection.FromStreamer && typeof handler === 'undefined') {
|
|
590
|
-
lib_pixelstreamingcommon_ue5_5_1.Logger.Warning(`Unable to register an undefined handler for ${name}`);
|
|
591
|
-
return;
|
|
592
|
-
}
|
|
593
|
-
if (direction === StreamMessageController_1.MessageDirection.ToStreamer && typeof handler === 'undefined') {
|
|
594
|
-
this._webRtcController.streamMessageController.registerMessageHandler(direction, name, (data) => this._webRtcController.sendMessageController.sendMessageToStreamer(name, data));
|
|
595
|
-
}
|
|
596
|
-
else {
|
|
597
|
-
this._webRtcController.streamMessageController.registerMessageHandler(direction, name, (data) => handler(data));
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
get toStreamerHandlers() {
|
|
601
|
-
return this._webRtcController.streamMessageController.toStreamerHandlers;
|
|
602
|
-
}
|
|
603
|
-
isReconnecting() {
|
|
604
|
-
return this._webRtcController.isReconnecting;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
exports.PixelStreaming = PixelStreaming;
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PixelStreaming = void 0;
|
|
5
|
+
const Config_1 = require("../Config/Config");
|
|
6
|
+
const WebRtcPlayerController_1 = require("../WebRtcPlayer/WebRtcPlayerController");
|
|
7
|
+
const Config_2 = require("../Config/Config");
|
|
8
|
+
const lib_pixelstreamingcommon_ue5_5_1 = require("@epicgames-ps/lib-pixelstreamingcommon-ue5.5");
|
|
9
|
+
const OnScreenKeyboard_1 = require("../UI/OnScreenKeyboard");
|
|
10
|
+
const EventEmitter_1 = require("../Util/EventEmitter");
|
|
11
|
+
const WebXRController_1 = require("../WebXR/WebXRController");
|
|
12
|
+
const StreamMessageController_1 = require("../UeInstanceMessage/StreamMessageController");
|
|
13
|
+
const DataChannelLatencyTestController_1 = require("../DataChannel/DataChannelLatencyTestController");
|
|
14
|
+
const RTCUtils_1 = require("../Util/RTCUtils");
|
|
15
|
+
const IURLSearchParams_1 = require("../Util/IURLSearchParams");
|
|
16
|
+
/**
|
|
17
|
+
* The key class for the browser side of a Pixel Streaming application, it includes:
|
|
18
|
+
* WebRTC handling, XR support, input handling, and emitters for lifetime and state change events.
|
|
19
|
+
* Users are encouraged to use this class as is, through composition, or extend it. In any case,
|
|
20
|
+
* this will likely be the core of your Pixel Streaming experience in terms of functionality.
|
|
21
|
+
*/
|
|
22
|
+
class PixelStreaming {
|
|
23
|
+
/**
|
|
24
|
+
* @param config - A newly instantiated config object
|
|
25
|
+
* @param overrides - Parameters to override default behaviour
|
|
26
|
+
* returns the base Pixel streaming object
|
|
27
|
+
*/
|
|
28
|
+
constructor(config, overrides) {
|
|
29
|
+
this.allowConsoleCommands = false;
|
|
30
|
+
this.config = config;
|
|
31
|
+
if (overrides === null || overrides === void 0 ? void 0 : overrides.videoElementParent) {
|
|
32
|
+
this._videoElementParent = overrides.videoElementParent;
|
|
33
|
+
}
|
|
34
|
+
this._eventEmitter = new EventEmitter_1.EventEmitter();
|
|
35
|
+
this.configureSettings();
|
|
36
|
+
// setup WebRTC
|
|
37
|
+
this.setWebRtcPlayerController(new WebRtcPlayerController_1.WebRtcPlayerController(this.config, this));
|
|
38
|
+
// Onscreen keyboard
|
|
39
|
+
this.onScreenKeyboardHelper = new OnScreenKeyboard_1.OnScreenKeyboard(this.videoElementParent);
|
|
40
|
+
this.onScreenKeyboardHelper.unquantizeAndDenormalizeUnsigned = (x, y) => this._webRtcController.requestUnquantizedAndDenormalizeUnsigned(x, y);
|
|
41
|
+
this._activateOnScreenKeyboard = (command) => this.onScreenKeyboardHelper.showOnScreenKeyboard(command);
|
|
42
|
+
this._webXrController = new WebXRController_1.WebXRController(this._webRtcController);
|
|
43
|
+
this._setupWebRtcTCPRelayDetection = this._setupWebRtcTCPRelayDetection.bind(this);
|
|
44
|
+
// Add event listener for the webRtcConnected event
|
|
45
|
+
this._eventEmitter.addEventListener('webRtcConnected', (_) => {
|
|
46
|
+
// Bind to the stats received event
|
|
47
|
+
this._eventEmitter.addEventListener('statsReceived', this._setupWebRtcTCPRelayDetection);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Gets the element that contains the video stream element.
|
|
52
|
+
*/
|
|
53
|
+
get videoElementParent() {
|
|
54
|
+
if (!this._videoElementParent) {
|
|
55
|
+
this._videoElementParent = document.createElement('div');
|
|
56
|
+
this._videoElementParent.id = 'videoElementParent';
|
|
57
|
+
}
|
|
58
|
+
return this._videoElementParent;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Configure the settings with on change listeners and any additional per experience settings.
|
|
62
|
+
*/
|
|
63
|
+
configureSettings() {
|
|
64
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.IsQualityController, (wantsQualityController) => {
|
|
65
|
+
// If the setting has been set to true (either programmatically or the user has flicked the toggle)
|
|
66
|
+
// and we aren't currently quality controller, send the request
|
|
67
|
+
if (wantsQualityController === true && !this._webRtcController.isQualityController) {
|
|
68
|
+
this._webRtcController.sendRequestQualityControlOwnership();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.AFKDetection, (isAFKEnabled) => {
|
|
72
|
+
this._webRtcController.setAfkEnabled(isAFKEnabled);
|
|
73
|
+
});
|
|
74
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.MatchViewportResolution, () => {
|
|
75
|
+
this._webRtcController.videoPlayer.updateVideoStreamSize();
|
|
76
|
+
});
|
|
77
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.HoveringMouseMode, (isHoveringMouse) => {
|
|
78
|
+
this.config.setFlagLabel(Config_2.Flags.HoveringMouseMode, `Control Scheme: ${isHoveringMouse ? 'Hovering' : 'Locked'} Mouse`);
|
|
79
|
+
this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(Config_2.Flags.MouseInput));
|
|
80
|
+
});
|
|
81
|
+
// user input
|
|
82
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.KeyboardInput, (isEnabled) => {
|
|
83
|
+
this._webRtcController.setKeyboardInputEnabled(isEnabled);
|
|
84
|
+
});
|
|
85
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.MouseInput, (isEnabled) => {
|
|
86
|
+
this._webRtcController.setMouseInputEnabled(isEnabled);
|
|
87
|
+
});
|
|
88
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.FakeMouseWithTouches, (_isFakeMouseEnabled) => {
|
|
89
|
+
this._webRtcController.setTouchInputEnabled(this.config.isFlagEnabled(Config_2.Flags.TouchInput));
|
|
90
|
+
});
|
|
91
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.TouchInput, (isEnabled) => {
|
|
92
|
+
this._webRtcController.setTouchInputEnabled(isEnabled);
|
|
93
|
+
});
|
|
94
|
+
this.config._addOnSettingChangedListener(Config_2.Flags.GamepadInput, (isEnabled) => {
|
|
95
|
+
this._webRtcController.setGamePadInputEnabled(isEnabled);
|
|
96
|
+
});
|
|
97
|
+
// encoder settings
|
|
98
|
+
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.MinQP, (newValue) => {
|
|
99
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending MinQP --------');
|
|
100
|
+
this._webRtcController.sendEncoderMinQP(newValue);
|
|
101
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
102
|
+
});
|
|
103
|
+
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.MaxQP, (newValue) => {
|
|
104
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending encoder settings --------');
|
|
105
|
+
this._webRtcController.sendEncoderMaxQP(newValue);
|
|
106
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
107
|
+
});
|
|
108
|
+
// WebRTC settings
|
|
109
|
+
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.WebRTCMinBitrate, (newValue) => {
|
|
110
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending web rtc settings --------');
|
|
111
|
+
this._webRtcController.sendWebRTCMinBitrate(newValue * 1000 /* kbps to bps */);
|
|
112
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
113
|
+
});
|
|
114
|
+
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.WebRTCMaxBitrate, (newValue) => {
|
|
115
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending web rtc settings --------');
|
|
116
|
+
this._webRtcController.sendWebRTCMaxBitrate(newValue * 1000 /* kbps to bps */);
|
|
117
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
118
|
+
});
|
|
119
|
+
this.config._addOnNumericSettingChangedListener(Config_2.NumericParameters.WebRTCFPS, (newValue) => {
|
|
120
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------- Sending web rtc settings --------');
|
|
121
|
+
this._webRtcController.sendWebRTCFps(newValue);
|
|
122
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-------------------------------------------');
|
|
123
|
+
});
|
|
124
|
+
this.config._addOnOptionSettingChangedListener(Config_1.OptionParameters.PreferredCodec, (newValue) => {
|
|
125
|
+
if (this._webRtcController) {
|
|
126
|
+
this._webRtcController.setPreferredCodec(newValue);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
this.config._registerOnChangeEvents(this._eventEmitter);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Activate the on screen keyboard when receiving the command from the streamer
|
|
133
|
+
* @param command - the keyboard command
|
|
134
|
+
*/
|
|
135
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
136
|
+
_activateOnScreenKeyboard(command) {
|
|
137
|
+
throw new Error('Method not implemented.');
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Set the input control ownership
|
|
141
|
+
* @param inputControlOwnership - does the user have input control ownership
|
|
142
|
+
*/
|
|
143
|
+
_onInputControlOwnership(inputControlOwnership) {
|
|
144
|
+
this._inputController = inputControlOwnership;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Instantiate the WebRTCPlayerController interface to provide WebRTCPlayerController functionality within this class and set up anything that requires it
|
|
148
|
+
* @param webRtcPlayerController - a WebRtcPlayerController controller instance
|
|
149
|
+
*/
|
|
150
|
+
setWebRtcPlayerController(webRtcPlayerController) {
|
|
151
|
+
this._webRtcController = webRtcPlayerController;
|
|
152
|
+
this._webRtcController.setPreferredCodec(this.config.getSettingOption(Config_1.OptionParameters.PreferredCodec).selected);
|
|
153
|
+
this._webRtcController.resizePlayerStyle();
|
|
154
|
+
// connect if auto connect flag is enabled
|
|
155
|
+
this.checkForAutoConnect();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Connect to signaling server.
|
|
159
|
+
*/
|
|
160
|
+
connect() {
|
|
161
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.StreamPreConnectEvent());
|
|
162
|
+
this._webRtcController.connectToSignallingServer();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Reconnects to the signaling server. If connection is up, disconnects first
|
|
166
|
+
* before establishing a new connection
|
|
167
|
+
*/
|
|
168
|
+
reconnect() {
|
|
169
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.StreamReconnectEvent());
|
|
170
|
+
this._webRtcController.tryReconnect('Reconnecting...');
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Disconnect from the signaling server and close open peer connections.
|
|
174
|
+
*/
|
|
175
|
+
disconnect() {
|
|
176
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.StreamPreDisconnectEvent());
|
|
177
|
+
this._webRtcController.close();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Play the stream. Can be called only after a peer connection has been established.
|
|
181
|
+
*/
|
|
182
|
+
play() {
|
|
183
|
+
this._onStreamLoading();
|
|
184
|
+
this._webRtcController.playStream();
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Auto connect if AutoConnect flag is enabled
|
|
188
|
+
*/
|
|
189
|
+
checkForAutoConnect() {
|
|
190
|
+
// set up if the auto play will be used or regular click to start
|
|
191
|
+
if (this.config.isFlagEnabled(Config_2.Flags.AutoConnect)) {
|
|
192
|
+
// if autoplaying show an info overlay while while waiting for the connection to begin
|
|
193
|
+
this._onWebRtcAutoConnect();
|
|
194
|
+
this._webRtcController.connectToSignallingServer();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Will unmute the microphone track which is sent to Unreal Engine.
|
|
199
|
+
* By default, will only unmute an existing mic track.
|
|
200
|
+
*
|
|
201
|
+
* @param forceEnable Can be used for cases when this object wasn't initialized with a mic track.
|
|
202
|
+
* If this parameter is true, the connection will be restarted with a microphone.
|
|
203
|
+
* Warning: this takes some time, as a full renegotiation and reconnection will happen.
|
|
204
|
+
*/
|
|
205
|
+
unmuteMicrophone(forceEnable = false) {
|
|
206
|
+
// If there's an existing mic track, we just set muted state
|
|
207
|
+
if (this.config.isFlagEnabled('UseMic')) {
|
|
208
|
+
this.setMicrophoneMuted(false);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
// If there's no pre-existing mic track, and caller is ok with full reset, we enable and reset
|
|
212
|
+
if (forceEnable) {
|
|
213
|
+
this.config.setFlagEnabled('UseMic', true);
|
|
214
|
+
this.reconnect();
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
// If we prefer not to force a reconnection, just warn the user that this operation didn't happen
|
|
218
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Warning('Trying to unmute mic, but PixelStreaming was initialized with no microphone track. Call with forceEnable == true to re-connect with a mic track.');
|
|
219
|
+
}
|
|
220
|
+
muteMicrophone() {
|
|
221
|
+
if (this.config.isFlagEnabled('UseMic')) {
|
|
222
|
+
this.setMicrophoneMuted(true);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// If there wasn't a mic track, just let user know there's nothing to mute
|
|
226
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('Trying to mute mic, but PixelStreaming has no microphone track, so sending sound is already disabled.');
|
|
227
|
+
}
|
|
228
|
+
setMicrophoneMuted(mute) {
|
|
229
|
+
var _a, _b, _c, _d;
|
|
230
|
+
for (const transceiver of (_d = (_c = (_b = (_a = this._webRtcController) === null || _a === void 0 ? void 0 : _a.peerConnectionController) === null || _b === void 0 ? void 0 : _b.peerConnection) === null || _c === void 0 ? void 0 : _c.getTransceivers()) !== null && _d !== void 0 ? _d : []) {
|
|
231
|
+
if (RTCUtils_1.RTCUtils.canTransceiverSendAudio(transceiver)) {
|
|
232
|
+
transceiver.sender.track.enabled = !mute;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Will unmute the video track which is sent to Unreal Engine.
|
|
238
|
+
* By default, will only unmute an existing video track.
|
|
239
|
+
*
|
|
240
|
+
* @param forceEnable Can be used for cases when this object wasn't initialized with a video track.
|
|
241
|
+
* If this parameter is true, the connection will be restarted with a camera.
|
|
242
|
+
* Warning: this takes some time, as a full renegotiation and reconnection will happen.
|
|
243
|
+
*/
|
|
244
|
+
unmuteCamera(forceEnable = false) {
|
|
245
|
+
// If there's an existing video track, we just set muted state
|
|
246
|
+
if (this.config.isFlagEnabled('UseCamera')) {
|
|
247
|
+
this.setCameraMuted(false);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
// If there's no pre-existing video track, and caller is ok with full reset, we enable and reset
|
|
251
|
+
if (forceEnable) {
|
|
252
|
+
this.config.setFlagEnabled('UseCamera', true);
|
|
253
|
+
this.reconnect();
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
// If we prefer not to force a reconnection, just warn the user that this operation didn't happen
|
|
257
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Warning('Trying to unmute video, but PixelStreaming was initialized with no video track. Call with forceEnable == true to re-connect with a video track.');
|
|
258
|
+
}
|
|
259
|
+
muteCamera() {
|
|
260
|
+
if (this.config.isFlagEnabled('UseCamera')) {
|
|
261
|
+
this.setCameraMuted(true);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
// If there wasn't a mic track, just let user know there's nothing to mute
|
|
265
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('Trying to mute camera, but PixelStreaming has no video track, so sending video is already disabled.');
|
|
266
|
+
}
|
|
267
|
+
setCameraMuted(mute) {
|
|
268
|
+
var _a, _b, _c, _d;
|
|
269
|
+
for (const transceiver of (_d = (_c = (_b = (_a = this._webRtcController) === null || _a === void 0 ? void 0 : _a.peerConnectionController) === null || _b === void 0 ? void 0 : _b.peerConnection) === null || _c === void 0 ? void 0 : _c.getTransceivers()) !== null && _d !== void 0 ? _d : []) {
|
|
270
|
+
if (RTCUtils_1.RTCUtils.canTransceiverSendVideo(transceiver)) {
|
|
271
|
+
transceiver.sender.track.enabled = !mute;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Emit an event on auto connecting
|
|
277
|
+
*/
|
|
278
|
+
_onWebRtcAutoConnect() {
|
|
279
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcAutoConnectEvent());
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Set up functionality to happen when receiving a webRTC answer
|
|
283
|
+
*/
|
|
284
|
+
_onWebRtcSdp() {
|
|
285
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcSdpEvent());
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Emits a StreamLoading event
|
|
289
|
+
*/
|
|
290
|
+
_onStreamLoading() {
|
|
291
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.StreamLoadingEvent());
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Event fired when the video is disconnected - emits given eventString or an override
|
|
295
|
+
* message from webRtcController if one has been set
|
|
296
|
+
* @param eventString - a string describing why the connection closed
|
|
297
|
+
* @param allowClickToReconnect - true if we want to allow the user to retry the connection with a click
|
|
298
|
+
*/
|
|
299
|
+
_onDisconnect(eventString, allowClickToReconnect) {
|
|
300
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcDisconnectedEvent({
|
|
301
|
+
eventString: eventString,
|
|
302
|
+
allowClickToReconnect: allowClickToReconnect
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Handles when Web Rtc is connecting
|
|
307
|
+
*/
|
|
308
|
+
_onWebRtcConnecting() {
|
|
309
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcConnectingEvent());
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Handles when Web Rtc has connected
|
|
313
|
+
*/
|
|
314
|
+
_onWebRtcConnected() {
|
|
315
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcConnectedEvent());
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Handles when Web Rtc fails to connect
|
|
319
|
+
*/
|
|
320
|
+
_onWebRtcFailed() {
|
|
321
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcFailedEvent());
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Handle when the Video has been Initialized
|
|
325
|
+
*/
|
|
326
|
+
_onVideoInitialized() {
|
|
327
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.VideoInitializedEvent());
|
|
328
|
+
this._videoStartTime = Date.now();
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Set up functionality to happen when receiving latency test results
|
|
332
|
+
* @param latency - latency test results object
|
|
333
|
+
*/
|
|
334
|
+
_onLatencyTestResult(latencyTimings) {
|
|
335
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.LatencyTestResultEvent({ latencyTimings }));
|
|
336
|
+
}
|
|
337
|
+
_onDataChannelLatencyTestResponse(response) {
|
|
338
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.DataChannelLatencyTestResponseEvent({ response }));
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Set up functionality to happen when receiving video statistics
|
|
342
|
+
* @param videoStats - video statistics as a aggregate stats object
|
|
343
|
+
*/
|
|
344
|
+
_onVideoStats(videoStats) {
|
|
345
|
+
// Duration
|
|
346
|
+
if (!this._videoStartTime || this._videoStartTime === undefined) {
|
|
347
|
+
this._videoStartTime = Date.now();
|
|
348
|
+
}
|
|
349
|
+
videoStats.handleSessionStatistics(this._videoStartTime, this._inputController, this._webRtcController.videoAvgQp);
|
|
350
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.StatsReceivedEvent({ aggregatedStats: videoStats }));
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Set up functionality to happen when calculating the average video encoder qp
|
|
354
|
+
* @param QP - the quality number of the stream
|
|
355
|
+
*/
|
|
356
|
+
_onVideoEncoderAvgQP(QP) {
|
|
357
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.VideoEncoderAvgQPEvent({ avgQP: QP }));
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Set up functionality to happen when receiving and handling initial settings for the UE app
|
|
361
|
+
* @param settings - initial UE app settings
|
|
362
|
+
*/
|
|
363
|
+
_onInitialSettings(settings) {
|
|
364
|
+
var _a;
|
|
365
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.InitialSettingsEvent({ settings }));
|
|
366
|
+
if (settings.PixelStreamingSettings) {
|
|
367
|
+
this.allowConsoleCommands = (_a = settings.PixelStreamingSettings.AllowPixelStreamingCommands) !== null && _a !== void 0 ? _a : false;
|
|
368
|
+
if (this.allowConsoleCommands === false) {
|
|
369
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info('-AllowPixelStreamingCommands=false, sending arbitrary console commands from browser to UE is disabled.');
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const useUrlParams = this.config.useUrlParams;
|
|
373
|
+
const urlParams = new IURLSearchParams_1.IURLSearchParams(window.location.search);
|
|
374
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Info(`using URL parameters ${useUrlParams}`);
|
|
375
|
+
if (settings.EncoderSettings) {
|
|
376
|
+
this.config.setNumericSetting(Config_2.NumericParameters.MinQP,
|
|
377
|
+
// If a setting is set in the URL, make sure we respect that value as opposed to what the application sends us
|
|
378
|
+
useUrlParams && urlParams.has(Config_2.NumericParameters.MinQP)
|
|
379
|
+
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.MinQP))
|
|
380
|
+
: settings.EncoderSettings.MinQP);
|
|
381
|
+
this.config.setNumericSetting(Config_2.NumericParameters.MaxQP, useUrlParams && urlParams.has(Config_2.NumericParameters.MaxQP)
|
|
382
|
+
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.MaxQP))
|
|
383
|
+
: settings.EncoderSettings.MaxQP);
|
|
384
|
+
}
|
|
385
|
+
if (settings.WebRTCSettings) {
|
|
386
|
+
this.config.setNumericSetting(Config_2.NumericParameters.WebRTCMinBitrate, useUrlParams && urlParams.has(Config_2.NumericParameters.WebRTCMinBitrate)
|
|
387
|
+
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.WebRTCMinBitrate))
|
|
388
|
+
: settings.WebRTCSettings.MinBitrate / 1000 /* bps to kbps */);
|
|
389
|
+
this.config.setNumericSetting(Config_2.NumericParameters.WebRTCMaxBitrate, useUrlParams && urlParams.has(Config_2.NumericParameters.WebRTCMaxBitrate)
|
|
390
|
+
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.WebRTCMaxBitrate))
|
|
391
|
+
: settings.WebRTCSettings.MaxBitrate / 1000 /* bps to kbps */);
|
|
392
|
+
this.config.setNumericSetting(Config_2.NumericParameters.WebRTCFPS, useUrlParams && urlParams.has(Config_2.NumericParameters.WebRTCFPS)
|
|
393
|
+
? Number.parseFloat(urlParams.get(Config_2.NumericParameters.WebRTCFPS))
|
|
394
|
+
: settings.WebRTCSettings.FPS);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Set up functionality to happen when setting quality control ownership of a stream
|
|
399
|
+
* @param hasQualityOwnership - does this user have quality ownership of the stream true / false
|
|
400
|
+
*/
|
|
401
|
+
_onQualityControlOwnership(hasQualityOwnership) {
|
|
402
|
+
this.config.setFlagEnabled(Config_2.Flags.IsQualityController, hasQualityOwnership);
|
|
403
|
+
}
|
|
404
|
+
_onPlayerCount(playerCount) {
|
|
405
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.PlayerCountEvent({ count: playerCount }));
|
|
406
|
+
}
|
|
407
|
+
// Sets up to emit the webrtc tcp relay detect event
|
|
408
|
+
_setupWebRtcTCPRelayDetection(statsReceivedEvent) {
|
|
409
|
+
// Get the active candidate pair
|
|
410
|
+
const activeCandidatePair = statsReceivedEvent.data.aggregatedStats.getActiveCandidatePair();
|
|
411
|
+
// Check if the active candidate pair is not null
|
|
412
|
+
if (activeCandidatePair != null) {
|
|
413
|
+
// Get the local candidate assigned to the active candidate pair
|
|
414
|
+
const localCandidate = statsReceivedEvent.data.aggregatedStats.localCandidates.find((candidate) => candidate.id == activeCandidatePair.localCandidateId, null);
|
|
415
|
+
// Check if the local candidate is not null, candidate type is relay and the relay protocol is tcp
|
|
416
|
+
if (localCandidate != null &&
|
|
417
|
+
localCandidate.candidateType == 'relay' &&
|
|
418
|
+
localCandidate.relayProtocol == 'tcp') {
|
|
419
|
+
// Send the web rtc tcp relay detected event
|
|
420
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.WebRtcTCPRelayDetectedEvent());
|
|
421
|
+
}
|
|
422
|
+
// The check is completed and the stats listen event can be removed
|
|
423
|
+
this._eventEmitter.removeEventListener('statsReceived', this._setupWebRtcTCPRelayDetection);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Request a connection latency test.
|
|
428
|
+
* NOTE: There are plans to refactor all request* functions. Expect changes if you use this!
|
|
429
|
+
* @returns
|
|
430
|
+
*/
|
|
431
|
+
requestLatencyTest() {
|
|
432
|
+
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
this._webRtcController.sendLatencyTest();
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Request a data channel latency test.
|
|
440
|
+
* NOTE: There are plans to refactor all request* functions. Expect changes if you use this!
|
|
441
|
+
*/
|
|
442
|
+
requestDataChannelLatencyTest(config) {
|
|
443
|
+
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
if (!this._dataChannelLatencyTestController) {
|
|
447
|
+
this._dataChannelLatencyTestController = new DataChannelLatencyTestController_1.DataChannelLatencyTestController(this._webRtcController.sendDataChannelLatencyTest.bind(this._webRtcController), (result) => {
|
|
448
|
+
this._eventEmitter.dispatchEvent(new EventEmitter_1.DataChannelLatencyTestResultEvent({ result }));
|
|
449
|
+
});
|
|
450
|
+
this.addEventListener('dataChannelLatencyTestResponse', ({ data: { response } }) => {
|
|
451
|
+
this._dataChannelLatencyTestController.receive(response);
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
return this._dataChannelLatencyTestController.start(config);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Request for the UE application to show FPS counter.
|
|
458
|
+
* NOTE: There are plans to refactor all request* functions. Expect changes if you use this!
|
|
459
|
+
* @returns
|
|
460
|
+
*/
|
|
461
|
+
requestShowFps() {
|
|
462
|
+
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
this._webRtcController.sendShowFps();
|
|
466
|
+
return true;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Request for a new IFrame from the UE application.
|
|
470
|
+
* NOTE: There are plans to refactor all request* functions. Expect changes if you use this!
|
|
471
|
+
* @returns
|
|
472
|
+
*/
|
|
473
|
+
requestIframe() {
|
|
474
|
+
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
this._webRtcController.sendIframeRequest();
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Send data to UE application. The data will be run through JSON.stringify() so e.g. strings
|
|
482
|
+
* and any serializable plain JSON objects with no recurrence can be sent.
|
|
483
|
+
* @returns true if succeeded, false if rejected
|
|
484
|
+
*/
|
|
485
|
+
emitUIInteraction(descriptor) {
|
|
486
|
+
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
this._webRtcController.emitUIInteraction(descriptor);
|
|
490
|
+
return true;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Send a command to UE application. Blocks ConsoleCommand descriptors unless UE
|
|
494
|
+
* has signaled that it allows console commands.
|
|
495
|
+
* @returns true if succeeded, false if rejected
|
|
496
|
+
*/
|
|
497
|
+
emitCommand(descriptor) {
|
|
498
|
+
if (!this._webRtcController.videoPlayer.isVideoReady()) {
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
if (!this.allowConsoleCommands && 'ConsoleCommand' in descriptor) {
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
this._webRtcController.emitCommand(descriptor);
|
|
505
|
+
return true;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Send a console command to UE application. Only allowed if UE has signaled that it allows
|
|
509
|
+
* console commands.
|
|
510
|
+
* @returns true if succeeded, false if rejected
|
|
511
|
+
*/
|
|
512
|
+
emitConsoleCommand(command) {
|
|
513
|
+
if (!this.allowConsoleCommands || !this._webRtcController.videoPlayer.isVideoReady()) {
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
this._webRtcController.emitConsoleCommand(command);
|
|
517
|
+
return true;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Add a UE -> browser response event listener
|
|
521
|
+
* @param name - The name of the response handler
|
|
522
|
+
* @param listener - The method to be activated when a message is received
|
|
523
|
+
*/
|
|
524
|
+
addResponseEventListener(name, listener) {
|
|
525
|
+
this._webRtcController.responseController.addResponseEventListener(name, listener);
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Remove a UE -> browser response event listener
|
|
529
|
+
* @param name - The name of the response handler
|
|
530
|
+
*/
|
|
531
|
+
removeResponseEventListener(name) {
|
|
532
|
+
this._webRtcController.responseController.removeResponseEventListener(name);
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Dispatch a new event.
|
|
536
|
+
* @param e event
|
|
537
|
+
* @returns
|
|
538
|
+
*/
|
|
539
|
+
dispatchEvent(e) {
|
|
540
|
+
return this._eventEmitter.dispatchEvent(e);
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Register an event handler.
|
|
544
|
+
* @param type event name
|
|
545
|
+
* @param listener event handler function
|
|
546
|
+
*/
|
|
547
|
+
addEventListener(type, listener) {
|
|
548
|
+
this._eventEmitter.addEventListener(type, listener);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Remove an event handler.
|
|
552
|
+
* @param type event name
|
|
553
|
+
* @param listener event handler function
|
|
554
|
+
*/
|
|
555
|
+
removeEventListener(type, listener) {
|
|
556
|
+
this._eventEmitter.removeEventListener(type, listener);
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Enable/disable XR mode.
|
|
560
|
+
*/
|
|
561
|
+
toggleXR() {
|
|
562
|
+
this.webXrController.xrClicked();
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Pass in a function to generate a signalling server URL.
|
|
566
|
+
* This function is useful if you need to programmatically construct your signalling server URL.
|
|
567
|
+
* @param signallingUrlBuilderFunc A function that generates a signalling server url.
|
|
568
|
+
*/
|
|
569
|
+
setSignallingUrlBuilder(signallingUrlBuilderFunc) {
|
|
570
|
+
this._webRtcController.signallingUrlBuilder = signallingUrlBuilderFunc;
|
|
571
|
+
}
|
|
572
|
+
get webRtcController() {
|
|
573
|
+
return this._webRtcController;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Public getter for the websocket controller. Access to this property allows you to send
|
|
577
|
+
* custom websocket messages.
|
|
578
|
+
*/
|
|
579
|
+
get signallingProtocol() {
|
|
580
|
+
return this._webRtcController.protocol;
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Public getter for the webXrController controller. Used for all XR features.
|
|
584
|
+
*/
|
|
585
|
+
get webXrController() {
|
|
586
|
+
return this._webXrController;
|
|
587
|
+
}
|
|
588
|
+
registerMessageHandler(name, direction, handler) {
|
|
589
|
+
if (direction === StreamMessageController_1.MessageDirection.FromStreamer && typeof handler === 'undefined') {
|
|
590
|
+
lib_pixelstreamingcommon_ue5_5_1.Logger.Warning(`Unable to register an undefined handler for ${name}`);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
if (direction === StreamMessageController_1.MessageDirection.ToStreamer && typeof handler === 'undefined') {
|
|
594
|
+
this._webRtcController.streamMessageController.registerMessageHandler(direction, name, (data) => this._webRtcController.sendMessageController.sendMessageToStreamer(name, data));
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
this._webRtcController.streamMessageController.registerMessageHandler(direction, name, (data) => handler(data));
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
get toStreamerHandlers() {
|
|
601
|
+
return this._webRtcController.streamMessageController.toStreamerHandlers;
|
|
602
|
+
}
|
|
603
|
+
isReconnecting() {
|
|
604
|
+
return this._webRtcController.isReconnecting;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
exports.PixelStreaming = PixelStreaming;
|
|
608
608
|
//# sourceMappingURL=PixelStreaming.js.map
|