@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
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
export interface MockRTCPeerConnectionSpyFunctions {
|
|
2
|
+
constructorSpy: null | ((config: RTCConfiguration) => void);
|
|
3
|
+
closeSpy: null | (() => void);
|
|
4
|
+
setRemoteDescriptionSpy: null | ((description: RTCSessionDescriptionInit) => void);
|
|
5
|
+
setLocalDescriptionSpy: null | ((description: RTCLocalSessionDescriptionInit) => void);
|
|
6
|
+
createAnswerSpy: null | (() => void);
|
|
7
|
+
addTransceiverSpy: null | ((trackOrKind: string | MediaStreamTrack, init?: RTCRtpTransceiverInit | undefined) => void);
|
|
8
|
+
addIceCandidateSpy: null | ((candidate: RTCIceCandidateInit) => void);
|
|
9
|
+
sendDataSpy: null | ((data: ArrayBuffer) => void);
|
|
10
|
+
}
|
|
11
|
+
export interface MockRTCPeerConnectionTriggerFunctions {
|
|
12
|
+
triggerIceConnectionStateChange: null | ((state: RTCIceConnectionState) => void);
|
|
13
|
+
triggerOnTrack: null | ((data: RTCTrackEventInit) => void);
|
|
14
|
+
triggerOnIceCandidate: null | ((data: RTCPeerConnectionIceEventInit) => void);
|
|
15
|
+
triggerOnDataChannel: null | ((data: RTCDataChannelEventInit) => void);
|
|
16
|
+
}
|
|
17
|
+
export declare class MockRTCPeerConnectionImpl implements RTCPeerConnection {
|
|
18
|
+
canTrickleIceCandidates: boolean | null;
|
|
19
|
+
connectionState: RTCPeerConnectionState;
|
|
20
|
+
currentLocalDescription: RTCSessionDescription | null;
|
|
21
|
+
currentRemoteDescription: RTCSessionDescription | null;
|
|
22
|
+
iceConnectionState: RTCIceConnectionState;
|
|
23
|
+
iceGatheringState: RTCIceGatheringState;
|
|
24
|
+
localDescription: RTCSessionDescription | null;
|
|
25
|
+
pendingLocalDescription: RTCSessionDescription | null;
|
|
26
|
+
pendingRemoteDescription: RTCSessionDescription | null;
|
|
27
|
+
remoteDescription: RTCSessionDescription | null;
|
|
28
|
+
sctp: RTCSctpTransport | null;
|
|
29
|
+
signalingState: RTCSignalingState;
|
|
30
|
+
_dataChannels: RTCDataChannel[];
|
|
31
|
+
constructor(config: RTCConfiguration);
|
|
32
|
+
onconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
|
|
33
|
+
ondatachannel: ((this: RTCPeerConnection, ev: RTCDataChannelEvent) => any) | null;
|
|
34
|
+
onicecandidate: ((this: RTCPeerConnection, ev: RTCPeerConnectionIceEvent) => any) | null;
|
|
35
|
+
onicecandidateerror: ((this: RTCPeerConnection, ev: Event) => any) | null;
|
|
36
|
+
oniceconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
|
|
37
|
+
onicegatheringstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
|
|
38
|
+
onnegotiationneeded: ((this: RTCPeerConnection, ev: Event) => any) | null;
|
|
39
|
+
onsignalingstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;
|
|
40
|
+
ontrack: ((this: RTCPeerConnection, ev: RTCTrackEvent) => any) | null;
|
|
41
|
+
addIceCandidate(candidate?: RTCIceCandidateInit | undefined): Promise<void>;
|
|
42
|
+
addIceCandidate(candidate: RTCIceCandidateInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;
|
|
43
|
+
addTrack(track: MediaStreamTrack, ...streams: MediaStream[]): RTCRtpSender;
|
|
44
|
+
addTransceiver(trackOrKind: string | MediaStreamTrack, init?: RTCRtpTransceiverInit | undefined): RTCRtpTransceiver;
|
|
45
|
+
createAnswer(options?: RTCAnswerOptions | undefined): Promise<RTCSessionDescriptionInit>;
|
|
46
|
+
createAnswer(successCallback: RTCSessionDescriptionCallback, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;
|
|
47
|
+
createDataChannel(label: string, dataChannelDict?: RTCDataChannelInit | undefined): RTCDataChannel;
|
|
48
|
+
createOffer(options?: RTCOfferOptions | undefined): Promise<RTCSessionDescriptionInit>;
|
|
49
|
+
createOffer(successCallback: RTCSessionDescriptionCallback, failureCallback: RTCPeerConnectionErrorCallback, options?: RTCOfferOptions | undefined): Promise<void>;
|
|
50
|
+
getConfiguration(): RTCConfiguration;
|
|
51
|
+
getReceivers(): RTCRtpReceiver[];
|
|
52
|
+
getSenders(): RTCRtpSender[];
|
|
53
|
+
getStats(selector?: MediaStreamTrack | null | undefined): Promise<RTCStatsReport>;
|
|
54
|
+
getTransceivers(): RTCRtpTransceiver[];
|
|
55
|
+
removeTrack(sender: RTCRtpSender): void;
|
|
56
|
+
restartIce(): void;
|
|
57
|
+
setConfiguration(configuration?: RTCConfiguration | undefined): void;
|
|
58
|
+
setLocalDescription(description?: RTCLocalSessionDescriptionInit | undefined): Promise<void>;
|
|
59
|
+
setLocalDescription(description: RTCLocalSessionDescriptionInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;
|
|
60
|
+
setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void>;
|
|
61
|
+
setRemoteDescription(description: RTCSessionDescriptionInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;
|
|
62
|
+
addEventListener<K extends keyof RTCPeerConnectionEventMap>(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
63
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
64
|
+
removeEventListener<K extends keyof RTCPeerConnectionEventMap>(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void;
|
|
65
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void;
|
|
66
|
+
dispatchEvent(event: Event): boolean;
|
|
67
|
+
static generateCertificate(keygenAlgorithm: AlgorithmIdentifier): Promise<RTCCertificate>;
|
|
68
|
+
close(): void;
|
|
69
|
+
triggerIceConnectionStateChange(state: RTCIceConnectionState): void;
|
|
70
|
+
triggerOnTrack(data: RTCTrackEventInit): void;
|
|
71
|
+
triggerOnIceCandidate(data: RTCPeerConnectionIceEventInit): void;
|
|
72
|
+
triggerOnDataChannel(data: RTCDataChannelEventInit): void;
|
|
73
|
+
}
|
|
74
|
+
export declare class MockRTCIceCandidateImpl implements RTCIceCandidate {
|
|
75
|
+
address: string | null;
|
|
76
|
+
candidate: string;
|
|
77
|
+
component: RTCIceComponent | null;
|
|
78
|
+
foundation: string | null;
|
|
79
|
+
port: number | null;
|
|
80
|
+
priority: number | null;
|
|
81
|
+
protocol: RTCIceProtocol | null;
|
|
82
|
+
relatedAddress: string | null;
|
|
83
|
+
relatedPort: number | null;
|
|
84
|
+
sdpMLineIndex: number | null;
|
|
85
|
+
sdpMid: string | null;
|
|
86
|
+
tcpType: RTCIceTcpCandidateType | null;
|
|
87
|
+
type: RTCIceCandidateType | null;
|
|
88
|
+
usernameFragment: string | null;
|
|
89
|
+
constructor(options?: RTCIceCandidateInit);
|
|
90
|
+
toJSON(): RTCIceCandidateInit;
|
|
91
|
+
}
|
|
92
|
+
export declare class MockRTCDataChannelImpl implements RTCDataChannel {
|
|
93
|
+
binaryType: BinaryType;
|
|
94
|
+
bufferedAmount: number;
|
|
95
|
+
bufferedAmountLowThreshold: number;
|
|
96
|
+
id: number | null;
|
|
97
|
+
label: string;
|
|
98
|
+
maxPacketLifeTime: number | null;
|
|
99
|
+
maxRetransmits: number | null;
|
|
100
|
+
negotiated: boolean;
|
|
101
|
+
ordered: boolean;
|
|
102
|
+
protocol: string;
|
|
103
|
+
readyState: RTCDataChannelState;
|
|
104
|
+
constructor();
|
|
105
|
+
onbufferedamountlow: ((this: RTCDataChannel, ev: Event) => any) | null;
|
|
106
|
+
onclose: ((this: RTCDataChannel, ev: Event) => any) | null;
|
|
107
|
+
onclosing: ((this: RTCDataChannel, ev: Event) => any) | null;
|
|
108
|
+
onerror: ((this: RTCDataChannel, ev: Event) => any) | null;
|
|
109
|
+
onmessage: ((this: RTCDataChannel, ev: MessageEvent<any>) => any) | null;
|
|
110
|
+
onopen: ((this: RTCDataChannel, ev: Event) => any) | null;
|
|
111
|
+
close(): void;
|
|
112
|
+
send(data: string): void;
|
|
113
|
+
send(data: Blob): void;
|
|
114
|
+
send(data: ArrayBuffer): void;
|
|
115
|
+
send(data: ArrayBufferView): void;
|
|
116
|
+
addEventListener<K extends keyof RTCDataChannelEventMap>(type: K, listener: (this: RTCDataChannel, ev: RTCDataChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
117
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
118
|
+
removeEventListener<K extends keyof RTCDataChannelEventMap>(type: K, listener: (this: RTCDataChannel, ev: RTCDataChannelEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void;
|
|
119
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void;
|
|
120
|
+
dispatchEvent(event: Event): boolean;
|
|
121
|
+
}
|
|
122
|
+
export declare class MockRTCDataChannelEventImpl extends Event implements RTCDataChannelEvent {
|
|
123
|
+
channel: RTCDataChannel;
|
|
124
|
+
constructor(name: string, data: RTCDataChannelEventInit);
|
|
125
|
+
}
|
|
126
|
+
export declare class MockRTCTrackEventImpl extends Event implements RTCTrackEvent {
|
|
127
|
+
receiver: RTCRtpReceiver;
|
|
128
|
+
streams: readonly MediaStream[];
|
|
129
|
+
track: MediaStreamTrack;
|
|
130
|
+
transceiver: RTCRtpTransceiver;
|
|
131
|
+
constructor(name: string, data: RTCTrackEventInit);
|
|
132
|
+
}
|
|
133
|
+
export declare const mockRTCPeerConnection: () => [MockRTCPeerConnectionSpyFunctions, MockRTCPeerConnectionTriggerFunctions];
|
|
134
|
+
export declare const unmockRTCPeerConnection: () => void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BaseMessage } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
|
|
2
|
+
export interface MockWebSocketSpyFunctions {
|
|
3
|
+
constructorSpy: null | ((url: string) => void);
|
|
4
|
+
openSpy: null | ((event: Event) => void);
|
|
5
|
+
errorSpy: null | ((event: Event) => void);
|
|
6
|
+
closeSpy: null | ((event: CloseEvent) => void);
|
|
7
|
+
messageSpy: null | ((event: MessageEvent) => void);
|
|
8
|
+
messageBinarySpy: null | ((event: MessageEvent) => void);
|
|
9
|
+
sendSpy: null | ((data: string | Blob | ArrayBufferView | ArrayBufferLike) => void);
|
|
10
|
+
}
|
|
11
|
+
export interface MockWebSocketTriggerFunctions {
|
|
12
|
+
triggerOnOpen: null | (() => void);
|
|
13
|
+
triggerOnError: null | (() => void);
|
|
14
|
+
triggerOnClose: null | ((closeReason?: CloseEventInit) => void);
|
|
15
|
+
triggerOnMessage: null | ((message?: BaseMessage) => void);
|
|
16
|
+
triggerOnMessageBinary: null | ((message?: Blob) => void);
|
|
17
|
+
triggerRemoteClose: null | ((code?: number, reason?: string) => void);
|
|
18
|
+
}
|
|
19
|
+
export declare class MockWebSocketImpl extends WebSocket {
|
|
20
|
+
_readyState: number;
|
|
21
|
+
constructor(url: string | URL, protocols?: string | string[]);
|
|
22
|
+
get readyState(): number;
|
|
23
|
+
close(code?: number | undefined, reason?: string | undefined): void;
|
|
24
|
+
send(data: string | Blob | ArrayBufferView | ArrayBufferLike): void;
|
|
25
|
+
triggerOnOpen(): void;
|
|
26
|
+
triggerOnError(): void;
|
|
27
|
+
triggerOnClose(closeReason?: CloseEventInit): void;
|
|
28
|
+
triggerRemoteClose(code?: number, reason?: string): void;
|
|
29
|
+
triggerOnMessage(message: BaseMessage): void;
|
|
30
|
+
triggerOnMessageBinary(message?: Blob): void;
|
|
31
|
+
}
|
|
32
|
+
export declare const mockWebSocket: () => [MockWebSocketSpyFunctions, MockWebSocketTriggerFunctions];
|
|
33
|
+
export declare const unmockWebSocket: () => void;
|
|
@@ -17,7 +17,8 @@ export { CandidatePairStats } from './PeerConnectionController/CandidatePairStat
|
|
|
17
17
|
export { CandidateStat } from './PeerConnectionController/CandidateStat';
|
|
18
18
|
export { DataChannelStats } from './PeerConnectionController/DataChannelStats';
|
|
19
19
|
export { InboundAudioStats, InboundVideoStats } from './PeerConnectionController/InboundRTPStats';
|
|
20
|
-
export {
|
|
20
|
+
export { OutboundRTPStats, RemoteOutboundRTPStats } from './PeerConnectionController/OutBoundRTPStats';
|
|
21
|
+
export * from './PeerConnectionController/LatencyCalculator';
|
|
21
22
|
export * from './DataChannel/DataChannelLatencyTestResults';
|
|
22
23
|
export * from './Util/EventEmitter';
|
|
23
24
|
export * from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
2
|
+
import eslint from '@eslint/js';
|
|
3
|
+
import tseslint from 'typescript-eslint';
|
|
4
|
+
|
|
5
|
+
export default tseslint.config(
|
|
6
|
+
{
|
|
7
|
+
ignores: ["src/__test__/**/*.ts", "**/*.test.ts"],
|
|
8
|
+
},
|
|
9
|
+
eslint.configs.recommended,
|
|
10
|
+
tseslint.configs.recommendedTypeCheckedOnly,
|
|
11
|
+
{
|
|
12
|
+
languageOptions: {
|
|
13
|
+
parser: tseslint.parser,
|
|
14
|
+
parserOptions: {
|
|
15
|
+
project: 'tsconfig.base.json',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
files: ["src/**/*.ts"],
|
|
19
|
+
rules: {
|
|
20
|
+
// TODO: when updating eslint a lot of issues suddently popped up
|
|
21
|
+
// these ignores should be turned off slowly and new issues should
|
|
22
|
+
// be addressed
|
|
23
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
24
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
25
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
26
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
27
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
28
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
29
|
+
"@typescript-eslint/no-floating-promises": "off",
|
|
30
|
+
"@typescript-eslint/restrict-plus-operands": "off",
|
|
31
|
+
"@typescript-eslint/unbound-method": "off",
|
|
32
|
+
"@typescript-eslint/no-duplicate-type-constituents": "off",
|
|
33
|
+
"@typescript-eslint/no-redundant-type-constituents": "off",
|
|
34
|
+
"@typescript-eslint/restrict-template-expressions": "off",
|
|
35
|
+
"@typescript-eslint/no-unnecessary-type-assertion": "off",
|
|
36
|
+
"@typescript-eslint/no-array-delete": "off",
|
|
37
|
+
"@typescript-eslint/no-unsafe-enum-comparison": "off",
|
|
38
|
+
"@typescript-eslint/require-await": "off",
|
|
39
|
+
"@typescript-eslint/no-base-to-string": "off",
|
|
40
|
+
"no-unused-vars": "off",
|
|
41
|
+
"@typescript-eslint/no-unused-vars": [
|
|
42
|
+
"error",
|
|
43
|
+
{
|
|
44
|
+
"argsIgnorePattern": "^_",
|
|
45
|
+
"varsIgnorePattern": "^_",
|
|
46
|
+
"caughtErrorsIgnorePattern": "^_"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epicgames-ps/lib-pixelstreamingfrontend-ue5.5",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Frontend library for Unreal Engine 5.5 Pixel Streaming",
|
|
5
5
|
"main": "dist/cjs/pixelstreamingfrontend.js",
|
|
6
6
|
"module": "dist/esm/pixelstreamingfrontend.js",
|
|
@@ -12,29 +12,28 @@
|
|
|
12
12
|
"build:esm": "tsc --project tsconfig.esm.json",
|
|
13
13
|
"build": "npm run build:cjs && npm run build:esm",
|
|
14
14
|
"rebuild": "npm run clean && npm run build",
|
|
15
|
-
"watch": "nodemon -V -d 3 --watch src --watch ../../Common/dist -e
|
|
16
|
-
"lint": "eslint src
|
|
15
|
+
"watch": "nodemon -V -d 3 --watch src --watch ../../Common/dist -e \"ts,js,mjs,cjs,json\" --exec \"npm run build:cjs\"",
|
|
16
|
+
"lint": "eslint src",
|
|
17
17
|
"test": "jest --detectOpenHandles --coverage=true",
|
|
18
18
|
"spellcheck": "cspell \"{README.md,.github/*.md,src/**/*.ts}\""
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
+
"@eslint/js": "^9.20.0",
|
|
21
22
|
"@types/jest": "^29.5.14",
|
|
22
|
-
"@
|
|
23
|
-
"cspell": "^
|
|
24
|
-
"eslint": "^
|
|
25
|
-
"eslint-config-prettier": "^9.1.0",
|
|
26
|
-
"eslint-plugin-prettier": "^5.2.1",
|
|
23
|
+
"@types/webxr": "^0.5.21",
|
|
24
|
+
"cspell": "^8.17.3",
|
|
25
|
+
"eslint": "^9.20.0",
|
|
27
26
|
"jest": "^29.7.0",
|
|
28
27
|
"jest-environment-jsdom": "^29.7.0",
|
|
29
|
-
"
|
|
28
|
+
"nodemon": "^3.1.9",
|
|
29
|
+
"rimraf": "^6.0.1",
|
|
30
30
|
"ts-jest": "^29.2.5",
|
|
31
|
-
"
|
|
32
|
-
"typescript": "^
|
|
31
|
+
"typescript": "^5.7.3",
|
|
32
|
+
"typescript-eslint": "^8.24.0"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@epicgames-ps/lib-pixelstreamingcommon-ue5.5": "^0.
|
|
36
|
-
"
|
|
37
|
-
"sdp": "^3.1.0"
|
|
35
|
+
"@epicgames-ps/lib-pixelstreamingcommon-ue5.5": "^0.2.8",
|
|
36
|
+
"sdp": "^3.2.0"
|
|
38
37
|
},
|
|
39
38
|
"repository": {
|
|
40
39
|
"type": "git",
|
package/src/Config/Config.ts
CHANGED
|
@@ -33,6 +33,7 @@ export class Flags {
|
|
|
33
33
|
static XRControllerInput = 'XRControllerInput' as const;
|
|
34
34
|
static WaitForStreamer = 'WaitForStreamer' as const;
|
|
35
35
|
static HideUI = 'HideUI' as const;
|
|
36
|
+
static EnableCaptureTimeExt = 'EnableCaptureTimeExt' as const;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export type FlagsKeys = Exclude<keyof typeof Flags, 'prototype'>;
|
|
@@ -564,6 +565,19 @@ export class Config {
|
|
|
564
565
|
)
|
|
565
566
|
);
|
|
566
567
|
|
|
568
|
+
this.flags.set(
|
|
569
|
+
Flags.EnableCaptureTimeExt,
|
|
570
|
+
new SettingFlag(
|
|
571
|
+
Flags.EnableCaptureTimeExt,
|
|
572
|
+
'Enable abs-capture-time',
|
|
573
|
+
'Enables the abs-capture-time RTP header extension',
|
|
574
|
+
settings && Object.prototype.hasOwnProperty.call(settings, Flags.EnableCaptureTimeExt)
|
|
575
|
+
? settings[Flags.EnableCaptureTimeExt]
|
|
576
|
+
: true,
|
|
577
|
+
useUrlParams
|
|
578
|
+
)
|
|
579
|
+
);
|
|
580
|
+
|
|
567
581
|
/**
|
|
568
582
|
* Numeric parameters
|
|
569
583
|
*/
|
|
@@ -18,7 +18,7 @@ export class SettingBase {
|
|
|
18
18
|
label: string,
|
|
19
19
|
description: string,
|
|
20
20
|
defaultSettingValue: unknown,
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => {
|
|
23
23
|
/* Do nothing, to be overridden. */
|
|
24
24
|
}
|
|
@@ -16,7 +16,7 @@ export class SettingFlag<CustomIds extends string = FlagsIds> extends SettingBas
|
|
|
16
16
|
description: string,
|
|
17
17
|
defaultFlagValue: boolean,
|
|
18
18
|
useUrlParams: boolean,
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => {
|
|
21
21
|
/* Do nothing, to be overridden. */
|
|
22
22
|
}
|
|
@@ -21,7 +21,7 @@ export class SettingNumber<CustomIds extends string = NumericParametersIds> exte
|
|
|
21
21
|
max: number | null,
|
|
22
22
|
defaultNumber: number,
|
|
23
23
|
useUrlParams: boolean,
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => {
|
|
26
26
|
/* Do nothing, to be overridden. */
|
|
27
27
|
}
|
|
@@ -22,12 +22,12 @@ export class SettingOption<CustomIds extends string = OptionParametersIds> exten
|
|
|
22
22
|
defaultTextValue: string,
|
|
23
23
|
options: Array<string>,
|
|
24
24
|
useUrlParams: boolean,
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
defaultUrlParamResolver: (urlParamValue: string) => string = function (value: string) {
|
|
27
27
|
/* Return the string as-is by default */
|
|
28
28
|
return value;
|
|
29
29
|
},
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => {
|
|
32
32
|
/* Do nothing, to be overridden. */
|
|
33
33
|
}
|
|
@@ -17,7 +17,7 @@ export class SettingText<CustomIds extends string = TextParametersIds> extends S
|
|
|
17
17
|
description: string,
|
|
18
18
|
defaultTextValue: string,
|
|
19
19
|
useUrlParams: boolean,
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
defaultOnChangeListener: (changedValue: unknown, setting: SettingBase) => void = () => {
|
|
22
22
|
/* Do nothing, to be overridden. */
|
|
23
23
|
}
|
|
@@ -21,7 +21,7 @@ declare global {
|
|
|
21
21
|
/**
|
|
22
22
|
* Gamepad layout codes enum
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
export enum GamepadLayout {
|
|
26
26
|
RightClusterBottomButton = 0,
|
|
27
27
|
RightClusterRightButton = 1,
|
|
@@ -46,7 +46,7 @@ export enum GamepadLayout {
|
|
|
46
46
|
RightStickHorizontal = 2,
|
|
47
47
|
RightStickVertical = 3
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Handles gamepad events from the document to send to the streamer.
|
|
@@ -5,7 +5,7 @@ import { InboundTrackStats } from './InboundTrackStats';
|
|
|
5
5
|
import { DataChannelStats } from './DataChannelStats';
|
|
6
6
|
import { CandidateStat } from './CandidateStat';
|
|
7
7
|
import { CandidatePairStats } from './CandidatePairStats';
|
|
8
|
-
import {
|
|
8
|
+
import { RemoteOutboundRTPStats, OutboundRTPStats } from './OutBoundRTPStats';
|
|
9
9
|
import { SessionStats } from './SessionStats';
|
|
10
10
|
import { StreamStats } from './StreamStats';
|
|
11
11
|
import { CodecStats } from './CodecStats';
|
|
@@ -15,15 +15,17 @@ import { Logger } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
|
|
|
15
15
|
* The Aggregated Stats that is generated from the RTC Stats Report
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
type RTCStatsTypePS = RTCStatsType | 'stream' | 'media-playout' | 'track';
|
|
19
18
|
export class AggregatedStats {
|
|
20
19
|
inboundVideoStats: InboundVideoStats;
|
|
21
20
|
inboundAudioStats: InboundAudioStats;
|
|
22
21
|
candidatePairs: Array<CandidatePairStats>;
|
|
23
|
-
|
|
22
|
+
datachannelStats: DataChannelStats;
|
|
24
23
|
localCandidates: Array<CandidateStat>;
|
|
25
24
|
remoteCandidates: Array<CandidateStat>;
|
|
26
|
-
|
|
25
|
+
outboundVideoStats: OutboundRTPStats;
|
|
26
|
+
outboundAudioStats: OutboundRTPStats;
|
|
27
|
+
remoteOutboundVideoStats: RemoteOutboundRTPStats;
|
|
28
|
+
remoteOutboundAudioStats: RemoteOutboundRTPStats;
|
|
27
29
|
sessionStats: SessionStats;
|
|
28
30
|
streamStats: StreamStats;
|
|
29
31
|
codecs: Map<string, CodecStats>;
|
|
@@ -32,8 +34,11 @@ export class AggregatedStats {
|
|
|
32
34
|
constructor() {
|
|
33
35
|
this.inboundVideoStats = new InboundVideoStats();
|
|
34
36
|
this.inboundAudioStats = new InboundAudioStats();
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
37
|
+
this.datachannelStats = new DataChannelStats();
|
|
38
|
+
this.outboundVideoStats = new OutboundRTPStats();
|
|
39
|
+
this.outboundAudioStats = new OutboundRTPStats();
|
|
40
|
+
this.remoteOutboundAudioStats = new RemoteOutboundRTPStats();
|
|
41
|
+
this.remoteOutboundVideoStats = new RemoteOutboundRTPStats();
|
|
37
42
|
this.sessionStats = new SessionStats();
|
|
38
43
|
this.streamStats = new StreamStats();
|
|
39
44
|
this.codecs = new Map<string, CodecStats>();
|
|
@@ -49,7 +54,7 @@ export class AggregatedStats {
|
|
|
49
54
|
this.candidatePairs = new Array<CandidatePairStats>();
|
|
50
55
|
|
|
51
56
|
rtcStatsReport.forEach((stat) => {
|
|
52
|
-
const type:
|
|
57
|
+
const type: string = stat.type;
|
|
53
58
|
|
|
54
59
|
switch (type) {
|
|
55
60
|
case 'candidate-pair':
|
|
@@ -64,7 +69,7 @@ export class AggregatedStats {
|
|
|
64
69
|
this.handleDataChannel(stat);
|
|
65
70
|
break;
|
|
66
71
|
case 'inbound-rtp':
|
|
67
|
-
this.
|
|
72
|
+
this.handleInboundRTP(stat);
|
|
68
73
|
break;
|
|
69
74
|
case 'local-candidate':
|
|
70
75
|
this.handleLocalCandidate(stat);
|
|
@@ -74,6 +79,7 @@ export class AggregatedStats {
|
|
|
74
79
|
case 'media-playout':
|
|
75
80
|
break;
|
|
76
81
|
case 'outbound-rtp':
|
|
82
|
+
this.handleLocalOutbound(stat);
|
|
77
83
|
break;
|
|
78
84
|
case 'peer-connection':
|
|
79
85
|
break;
|
|
@@ -83,7 +89,7 @@ export class AggregatedStats {
|
|
|
83
89
|
case 'remote-inbound-rtp':
|
|
84
90
|
break;
|
|
85
91
|
case 'remote-outbound-rtp':
|
|
86
|
-
this.
|
|
92
|
+
this.handleRemoteOutbound(stat);
|
|
87
93
|
break;
|
|
88
94
|
case 'track':
|
|
89
95
|
this.handleTrack(stat);
|
|
@@ -125,16 +131,16 @@ export class AggregatedStats {
|
|
|
125
131
|
* @param stat - the stats coming in from the data channel
|
|
126
132
|
*/
|
|
127
133
|
handleDataChannel(stat: DataChannelStats) {
|
|
128
|
-
this.
|
|
129
|
-
this.
|
|
130
|
-
this.
|
|
131
|
-
this.
|
|
132
|
-
this.
|
|
133
|
-
this.
|
|
134
|
-
this.
|
|
135
|
-
this.
|
|
136
|
-
this.
|
|
137
|
-
this.
|
|
134
|
+
this.datachannelStats.bytesReceived = stat.bytesReceived;
|
|
135
|
+
this.datachannelStats.bytesSent = stat.bytesSent;
|
|
136
|
+
this.datachannelStats.dataChannelIdentifier = stat.dataChannelIdentifier;
|
|
137
|
+
this.datachannelStats.id = stat.id;
|
|
138
|
+
this.datachannelStats.label = stat.label;
|
|
139
|
+
this.datachannelStats.messagesReceived = stat.messagesReceived;
|
|
140
|
+
this.datachannelStats.messagesSent = stat.messagesSent;
|
|
141
|
+
this.datachannelStats.protocol = stat.protocol;
|
|
142
|
+
this.datachannelStats.state = stat.state;
|
|
143
|
+
this.datachannelStats.timestamp = stat.timestamp;
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
/**
|
|
@@ -159,23 +165,23 @@ export class AggregatedStats {
|
|
|
159
165
|
* @param stat - ice candidate stats
|
|
160
166
|
*/
|
|
161
167
|
handleRemoteCandidate(stat: CandidateStat) {
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
this.remoteCandidates.push(
|
|
168
|
+
const remoteCandidate = new CandidateStat();
|
|
169
|
+
remoteCandidate.label = 'remote-candidate';
|
|
170
|
+
remoteCandidate.address = stat.address;
|
|
171
|
+
remoteCandidate.port = stat.port;
|
|
172
|
+
remoteCandidate.protocol = stat.protocol;
|
|
173
|
+
remoteCandidate.id = stat.id;
|
|
174
|
+
remoteCandidate.candidateType = stat.candidateType;
|
|
175
|
+
remoteCandidate.relayProtocol = stat.relayProtocol;
|
|
176
|
+
remoteCandidate.transportId = stat.transportId;
|
|
177
|
+
this.remoteCandidates.push(remoteCandidate);
|
|
172
178
|
}
|
|
173
179
|
|
|
174
180
|
/**
|
|
175
181
|
* Process the Inbound RTP Audio and Video Data
|
|
176
182
|
* @param stat - inbound rtp stats
|
|
177
183
|
*/
|
|
178
|
-
|
|
184
|
+
handleInboundRTP(stat: InboundRTPStats) {
|
|
179
185
|
switch (stat.kind) {
|
|
180
186
|
case 'video':
|
|
181
187
|
// Calculate bitrate between stat updates
|
|
@@ -216,25 +222,63 @@ export class AggregatedStats {
|
|
|
216
222
|
}
|
|
217
223
|
|
|
218
224
|
/**
|
|
219
|
-
* Process the outbound RTP Audio and Video
|
|
220
|
-
* @param stat -
|
|
225
|
+
* Process the "local" outbound RTP Audio and Video stats.
|
|
226
|
+
* @param stat - local outbound rtp stats
|
|
221
227
|
*/
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
228
|
+
handleLocalOutbound(stat: OutboundRTPStats) {
|
|
229
|
+
const localOutboundStats: OutboundRTPStats =
|
|
230
|
+
stat.kind === 'audio' ? this.outboundAudioStats : this.outboundVideoStats;
|
|
231
|
+
localOutboundStats.active = stat.active;
|
|
232
|
+
localOutboundStats.codecId = stat.codecId;
|
|
233
|
+
localOutboundStats.bytesSent = stat.bytesSent;
|
|
234
|
+
localOutboundStats.frameHeight = stat.frameHeight;
|
|
235
|
+
localOutboundStats.frameWidth = stat.frameWidth;
|
|
236
|
+
localOutboundStats.framesEncoded = stat.framesEncoded;
|
|
237
|
+
localOutboundStats.framesPerSecond = stat.framesPerSecond;
|
|
238
|
+
localOutboundStats.headerBytesSent = stat.headerBytesSent;
|
|
239
|
+
localOutboundStats.id = stat.id;
|
|
240
|
+
localOutboundStats.keyFramesEncoded = stat.keyFramesEncoded;
|
|
241
|
+
localOutboundStats.kind = stat.kind;
|
|
242
|
+
localOutboundStats.mediaSourceId = stat.mediaSourceId;
|
|
243
|
+
localOutboundStats.mid = stat.mid;
|
|
244
|
+
localOutboundStats.nackCount = stat.nackCount;
|
|
245
|
+
localOutboundStats.packetsSent = stat.packetsSent;
|
|
246
|
+
localOutboundStats.qpSum = stat.qpSum;
|
|
247
|
+
localOutboundStats.qualityLimitationDurations = stat.qualityLimitationDurations;
|
|
248
|
+
localOutboundStats.qualityLimitationReason = stat.qualityLimitationReason;
|
|
249
|
+
localOutboundStats.remoteId = stat.remoteId;
|
|
250
|
+
localOutboundStats.retransmittedBytesSent = stat.retransmittedBytesSent;
|
|
251
|
+
localOutboundStats.rid = stat.rid;
|
|
252
|
+
localOutboundStats.scalabilityMode = stat.scalabilityMode;
|
|
253
|
+
localOutboundStats.ssrc = stat.ssrc;
|
|
254
|
+
localOutboundStats.targetBitrate = stat.targetBitrate;
|
|
255
|
+
localOutboundStats.timestamp = stat.timestamp;
|
|
256
|
+
localOutboundStats.totalEncodeTime = stat.totalEncodeTime;
|
|
257
|
+
localOutboundStats.totalEncodeBytesTarget = stat.totalEncodeBytesTarget;
|
|
258
|
+
localOutboundStats.totalPacketSendDelay = stat.totalPacketSendDelay;
|
|
259
|
+
localOutboundStats.transportId = stat.transportId;
|
|
260
|
+
}
|
|
234
261
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
262
|
+
/**
|
|
263
|
+
* Process the "remote" outbound RTP Audio and Video stats.
|
|
264
|
+
* @param stat - remote outbound rtp stats
|
|
265
|
+
*/
|
|
266
|
+
handleRemoteOutbound(stat: RemoteOutboundRTPStats) {
|
|
267
|
+
const remoteOutboundStats: RemoteOutboundRTPStats =
|
|
268
|
+
stat.kind === 'audio' ? this.remoteOutboundAudioStats : this.remoteOutboundVideoStats;
|
|
269
|
+
remoteOutboundStats.bytesSent = stat.bytesSent;
|
|
270
|
+
remoteOutboundStats.codecId = stat.codecId;
|
|
271
|
+
remoteOutboundStats.id = stat.id;
|
|
272
|
+
remoteOutboundStats.kind = stat.kind;
|
|
273
|
+
remoteOutboundStats.localId = stat.localId;
|
|
274
|
+
remoteOutboundStats.packetsSent = stat.packetsSent;
|
|
275
|
+
remoteOutboundStats.remoteTimestamp = stat.remoteTimestamp;
|
|
276
|
+
remoteOutboundStats.reportsSent = stat.reportsSent;
|
|
277
|
+
remoteOutboundStats.roundTripTimeMeasurements = stat.roundTripTimeMeasurements;
|
|
278
|
+
remoteOutboundStats.ssrc = stat.ssrc;
|
|
279
|
+
remoteOutboundStats.timestamp = stat.timestamp;
|
|
280
|
+
remoteOutboundStats.totalRoundTripTime = stat.totalRoundTripTime;
|
|
281
|
+
remoteOutboundStats.transportId = stat.transportId;
|
|
238
282
|
}
|
|
239
283
|
|
|
240
284
|
/**
|
|
@@ -288,16 +332,31 @@ export class AggregatedStats {
|
|
|
288
332
|
* @returns The candidate pair that is currently receiving data
|
|
289
333
|
*/
|
|
290
334
|
public getActiveCandidatePair(): CandidatePairStats | null {
|
|
335
|
+
if (this.candidatePairs === undefined) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
|
|
291
339
|
// Check if the RTCTransport stat is not undefined
|
|
292
340
|
if (this.transportStats) {
|
|
293
341
|
// Return the candidate pair that matches the transport candidate pair id
|
|
294
|
-
|
|
295
|
-
(candidatePair) => candidatePair.id === this.transportStats.selectedCandidatePairId
|
|
296
|
-
null
|
|
342
|
+
const selectedPair: CandidatePairStats | undefined = this.candidatePairs.find(
|
|
343
|
+
(candidatePair) => candidatePair.id === this.transportStats.selectedCandidatePairId
|
|
297
344
|
);
|
|
345
|
+
if (selectedPair === undefined) {
|
|
346
|
+
return null;
|
|
347
|
+
} else {
|
|
348
|
+
return selectedPair;
|
|
349
|
+
}
|
|
298
350
|
}
|
|
299
351
|
|
|
300
|
-
// Fall back to the selected candidate pair
|
|
301
|
-
|
|
352
|
+
// Fall back to the `.selected` member of the candidate pair
|
|
353
|
+
const selectedPair: CandidatePairStats | undefined = this.candidatePairs.find(
|
|
354
|
+
(candidatePair) => candidatePair.selected
|
|
355
|
+
);
|
|
356
|
+
if (selectedPair === undefined) {
|
|
357
|
+
return null;
|
|
358
|
+
} else {
|
|
359
|
+
return selectedPair;
|
|
360
|
+
}
|
|
302
361
|
}
|
|
303
362
|
}
|