@epicgames-ps/lib-pixelstreamingfrontend-ue5.5 0.4.8 → 1.0.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/dist/cjs/Config/Config.js +4 -0
- package/dist/cjs/Config/Config.js.map +1 -1
- package/dist/cjs/Config/SettingBase.js +1 -3
- package/dist/cjs/Config/SettingBase.js.map +1 -1
- package/dist/cjs/Config/SettingFlag.js +1 -3
- package/dist/cjs/Config/SettingFlag.js.map +1 -1
- package/dist/cjs/Config/SettingNumber.js +1 -3
- package/dist/cjs/Config/SettingNumber.js.map +1 -1
- package/dist/cjs/Config/SettingOption.js +2 -6
- package/dist/cjs/Config/SettingOption.js.map +1 -1
- package/dist/cjs/Config/SettingText.js +1 -3
- package/dist/cjs/Config/SettingText.js.map +1 -1
- package/dist/cjs/Inputs/GamepadController.js +0 -2
- package/dist/cjs/Inputs/GamepadController.js.map +1 -1
- package/dist/cjs/PeerConnectionController/AggregatedStats.js +103 -45
- package/dist/cjs/PeerConnectionController/AggregatedStats.js.map +1 -1
- package/dist/cjs/PeerConnectionController/InboundRTPStats.js.map +1 -1
- package/dist/cjs/PeerConnectionController/LatencyCalculator.js +290 -0
- package/dist/cjs/PeerConnectionController/LatencyCalculator.js.map +1 -0
- package/dist/cjs/PeerConnectionController/OutBoundRTPStats.js +11 -7
- package/dist/cjs/PeerConnectionController/OutBoundRTPStats.js.map +1 -1
- package/dist/cjs/PeerConnectionController/PeerConnectionController.js +53 -19
- package/dist/cjs/PeerConnectionController/PeerConnectionController.js.map +1 -1
- package/dist/cjs/PixelStreaming/PixelStreaming.js +21 -3
- package/dist/cjs/PixelStreaming/PixelStreaming.js.map +1 -1
- package/dist/cjs/Util/EventEmitter.js +31 -1
- package/dist/cjs/Util/EventEmitter.js.map +1 -1
- package/dist/cjs/WebRtcPlayer/WebRtcPlayerController.js +20 -4
- package/dist/cjs/WebRtcPlayer/WebRtcPlayerController.js.map +1 -1
- package/dist/cjs/__test__/mockMediaStream.js +100 -0
- package/dist/cjs/__test__/mockMediaStream.js.map +1 -0
- package/dist/cjs/__test__/mockRTCPeerConnection.js +252 -0
- package/dist/cjs/__test__/mockRTCPeerConnection.js.map +1 -0
- package/dist/cjs/__test__/mockRTCRtpReceiver.js +26 -0
- package/dist/cjs/__test__/mockRTCRtpReceiver.js.map +1 -0
- package/dist/cjs/__test__/mockWebSocket.js +109 -0
- package/dist/cjs/__test__/mockWebSocket.js.map +1 -0
- package/dist/cjs/pixelstreamingfrontend.js +4 -2
- package/dist/cjs/pixelstreamingfrontend.js.map +1 -1
- package/dist/esm/Config/Config.js +4 -0
- package/dist/esm/Config/Config.js.map +1 -1
- package/dist/esm/Config/SettingBase.js +1 -3
- package/dist/esm/Config/SettingBase.js.map +1 -1
- package/dist/esm/Config/SettingFlag.js +1 -3
- package/dist/esm/Config/SettingFlag.js.map +1 -1
- package/dist/esm/Config/SettingNumber.js +1 -3
- package/dist/esm/Config/SettingNumber.js.map +1 -1
- package/dist/esm/Config/SettingOption.js +2 -6
- package/dist/esm/Config/SettingOption.js.map +1 -1
- package/dist/esm/Config/SettingText.js +1 -3
- package/dist/esm/Config/SettingText.js.map +1 -1
- package/dist/esm/Inputs/GamepadController.js +0 -2
- package/dist/esm/Inputs/GamepadController.js.map +1 -1
- package/dist/esm/PeerConnectionController/AggregatedStats.js +104 -46
- package/dist/esm/PeerConnectionController/AggregatedStats.js.map +1 -1
- package/dist/esm/PeerConnectionController/InboundRTPStats.js.map +1 -1
- package/dist/esm/PeerConnectionController/LatencyCalculator.js +284 -0
- package/dist/esm/PeerConnectionController/LatencyCalculator.js.map +1 -0
- package/dist/esm/PeerConnectionController/OutBoundRTPStats.js +8 -4
- package/dist/esm/PeerConnectionController/OutBoundRTPStats.js.map +1 -1
- package/dist/esm/PeerConnectionController/PeerConnectionController.js +52 -18
- package/dist/esm/PeerConnectionController/PeerConnectionController.js.map +1 -1
- package/dist/esm/PixelStreaming/PixelStreaming.js +22 -4
- package/dist/esm/PixelStreaming/PixelStreaming.js.map +1 -1
- package/dist/esm/Util/EventEmitter.js +27 -0
- package/dist/esm/Util/EventEmitter.js.map +1 -1
- package/dist/esm/WebRtcPlayer/WebRtcPlayerController.js +20 -4
- package/dist/esm/WebRtcPlayer/WebRtcPlayerController.js.map +1 -1
- package/dist/esm/__test__/mockMediaStream.js +92 -0
- package/dist/esm/__test__/mockMediaStream.js.map +1 -0
- package/dist/esm/__test__/mockRTCPeerConnection.js +242 -0
- package/dist/esm/__test__/mockRTCPeerConnection.js.map +1 -0
- package/dist/esm/__test__/mockRTCRtpReceiver.js +21 -0
- package/dist/esm/__test__/mockRTCRtpReceiver.js.map +1 -0
- package/dist/esm/__test__/mockWebSocket.js +103 -0
- package/dist/esm/__test__/mockWebSocket.js.map +1 -0
- package/dist/esm/pixelstreamingfrontend.js +2 -1
- package/dist/esm/pixelstreamingfrontend.js.map +1 -1
- package/dist/types/Config/Config.d.ts +1 -0
- package/dist/types/PeerConnectionController/AggregatedStats.d.ts +18 -7
- package/dist/types/PeerConnectionController/InboundRTPStats.d.ts +88 -85
- package/dist/types/PeerConnectionController/LatencyCalculator.d.ts +87 -0
- package/dist/types/PeerConnectionController/OutBoundRTPStats.d.ts +46 -12
- package/dist/types/PeerConnectionController/PeerConnectionController.d.ts +17 -3
- package/dist/types/PixelStreaming/PixelStreaming.d.ts +16 -3
- package/dist/types/Util/EventEmitter.d.ts +34 -1
- package/dist/types/VideoPlayer/VideoPlayer.d.ts +1 -1
- package/dist/types/__test__/mockMediaStream.d.ts +49 -0
- package/dist/types/__test__/mockRTCPeerConnection.d.ts +134 -0
- package/dist/types/__test__/mockRTCRtpReceiver.d.ts +3 -0
- package/dist/types/__test__/mockWebSocket.d.ts +33 -0
- package/dist/types/pixelstreamingfrontend.d.ts +2 -1
- package/eslint.config.mjs +52 -0
- package/package.json +13 -14
- package/src/Config/Config.ts +14 -0
- package/src/Config/SettingBase.ts +1 -1
- package/src/Config/SettingFlag.ts +1 -1
- package/src/Config/SettingNumber.ts +1 -1
- package/src/Config/SettingOption.ts +2 -2
- package/src/Config/SettingText.ts +1 -1
- package/src/Inputs/GamepadController.ts +2 -2
- package/src/PeerConnectionController/AggregatedStats.ts +111 -52
- package/src/PeerConnectionController/InboundRTPStats.ts +88 -85
- package/src/PeerConnectionController/LatencyCalculator.ts +392 -0
- package/src/PeerConnectionController/OutBoundRTPStats.ts +46 -12
- package/src/PeerConnectionController/PeerConnectionController.ts +72 -19
- package/src/PixelStreaming/PixelStreaming.ts +29 -4
- package/src/Util/EventEmitter.ts +48 -0
- package/src/VideoPlayer/VideoPlayer.ts +1 -1
- package/src/WebRtcPlayer/WebRtcPlayerController.ts +23 -5
- package/src/__test__/mockRTCPeerConnection.ts +1 -1
- package/src/pixelstreamingfrontend.ts +2 -1
- package/tsconfig.base.json +2 -2
- package/.eslintignore +0 -12
- package/.eslintrc.js +0 -20
- package/.prettierrc.json +0 -7
|
@@ -1,26 +1,60 @@
|
|
|
1
1
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Outbound
|
|
4
|
+
* Outbound RTP stats collected from the RTC Stats Report under `outbound-rtp`.
|
|
5
|
+
* Wrapper around: https://developer.mozilla.org/en-US/docs/Web/API/RTCOutboundRtpStreamStats
|
|
6
|
+
* These are stats for video we are sending to a remote peer.
|
|
5
7
|
*/
|
|
6
|
-
export class
|
|
8
|
+
export class OutboundRTPStats {
|
|
9
|
+
active: boolean | undefined;
|
|
10
|
+
codecId: string | undefined;
|
|
7
11
|
bytesSent: number;
|
|
12
|
+
frameHeight: number | undefined;
|
|
13
|
+
frameWidth: number | undefined;
|
|
14
|
+
framesEncoded: number | undefined;
|
|
15
|
+
framesPerSecond: number | undefined;
|
|
16
|
+
framesSent: number | undefined;
|
|
17
|
+
headerBytesSent: number;
|
|
8
18
|
id: string;
|
|
9
|
-
|
|
19
|
+
keyFramesEncoded: number | undefined;
|
|
20
|
+
kind: string;
|
|
21
|
+
mediaSourceId: string | undefined;
|
|
22
|
+
mid: string | undefined;
|
|
23
|
+
nackCount: number | undefined;
|
|
10
24
|
packetsSent: number;
|
|
11
|
-
|
|
25
|
+
qpSum: number | undefined;
|
|
26
|
+
qualityLimitationDurations: number | undefined;
|
|
27
|
+
qualityLimitationReason: string | undefined;
|
|
28
|
+
remoteId: string | undefined;
|
|
29
|
+
retransmittedBytesSent: number;
|
|
30
|
+
rid: string | undefined;
|
|
31
|
+
scalabilityMode: string | undefined;
|
|
32
|
+
ssrc: string;
|
|
33
|
+
targetBitrate: number | undefined;
|
|
12
34
|
timestamp: number;
|
|
35
|
+
totalEncodeTime: number | undefined;
|
|
36
|
+
totalEncodeBytesTarget: number | undefined;
|
|
37
|
+
totalPacketSendDelay: number | undefined;
|
|
38
|
+
transportId: string | undefined;
|
|
13
39
|
}
|
|
14
40
|
|
|
15
41
|
/**
|
|
16
|
-
*
|
|
42
|
+
* Remote outbound stats collected from the RTC Stats Report under `remote-outbound-rtp`.
|
|
43
|
+
* Wrapper around: https://developer.mozilla.org/en-US/docs/Web/API/RTCRemoteOutboundRtpStreamStats
|
|
44
|
+
* These are stats for media we are receiving from a remote peer.
|
|
17
45
|
*/
|
|
18
|
-
export class
|
|
46
|
+
export class RemoteOutboundRTPStats {
|
|
47
|
+
bytesSent: number | undefined;
|
|
48
|
+
codecId: string;
|
|
49
|
+
id: string | undefined;
|
|
19
50
|
kind: string;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
51
|
+
localId: string | undefined;
|
|
52
|
+
packetsSent: number | undefined;
|
|
53
|
+
remoteTimestamp: number | undefined;
|
|
54
|
+
reportsSent: number | undefined;
|
|
55
|
+
roundTripTimeMeasurements: number | undefined;
|
|
56
|
+
ssrc: string;
|
|
57
|
+
timestamp: number | undefined;
|
|
58
|
+
totalRoundTripTime: number | undefined;
|
|
59
|
+
transportId: string | undefined;
|
|
26
60
|
}
|
|
@@ -6,6 +6,10 @@ import { AggregatedStats } from './AggregatedStats';
|
|
|
6
6
|
import { parseRtpParameters, splitSections } from 'sdp';
|
|
7
7
|
import { RTCUtils } from '../Util/RTCUtils';
|
|
8
8
|
import { CodecStats } from './CodecStats';
|
|
9
|
+
import { SDPUtils } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
|
|
10
|
+
import { LatencyCalculator, LatencyInfo } from './LatencyCalculator';
|
|
11
|
+
|
|
12
|
+
export const kAbsCaptureTime = 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time';
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
15
|
* Handles the Peer Connection
|
|
@@ -18,6 +22,7 @@ export class PeerConnectionController {
|
|
|
18
22
|
updateCodecSelection: boolean;
|
|
19
23
|
videoTrack: MediaStreamTrack;
|
|
20
24
|
audioTrack: MediaStreamTrack;
|
|
25
|
+
latencyCalculator: LatencyCalculator;
|
|
21
26
|
|
|
22
27
|
/**
|
|
23
28
|
* Create a new RTC Peer Connection client
|
|
@@ -27,6 +32,7 @@ export class PeerConnectionController {
|
|
|
27
32
|
constructor(options: RTCConfiguration, config: Config, preferredCodec: string) {
|
|
28
33
|
this.config = config;
|
|
29
34
|
this.createPeerConnection(options, preferredCodec);
|
|
35
|
+
this.latencyCalculator = new LatencyCalculator();
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
createPeerConnection(options: RTCConfiguration, preferredCodec: string) {
|
|
@@ -88,12 +94,26 @@ export class PeerConnectionController {
|
|
|
88
94
|
}
|
|
89
95
|
|
|
90
96
|
/**
|
|
91
|
-
*
|
|
97
|
+
* Receive offer from UE side and process it as the remote description of this peer connection
|
|
92
98
|
*/
|
|
93
99
|
async receiveOffer(offer: RTCSessionDescriptionInit, config: Config) {
|
|
94
100
|
Logger.Info('Receive Offer');
|
|
95
101
|
|
|
102
|
+
// If UE or JSStreamer did send abs-capture-time RTP header extension to a non-Chrome browser
|
|
103
|
+
// then remove it from the SDP because if Firefox detects it in offer or answer it will fail to connect
|
|
104
|
+
// due having 15 or more header extensions: https://mailarchive.ietf.org/arch/msg/rtcweb/QRnWNuWzGuLRovWdHkodNP6VOgg/
|
|
105
|
+
if (this.isFirefox()) {
|
|
106
|
+
// example: a=extmap:15 http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
|
|
107
|
+
offer.sdp = offer.sdp.replace(
|
|
108
|
+
/^a=extmap:\d+ http:\/\/www\.webrtc\.org\/experiments\/rtp-hdrext\/abs-capture-time\r\n/gm,
|
|
109
|
+
''
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
96
113
|
this.peerConnection?.setRemoteDescription(offer).then(() => {
|
|
114
|
+
// Fire event for when remote offer description is set
|
|
115
|
+
this.onSetRemoteDescription(offer);
|
|
116
|
+
|
|
97
117
|
const isLocalhostConnection =
|
|
98
118
|
location.hostname === 'localhost' || location.hostname === '127.0.0.1';
|
|
99
119
|
const isHttpsConnection = location.protocol === 'https:';
|
|
@@ -124,10 +144,10 @@ export class PeerConnectionController {
|
|
|
124
144
|
return this.peerConnection?.setLocalDescription(Answer);
|
|
125
145
|
})
|
|
126
146
|
.then(() => {
|
|
127
|
-
this.
|
|
147
|
+
this.onSetLocalDescription(this.peerConnection?.currentLocalDescription);
|
|
128
148
|
})
|
|
129
|
-
.catch(() => {
|
|
130
|
-
Logger.Error(
|
|
149
|
+
.catch((err) => {
|
|
150
|
+
Logger.Error(`createAnswer() failed - ${err}`);
|
|
131
151
|
});
|
|
132
152
|
});
|
|
133
153
|
});
|
|
@@ -151,25 +171,29 @@ export class PeerConnectionController {
|
|
|
151
171
|
* Generate Aggregated Stats and then fire a onVideo Stats event
|
|
152
172
|
*/
|
|
153
173
|
generateStats() {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
})
|
|
158
|
-
: Promise.resolve();
|
|
159
|
-
const videoPromise = this.videoTrack
|
|
160
|
-
? this.peerConnection?.getStats(this.videoTrack).then((statsData: RTCStatsReport) => {
|
|
161
|
-
this.aggregatedStats.processStats(statsData);
|
|
162
|
-
})
|
|
163
|
-
: Promise.resolve();
|
|
164
|
-
|
|
165
|
-
Promise.allSettled([audioPromise, videoPromise]).then(() => {
|
|
174
|
+
this.peerConnection.getStats().then((statsData: RTCStatsReport) => {
|
|
175
|
+
this.aggregatedStats.processStats(statsData);
|
|
176
|
+
|
|
166
177
|
this.onVideoStats(this.aggregatedStats);
|
|
178
|
+
|
|
179
|
+
// Calculate latency using stats and video receivers and then call the handling function
|
|
180
|
+
const latencyInfo: LatencyInfo = this.latencyCalculator.calculate(
|
|
181
|
+
this.aggregatedStats,
|
|
182
|
+
this.peerConnection.getReceivers()
|
|
183
|
+
);
|
|
184
|
+
this.onLatencyCalculated(latencyInfo);
|
|
185
|
+
|
|
167
186
|
// Update the preferred codec selection based on what was actually negotiated
|
|
168
187
|
if (this.updateCodecSelection && !!this.aggregatedStats.inboundVideoStats.codecId) {
|
|
169
188
|
// Construct the qualified codec name from the mimetype and fmtp
|
|
170
|
-
const codecStats: CodecStats = this.aggregatedStats.codecs.get(
|
|
189
|
+
const codecStats: CodecStats | undefined = this.aggregatedStats.codecs.get(
|
|
171
190
|
this.aggregatedStats.inboundVideoStats.codecId
|
|
172
191
|
);
|
|
192
|
+
|
|
193
|
+
if (codecStats === undefined) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
173
197
|
const codecShortname = codecStats.mimeType.replace('video/', '');
|
|
174
198
|
let fullCodecName = codecShortname;
|
|
175
199
|
if (codecStats.sdpFmtpLine && codecStats.sdpFmtpLine.trim() !== '') {
|
|
@@ -237,9 +261,20 @@ export class PeerConnectionController {
|
|
|
237
261
|
// We use the line 'useinbandfec=1' (which Opus uses) to set our Opus specific audio parameters.
|
|
238
262
|
mungedSDP = mungedSDP.replace('useinbandfec=1', audioSDP);
|
|
239
263
|
|
|
264
|
+
// Add abs-capture-time RTP header extension if we have enabled the setting.
|
|
265
|
+
// Note: As at Feb 2025, Chromium based browsers are the only ones that support this and
|
|
266
|
+
// munging it into the answer in Firefox will cause the connection to fail.
|
|
267
|
+
if (this.config.isFlagEnabled(Flags.EnableCaptureTimeExt) && !this.isFirefox()) {
|
|
268
|
+
mungedSDP = SDPUtils.addVideoHeaderExtensionToSdp(mungedSDP, kAbsCaptureTime);
|
|
269
|
+
}
|
|
270
|
+
|
|
240
271
|
return mungedSDP;
|
|
241
272
|
}
|
|
242
273
|
|
|
274
|
+
isFirefox(): boolean {
|
|
275
|
+
return navigator.userAgent.indexOf('Firefox') > 0;
|
|
276
|
+
}
|
|
277
|
+
|
|
243
278
|
/**
|
|
244
279
|
* When a Ice Candidate is received add to the RTC Peer Connection
|
|
245
280
|
* @param iceCandidate - RTC Ice Candidate from the Signaling Server
|
|
@@ -586,6 +621,15 @@ export class PeerConnectionController {
|
|
|
586
621
|
// Default Functionality: Do Nothing
|
|
587
622
|
}
|
|
588
623
|
|
|
624
|
+
/**
|
|
625
|
+
* And override event for when latency info is calculated
|
|
626
|
+
* @param latencyInfo - Calculated latency information.
|
|
627
|
+
*/
|
|
628
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
629
|
+
onLatencyCalculated(latencyInfo: LatencyInfo) {
|
|
630
|
+
// Default Functionality: Do Nothing
|
|
631
|
+
}
|
|
632
|
+
|
|
589
633
|
/**
|
|
590
634
|
* Event to send the RTC offer to the Signaling server
|
|
591
635
|
* @param offer - RTC Offer
|
|
@@ -596,11 +640,20 @@ export class PeerConnectionController {
|
|
|
596
640
|
}
|
|
597
641
|
|
|
598
642
|
/**
|
|
599
|
-
* Event
|
|
643
|
+
* Event fired when remote offer description is set.
|
|
644
|
+
* @param offer - RTC Offer
|
|
645
|
+
*/
|
|
646
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
647
|
+
onSetRemoteDescription(offer: RTCSessionDescriptionInit) {
|
|
648
|
+
// Default Functionality: Do Nothing
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Event fire when local description answer is set.
|
|
600
653
|
* @param answer - RTC Answer
|
|
601
654
|
*/
|
|
602
655
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
603
|
-
|
|
656
|
+
onSetLocalDescription(answer: RTCSessionDescriptionInit) {
|
|
604
657
|
// Default Functionality: Do Nothing
|
|
605
658
|
}
|
|
606
659
|
|
|
@@ -11,6 +11,7 @@ import { OnScreenKeyboard } from '../UI/OnScreenKeyboard';
|
|
|
11
11
|
import {
|
|
12
12
|
PixelStreamingEventEmitter,
|
|
13
13
|
InitialSettingsEvent,
|
|
14
|
+
LatencyCalculatedEvent,
|
|
14
15
|
LatencyTestResultEvent,
|
|
15
16
|
PixelStreamingEvent,
|
|
16
17
|
StatsReceivedEvent,
|
|
@@ -30,7 +31,9 @@ import {
|
|
|
30
31
|
DataChannelLatencyTestResultEvent,
|
|
31
32
|
PlayerCountEvent,
|
|
32
33
|
WebRtcTCPRelayDetectedEvent,
|
|
33
|
-
SubscribeFailedEvent
|
|
34
|
+
SubscribeFailedEvent,
|
|
35
|
+
WebRtcSdpOfferEvent,
|
|
36
|
+
WebRtcSdpAnswerEvent
|
|
34
37
|
} from '../Util/EventEmitter';
|
|
35
38
|
import { WebXRController } from '../WebXR/WebXRController';
|
|
36
39
|
import { MessageDirection } from '../UeInstanceMessage/StreamMessageController';
|
|
@@ -44,6 +47,7 @@ import {
|
|
|
44
47
|
} from '../DataChannel/DataChannelLatencyTestResults';
|
|
45
48
|
import { RTCUtils } from '../Util/RTCUtils';
|
|
46
49
|
import { IURLSearchParams } from '../Util/IURLSearchParams';
|
|
50
|
+
import { LatencyInfo } from '../PeerConnectionController/LatencyCalculator';
|
|
47
51
|
|
|
48
52
|
export interface PixelStreamingOverrides {
|
|
49
53
|
/** The DOM element where Pixel Streaming video and user input event handlers are attached to.
|
|
@@ -450,21 +454,42 @@ export class PixelStreaming {
|
|
|
450
454
|
}
|
|
451
455
|
|
|
452
456
|
/**
|
|
453
|
-
*
|
|
457
|
+
* Internal function to emit an event when auto connecting occurs
|
|
454
458
|
*/
|
|
455
459
|
_onWebRtcAutoConnect() {
|
|
456
460
|
this._eventEmitter.dispatchEvent(new WebRtcAutoConnectEvent());
|
|
457
461
|
}
|
|
458
462
|
|
|
459
463
|
/**
|
|
460
|
-
*
|
|
464
|
+
* Internal function to emit an event for when SDP negotiation is fully finished.
|
|
461
465
|
*/
|
|
462
466
|
_onWebRtcSdp() {
|
|
463
467
|
this._eventEmitter.dispatchEvent(new WebRtcSdpEvent());
|
|
464
468
|
}
|
|
465
469
|
|
|
466
470
|
/**
|
|
467
|
-
*
|
|
471
|
+
* Internal function to emit an SDP offer after it has been set.
|
|
472
|
+
*/
|
|
473
|
+
_onWebRtcSdpOffer(offer: RTCSessionDescriptionInit) {
|
|
474
|
+
this._eventEmitter.dispatchEvent(new WebRtcSdpOfferEvent({ sdp: offer }));
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Internal function to emit an SDP answer after it has been set.
|
|
479
|
+
*/
|
|
480
|
+
_onWebRtcSdpAnswer(answer: RTCSessionDescriptionInit) {
|
|
481
|
+
this._eventEmitter.dispatchEvent(new WebRtcSdpAnswerEvent({ sdp: answer }));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Internal function call to emit a `latencyCalculated` event.
|
|
486
|
+
*/
|
|
487
|
+
_onLatencyCalculated(latencyInfo: LatencyInfo) {
|
|
488
|
+
this._eventEmitter.dispatchEvent(new LatencyCalculatedEvent({ latencyInfo }));
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Internal function to emits a StreamLoading event
|
|
468
493
|
*/
|
|
469
494
|
_onStreamLoading() {
|
|
470
495
|
this._eventEmitter.dispatchEvent(new StreamLoadingEvent());
|
package/src/Util/EventEmitter.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { FlagsIds, NumericParametersIds, OptionParametersIds, TextParametersIds
|
|
|
2
2
|
import { LatencyTestResults } from '../DataChannel/LatencyTestResults';
|
|
3
3
|
import { AggregatedStats } from '../PeerConnectionController/AggregatedStats';
|
|
4
4
|
import { InitialSettings } from '../DataChannel/InitialSettings';
|
|
5
|
+
import { LatencyInfo } from '../PeerConnectionController/LatencyCalculator';
|
|
5
6
|
import { Messages } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
|
|
6
7
|
import { SettingFlag } from '../Config/SettingFlag';
|
|
7
8
|
import { SettingNumber } from '../Config/SettingNumber';
|
|
@@ -90,6 +91,36 @@ export class WebRtcSdpEvent extends Event {
|
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
93
|
|
|
94
|
+
/**
|
|
95
|
+
* An event that is emitted after the SDP answer is set.
|
|
96
|
+
*/
|
|
97
|
+
export class WebRtcSdpAnswerEvent extends Event {
|
|
98
|
+
override readonly type: 'webRtcSdpAnswer';
|
|
99
|
+
readonly data: {
|
|
100
|
+
/** The sdp answer */
|
|
101
|
+
sdp: RTCSessionDescriptionInit;
|
|
102
|
+
};
|
|
103
|
+
constructor(data: WebRtcSdpAnswerEvent['data']) {
|
|
104
|
+
super('webRtcSdpAnswer');
|
|
105
|
+
this.data = data;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* An event that is emitted after the SDP offer is set.
|
|
111
|
+
*/
|
|
112
|
+
export class WebRtcSdpOfferEvent extends Event {
|
|
113
|
+
override readonly type: 'webRtcSdpOffer';
|
|
114
|
+
readonly data: {
|
|
115
|
+
/** The sdp offer */
|
|
116
|
+
sdp: RTCSessionDescriptionInit;
|
|
117
|
+
};
|
|
118
|
+
constructor(data: WebRtcSdpOfferEvent['data']) {
|
|
119
|
+
super('webRtcSdpOffer');
|
|
120
|
+
this.data = data;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
93
124
|
/**
|
|
94
125
|
* An event that is emitted when auto connecting.
|
|
95
126
|
*/
|
|
@@ -382,6 +413,20 @@ export class LatencyTestResultEvent extends Event {
|
|
|
382
413
|
}
|
|
383
414
|
}
|
|
384
415
|
|
|
416
|
+
/**
|
|
417
|
+
* An event that is emitted everytime latency is calculated using the WebRTC stats API.
|
|
418
|
+
*/
|
|
419
|
+
export class LatencyCalculatedEvent extends Event {
|
|
420
|
+
override readonly type: 'latencyCalculated';
|
|
421
|
+
readonly data: {
|
|
422
|
+
latencyInfo: LatencyInfo;
|
|
423
|
+
};
|
|
424
|
+
constructor(data: LatencyCalculatedEvent['data']) {
|
|
425
|
+
super('latencyCalculated');
|
|
426
|
+
this.data = data;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
385
430
|
/**
|
|
386
431
|
* An event that is emitted when receiving data channel latency test response from server.
|
|
387
432
|
* This event is handled by DataChannelLatencyTestController
|
|
@@ -560,6 +605,8 @@ export type PixelStreamingEvent =
|
|
|
560
605
|
| AfkTimedOutEvent
|
|
561
606
|
| VideoEncoderAvgQPEvent
|
|
562
607
|
| WebRtcSdpEvent
|
|
608
|
+
| WebRtcSdpOfferEvent
|
|
609
|
+
| WebRtcSdpAnswerEvent
|
|
563
610
|
| WebRtcAutoConnectEvent
|
|
564
611
|
| WebRtcConnectingEvent
|
|
565
612
|
| WebRtcConnectedEvent
|
|
@@ -581,6 +628,7 @@ export type PixelStreamingEvent =
|
|
|
581
628
|
| StatsReceivedEvent
|
|
582
629
|
| StreamerListMessageEvent
|
|
583
630
|
| StreamerIDChangedMessageEvent
|
|
631
|
+
| LatencyCalculatedEvent
|
|
584
632
|
| LatencyTestResultEvent
|
|
585
633
|
| DataChannelLatencyTestResponseEvent
|
|
586
634
|
| DataChannelLatencyTestResultEvent
|
|
@@ -55,6 +55,7 @@ import {
|
|
|
55
55
|
import { IURLSearchParams } from '../Util/IURLSearchParams';
|
|
56
56
|
import { IInputController } from '../Inputs/IInputController';
|
|
57
57
|
import { GamepadController } from '../Inputs/GamepadController';
|
|
58
|
+
import { LatencyInfo } from '../PeerConnectionController/LatencyCalculator';
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
61
|
* Entry point for the WebRTC Player
|
|
@@ -1075,15 +1076,29 @@ export class WebRtcPlayerController {
|
|
|
1075
1076
|
);
|
|
1076
1077
|
|
|
1077
1078
|
// set up peer connection controller video stats
|
|
1078
|
-
this.peerConnectionController.onVideoStats = (event: AggregatedStats) =>
|
|
1079
|
+
this.peerConnectionController.onVideoStats = (event: AggregatedStats) => {
|
|
1080
|
+
this.handleVideoStats(event);
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
/* Set event handler for latency information is calculated, handle the event by propogating to the PixelStreaming API */
|
|
1084
|
+
this.peerConnectionController.onLatencyCalculated = (latencyInfo: LatencyInfo) => {
|
|
1085
|
+
this.pixelStreaming._onLatencyCalculated(latencyInfo);
|
|
1086
|
+
};
|
|
1079
1087
|
|
|
1080
1088
|
/* When the Peer Connection wants to send an offer have it handled */
|
|
1081
|
-
this.peerConnectionController.onSendWebRTCOffer = (offer: RTCSessionDescriptionInit) =>
|
|
1089
|
+
this.peerConnectionController.onSendWebRTCOffer = (offer: RTCSessionDescriptionInit) => {
|
|
1082
1090
|
this.handleSendWebRTCOffer(offer);
|
|
1091
|
+
};
|
|
1083
1092
|
|
|
1084
|
-
/*
|
|
1085
|
-
this.peerConnectionController.
|
|
1086
|
-
this.handleSendWebRTCAnswer(
|
|
1093
|
+
/* Set event handler for when local answer description is set */
|
|
1094
|
+
this.peerConnectionController.onSetLocalDescription = (answer: RTCSessionDescriptionInit) => {
|
|
1095
|
+
this.handleSendWebRTCAnswer(answer);
|
|
1096
|
+
};
|
|
1097
|
+
|
|
1098
|
+
/* Set event handler for when remote offer description is set */
|
|
1099
|
+
this.peerConnectionController.onSetRemoteDescription = (offer: RTCSessionDescriptionInit) => {
|
|
1100
|
+
this.pixelStreaming._onWebRtcSdpOffer(offer);
|
|
1101
|
+
};
|
|
1087
1102
|
|
|
1088
1103
|
/* When the Peer Connection ice candidate is added have it handled */
|
|
1089
1104
|
this.peerConnectionController.onPeerIceCandidate = (
|
|
@@ -1484,6 +1499,9 @@ export class WebRtcPlayerController {
|
|
|
1484
1499
|
if (this.isUsingSFU) {
|
|
1485
1500
|
this.protocol.sendMessage(MessageHelpers.createMessage(Messages.dataChannelRequest));
|
|
1486
1501
|
}
|
|
1502
|
+
|
|
1503
|
+
// Send answer back to Pixel Streaming main class for event dispatch
|
|
1504
|
+
this.pixelStreaming._onWebRtcSdpAnswer(answer);
|
|
1487
1505
|
}
|
|
1488
1506
|
|
|
1489
1507
|
/**
|
|
@@ -111,7 +111,7 @@ export class MockRTCPeerConnectionImpl implements RTCPeerConnection {
|
|
|
111
111
|
throw new Error("Method not implemented.");
|
|
112
112
|
}
|
|
113
113
|
getReceivers(): RTCRtpReceiver[] {
|
|
114
|
-
|
|
114
|
+
return [];
|
|
115
115
|
}
|
|
116
116
|
getSenders(): RTCRtpSender[] {
|
|
117
117
|
throw new Error("Method not implemented.");
|
|
@@ -19,7 +19,8 @@ export { CandidatePairStats } from './PeerConnectionController/CandidatePairStat
|
|
|
19
19
|
export { CandidateStat } from './PeerConnectionController/CandidateStat';
|
|
20
20
|
export { DataChannelStats } from './PeerConnectionController/DataChannelStats';
|
|
21
21
|
export { InboundAudioStats, InboundVideoStats } from './PeerConnectionController/InboundRTPStats';
|
|
22
|
-
export {
|
|
22
|
+
export { OutboundRTPStats, RemoteOutboundRTPStats } from './PeerConnectionController/OutBoundRTPStats';
|
|
23
|
+
export * from './PeerConnectionController/LatencyCalculator';
|
|
23
24
|
export * from './DataChannel/DataChannelLatencyTestResults';
|
|
24
25
|
export * from './Util/EventEmitter';
|
|
25
26
|
export * from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
|
package/tsconfig.base.json
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"declarationDir": "./dist/types"
|
|
16
16
|
},
|
|
17
17
|
"lib": ["ES6"],
|
|
18
|
-
"include": ["./src
|
|
19
|
-
"exclude": ["./src/**/*.test.ts"
|
|
18
|
+
"include": ["./src/**/*.ts"],
|
|
19
|
+
"exclude": ["./src/**/*.test.ts"],
|
|
20
20
|
"typedocOptions": {
|
|
21
21
|
"exclude": "src/index.*",
|
|
22
22
|
"entryPoints": ["src/pixelstreamingfrontend.ts"],
|
package/.eslintignore
DELETED
package/.eslintrc.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
root: true,
|
|
5
|
-
parser: '@typescript-eslint/parser',
|
|
6
|
-
parserOptions: { project: './tsconfig.cjs.json' },
|
|
7
|
-
plugins: ['@typescript-eslint'],
|
|
8
|
-
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', "plugin:prettier/recommended"],
|
|
9
|
-
rules: {
|
|
10
|
-
"@typescript-eslint/no-explicit-any": "off",
|
|
11
|
-
"@typescript-eslint/no-unused-vars": [
|
|
12
|
-
"error",
|
|
13
|
-
{
|
|
14
|
-
"argsIgnorePattern": "^_",
|
|
15
|
-
"varsIgnorePattern": "^_",
|
|
16
|
-
"caughtErrorsIgnorePattern": "^_"
|
|
17
|
-
}
|
|
18
|
-
]
|
|
19
|
-
}
|
|
20
|
-
};
|