@observertc/observer-js 0.42.8 → 1.0.0-5f150eb.0
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/.prettierrc +6 -6
- package/README.md +493 -63
- package/lib/ObservedCall.d.ts +48 -43
- package/lib/ObservedCall.d.ts.map +1 -1
- package/lib/ObservedCall.js +164 -107
- package/lib/ObservedCallEventMonitor.d.ts +107 -0
- package/lib/ObservedCallEventMonitor.d.ts.map +1 -0
- package/lib/ObservedCallEventMonitor.js +321 -0
- package/lib/ObservedCallSummary.d.ts +18 -0
- package/lib/ObservedCallSummary.d.ts.map +1 -0
- package/lib/ObservedCertificate.d.ts +19 -0
- package/lib/ObservedCertificate.d.ts.map +1 -0
- package/lib/ObservedCertificate.js +38 -0
- package/lib/ObservedClient.d.ts +78 -145
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +661 -746
- package/lib/ObservedClientEventMonitor.d.ts +91 -0
- package/lib/ObservedClientEventMonitor.d.ts.map +1 -0
- package/lib/ObservedClientEventMonitor.js +254 -0
- package/lib/ObservedClientSummary.d.ts +23 -0
- package/lib/ObservedClientSummary.d.ts.map +1 -0
- package/lib/ObservedClientSummary.js +2 -0
- package/lib/ObservedCodec.d.ts +22 -0
- package/lib/ObservedCodec.d.ts.map +1 -0
- package/lib/ObservedCodec.js +45 -0
- package/lib/ObservedDataChannel.d.ts +25 -69
- package/lib/ObservedDataChannel.d.ts.map +1 -1
- package/lib/ObservedDataChannel.js +69 -109
- package/lib/ObservedIceCandidate.d.ts +29 -0
- package/lib/ObservedIceCandidate.d.ts.map +1 -0
- package/lib/ObservedIceCandidate.js +59 -0
- package/lib/ObservedIceCandidatePair.d.ts +45 -0
- package/lib/ObservedIceCandidatePair.d.ts.map +1 -0
- package/lib/ObservedIceCandidatePair.js +127 -0
- package/lib/ObservedIceTransport.d.ts +36 -0
- package/lib/ObservedIceTransport.d.ts.map +1 -0
- package/lib/ObservedIceTransport.js +93 -0
- package/lib/ObservedInboundRtp.d.ts +92 -0
- package/lib/ObservedInboundRtp.d.ts.map +1 -0
- package/lib/ObservedInboundRtp.js +193 -0
- package/lib/ObservedInboundTrack.d.ts +34 -0
- package/lib/ObservedInboundTrack.d.ts.map +1 -0
- package/lib/ObservedInboundTrack.js +92 -0
- package/lib/ObservedMediaPlayout.d.ts +22 -0
- package/lib/ObservedMediaPlayout.d.ts.map +1 -0
- package/lib/ObservedMediaPlayout.js +42 -0
- package/lib/ObservedMediaSource.d.ts +28 -0
- package/lib/ObservedMediaSource.d.ts.map +1 -0
- package/lib/ObservedMediaSource.js +55 -0
- package/lib/ObservedOutboundRtp.d.ts +62 -0
- package/lib/ObservedOutboundRtp.d.ts.map +1 -0
- package/lib/ObservedOutboundRtp.js +144 -0
- package/lib/ObservedOutboundTrack.d.ts +34 -0
- package/lib/ObservedOutboundTrack.d.ts.map +1 -0
- package/lib/ObservedOutboundTrack.js +65 -0
- package/lib/ObservedPeerConnection.d.ts +154 -80
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/ObservedPeerConnection.js +724 -357
- package/lib/ObservedPeerConnectionTransport.d.ts +17 -0
- package/lib/ObservedPeerConnectionTransport.d.ts.map +1 -0
- package/lib/ObservedPeerConnectionTransport.js +34 -0
- package/lib/ObservedRemoteInboundRtp.d.ts +30 -0
- package/lib/ObservedRemoteInboundRtp.d.ts.map +1 -0
- package/lib/ObservedRemoteInboundRtp.js +60 -0
- package/lib/ObservedRemoteOutboundRtp.d.ts +30 -0
- package/lib/ObservedRemoteOutboundRtp.d.ts.map +1 -0
- package/lib/ObservedRemoteOutboundRtp.js +60 -0
- package/lib/ObservedTURN.d.ts +31 -0
- package/lib/ObservedTURN.d.ts.map +1 -0
- package/lib/ObservedTURN.js +58 -0
- package/lib/ObservedTurnServer.d.ts +25 -0
- package/lib/ObservedTurnServer.d.ts.map +1 -0
- package/lib/ObservedTurnServer.js +59 -0
- package/lib/Observer.d.ts +46 -54
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +131 -226
- package/lib/ObserverEventMonitor.d.ts +141 -0
- package/lib/ObserverEventMonitor.d.ts.map +1 -0
- package/lib/ObserverEventMonitor.js +440 -0
- package/lib/ObserverSummary.d.ts +13 -0
- package/lib/ObserverSummary.d.ts.map +1 -0
- package/lib/ObserverSummary.js +2 -0
- package/lib/Reports.d.ts +85 -0
- package/lib/Reports.d.ts.map +1 -0
- package/lib/Reports.js +2 -0
- package/lib/common/Middleware.d.ts +10 -1
- package/lib/common/Middleware.d.ts.map +1 -1
- package/lib/common/Middleware.js +55 -36
- package/lib/common/logger.d.ts +8 -4
- package/lib/common/logger.d.ts.map +1 -1
- package/lib/common/logger.js +44 -68
- package/lib/common/types.d.ts +0 -21
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/types.js +1 -0
- package/lib/common/utils.d.ts +3 -1
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +23 -3
- package/lib/detectors/Detector.d.ts +5 -0
- package/lib/detectors/Detector.d.ts.map +1 -0
- package/lib/detectors/Detector.js +3 -0
- package/lib/detectors/Detectors.d.ts +11 -0
- package/lib/detectors/Detectors.d.ts.map +1 -0
- package/lib/detectors/Detectors.js +34 -0
- package/lib/index.d.ts +27 -24
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +45 -41
- package/lib/mediasoup/ObservedMediaRouter.d.ts +10 -0
- package/lib/mediasoup/ObservedMediaRouter.d.ts.map +1 -0
- package/lib/mediasoup/ObservedMediaRouter.js +6 -0
- package/lib/monitors/TurnUsageMonitor.d.ts +0 -52
- package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -1
- package/lib/monitors/TurnUsageMonitor.js +145 -120
- package/lib/schema/ClientEventTypes.d.ts +228 -0
- package/lib/schema/ClientEventTypes.d.ts.map +1 -0
- package/lib/schema/ClientEventTypes.js +41 -0
- package/lib/schema/ClientMetaTypes.d.ts +34 -0
- package/lib/schema/ClientMetaTypes.d.ts.map +1 -0
- package/lib/schema/ClientMetaTypes.js +16 -0
- package/lib/schema/ClientSample.d.ts +1333 -0
- package/lib/schema/ClientSample.d.ts.map +1 -0
- package/lib/schema/ClientSample.js +4 -0
- package/lib/scores/CalculatedScore.d.ts +6 -0
- package/lib/scores/CalculatedScore.d.ts.map +1 -0
- package/lib/scores/CalculatedScore.js +2 -0
- package/lib/scores/DefaultCallScoreCalculator.d.ts +7 -0
- package/lib/scores/DefaultCallScoreCalculator.d.ts.map +1 -0
- package/lib/scores/DefaultCallScoreCalculator.js +21 -0
- package/lib/scores/ScoreCalculator.d.ts +4 -0
- package/lib/scores/ScoreCalculator.d.ts.map +1 -0
- package/lib/scores/ScoreCalculator.js +2 -0
- package/lib/updaters/CallUpdater.d.ts +5 -0
- package/lib/updaters/CallUpdater.d.ts.map +1 -0
- package/lib/updaters/CallUpdater.js +2 -0
- package/lib/updaters/ObserverUpdater.d.ts +5 -0
- package/lib/updaters/ObserverUpdater.d.ts.map +1 -0
- package/lib/updaters/ObserverUpdater.js +2 -0
- package/lib/updaters/OnAllCallObserverUpdater.d.ts +15 -0
- package/lib/updaters/OnAllCallObserverUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAllCallObserverUpdater.js +50 -0
- package/lib/updaters/OnAllClientCallUpdater.d.ts +15 -0
- package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAllClientCallUpdater.js +53 -0
- package/lib/updaters/OnAnyCallObserverUpdater.d.ts +12 -0
- package/lib/updaters/OnAnyCallObserverUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAnyCallObserverUpdater.js +37 -0
- package/lib/updaters/OnAnyClientCallUpdater.d.ts +12 -0
- package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAnyClientCallUpdater.js +36 -0
- package/lib/updaters/OnIntervalUpdater.d.ts +10 -0
- package/lib/updaters/OnIntervalUpdater.d.ts.map +1 -0
- package/lib/updaters/OnIntervalUpdater.js +17 -0
- package/lib/updaters/Updater.d.ts +6 -0
- package/lib/updaters/Updater.d.ts.map +1 -0
- package/lib/updaters/Updater.js +2 -0
- package/lib/utils/MediasoupRemoteTrackResolver.d.ts +25 -0
- package/lib/utils/MediasoupRemoteTrackResolver.d.ts.map +1 -0
- package/lib/utils/MediasoupRemoteTrackResolver.js +110 -0
- package/lib/utils/RemoteTrackResolver.d.ts +7 -0
- package/lib/utils/RemoteTrackResolver.d.ts.map +1 -0
- package/lib/utils/RemoteTrackResolver.js +2 -0
- package/package.json +4 -4
- package/src/ObservedCall.ts +243 -161
- package/src/ObservedCallEventMonitor.ts +402 -0
- package/src/ObservedCallSummary.ts +22 -0
- package/src/ObservedCertificate.ts +43 -0
- package/src/ObservedClient.ts +716 -1002
- package/src/ObservedClientEventMonitor.ts +309 -0
- package/src/ObservedClientSummary.ts +24 -0
- package/src/ObservedCodec.ts +49 -0
- package/src/ObservedDataChannel.ts +71 -181
- package/src/ObservedIceCandidate.ts +64 -0
- package/src/ObservedIceCandidatePair.ts +134 -0
- package/src/ObservedIceTransport.ts +99 -0
- package/src/ObservedInboundRtp.ts +205 -0
- package/src/ObservedInboundTrack.ts +105 -0
- package/src/ObservedMediaPlayout.ts +49 -0
- package/src/ObservedMediaSource.ts +60 -0
- package/src/ObservedOutboundRtp.ts +156 -0
- package/src/ObservedOutboundTrack.ts +82 -0
- package/src/ObservedPeerConnection.ts +933 -402
- package/src/ObservedPeerConnectionTransport.ts +38 -0
- package/src/ObservedRemoteInboundRtp.ts +64 -0
- package/src/ObservedRemoteOutboundRtp.ts +65 -0
- package/src/ObservedTURN.ts +86 -0
- package/src/ObservedTurnServer.ts +72 -0
- package/src/Observer.ts +183 -298
- package/src/ObserverEventMonitor.ts +561 -0
- package/src/ObserverSummary.ts +15 -0
- package/src/Reports.ts +87 -0
- package/src/common/Middleware.ts +70 -42
- package/src/common/logger.ts +60 -69
- package/src/common/types.ts +0 -42
- package/src/common/utils.ts +24 -2
- package/src/detectors/Detector.ts +6 -0
- package/src/detectors/Detectors.ts +38 -0
- package/src/index.ts +30 -88
- package/src/mediasoup/ObservedMediaRouter.ts +10 -0
- package/src/monitors/TurnUsageMonitor.ts +164 -164
- package/src/schema/ClientEventTypes.ts +280 -0
- package/src/schema/ClientMetaTypes.ts +41 -0
- package/src/schema/ClientSample.ts +1682 -0
- package/src/scores/CalculatedScore.ts +6 -0
- package/src/scores/DefaultCallScoreCalculator.ts +23 -0
- package/src/scores/ScoreCalculator.ts +3 -0
- package/src/updaters/CallUpdater.ts +5 -0
- package/src/updaters/ObserverUpdater.ts +5 -0
- package/src/updaters/OnAllCallObserverUpdater.ts +59 -0
- package/src/updaters/OnAllClientCallUpdater.ts +61 -0
- package/src/updaters/OnAnyCallObserverUpdater.ts +41 -0
- package/src/updaters/OnAnyClientCallUpdater.ts +39 -0
- package/src/updaters/OnIntervalUpdater.ts +19 -0
- package/src/updaters/Updater.ts +5 -0
- package/src/utils/MediasoupRemoteTrackResolver.ts +155 -0
- package/src/utils/RemoteTrackResolver.ts +12 -0
- package/tsconfig.json +3 -3
- package/lib/ObservedICE.d.ts +0 -64
- package/lib/ObservedICE.d.ts.map +0 -1
- package/lib/ObservedICE.js +0 -141
- package/lib/ObservedInboundAudioTrack.d.ts +0 -96
- package/lib/ObservedInboundAudioTrack.d.ts.map +0 -1
- package/lib/ObservedInboundAudioTrack.js +0 -217
- package/lib/ObservedInboundVideoTrack.d.ts +0 -101
- package/lib/ObservedInboundVideoTrack.d.ts.map +0 -1
- package/lib/ObservedInboundVideoTrack.js +0 -232
- package/lib/ObservedOutboundAudioTrack.d.ts +0 -87
- package/lib/ObservedOutboundAudioTrack.d.ts.map +0 -1
- package/lib/ObservedOutboundAudioTrack.js +0 -186
- package/lib/ObservedOutboundVideoTrack.d.ts +0 -91
- package/lib/ObservedOutboundVideoTrack.d.ts.map +0 -1
- package/lib/ObservedOutboundVideoTrack.js +0 -193
- package/lib/ObservedSfu.d.ts +0 -59
- package/lib/ObservedSfu.d.ts.map +0 -1
- package/lib/ObservedSfu.js +0 -157
- package/lib/ObservedSfuInboundRtpPad.d.ts +0 -42
- package/lib/ObservedSfuInboundRtpPad.d.ts.map +0 -1
- package/lib/ObservedSfuInboundRtpPad.js +0 -71
- package/lib/ObservedSfuOutboundRtpPad.d.ts +0 -42
- package/lib/ObservedSfuOutboundRtpPad.d.ts.map +0 -1
- package/lib/ObservedSfuOutboundRtpPad.js +0 -72
- package/lib/ObservedSfuSctpChannel.d.ts +0 -42
- package/lib/ObservedSfuSctpChannel.d.ts.map +0 -1
- package/lib/ObservedSfuSctpChannel.js +0 -57
- package/lib/ObservedSfuTransport.d.ts +0 -58
- package/lib/ObservedSfuTransport.d.ts.map +0 -1
- package/lib/ObservedSfuTransport.js +0 -120
- package/lib/RemoteTrackAssigner.d.ts +0 -14
- package/lib/RemoteTrackAssigner.d.ts.map +0 -1
- package/lib/RemoteTrackAssigner.js +0 -52
- package/lib/ReportsCollector.d.ts +0 -109
- package/lib/ReportsCollector.d.ts.map +0 -1
- package/lib/ReportsCollector.js +0 -207
- package/lib/common/CalculatedScore.d.ts +0 -80
- package/lib/common/CalculatedScore.d.ts.map +0 -1
- package/lib/common/CalculatedScore.js +0 -162
- package/lib/common/CallEventType.d.ts +0 -63
- package/lib/common/CallEventType.d.ts.map +0 -1
- package/lib/common/CallEventType.js +0 -39
- package/lib/common/CallMetaReports.d.ts +0 -42
- package/lib/common/CallMetaReports.d.ts.map +0 -1
- package/lib/common/CallMetaReports.js +0 -36
- package/lib/common/QualityScoreUtils.d.ts +0 -1
- package/lib/common/QualityScoreUtils.d.ts.map +0 -1
- package/lib/common/QualityScoreUtils.js +0 -1
- package/lib/common/TypedEventEmitter.d.ts +0 -22
- package/lib/common/TypedEventEmitter.d.ts.map +0 -1
- package/lib/common/TypedEventEmitter.js +0 -11
- package/lib/common/callEventReports.d.ts +0 -10
- package/lib/common/callEventReports.d.ts.map +0 -1
- package/lib/common/callEventReports.js +0 -112
- package/lib/monitors/CallSummary.d.ts +0 -37
- package/lib/monitors/CallSummary.d.ts.map +0 -1
- package/lib/monitors/CallSummaryMonitor.d.ts +0 -32
- package/lib/monitors/CallSummaryMonitor.d.ts.map +0 -1
- package/lib/monitors/CallSummaryMonitor.js +0 -152
- package/lib/monitors/ClientIssueMonitor.d.ts +0 -32
- package/lib/monitors/ClientIssueMonitor.d.ts.map +0 -1
- package/lib/monitors/ClientIssueMonitor.js +0 -49
- package/lib/monitors/SfuServerMonitor.d.ts +0 -79
- package/lib/monitors/SfuServerMonitor.d.ts.map +0 -1
- package/lib/monitors/SfuServerMonitor.js +0 -198
- package/src/ObservedICE.ts +0 -237
- package/src/ObservedInboundAudioTrack.ts +0 -344
- package/src/ObservedInboundVideoTrack.ts +0 -361
- package/src/ObservedOutboundAudioTrack.ts +0 -307
- package/src/ObservedOutboundVideoTrack.ts +0 -319
- package/src/ObservedSfu.ts +0 -231
- package/src/ObservedSfuInboundRtpPad.ts +0 -106
- package/src/ObservedSfuOutboundRtpPad.ts +0 -107
- package/src/ObservedSfuSctpChannel.ts +0 -103
- package/src/ObservedSfuTransport.ts +0 -185
- package/src/RemoteTrackAssigner.ts +0 -68
- package/src/ReportsCollector.ts +0 -336
- package/src/common/CalculatedScore.ts +0 -188
- package/src/common/CallEventType.ts +0 -69
- package/src/common/CallMetaReports.ts +0 -82
- package/src/common/QualityScoreUtils.ts +0 -0
- package/src/common/TypedEventEmitter.ts +0 -32
- package/src/common/callEventReports.ts +0 -178
- package/src/monitors/CallSummary.ts +0 -38
- package/src/monitors/CallSummaryMonitor.ts +0 -192
- package/src/monitors/ClientIssueMonitor.ts +0 -88
- package/src/monitors/SfuServerMonitor.ts +0 -285
- /package/lib/{monitors/CallSummary.js → ObservedCallSummary.js} +0 -0
|
@@ -1,65 +1,146 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import { PeerConnectionTransport } from '@observertc/sample-schemas-js';
|
|
3
2
|
import { ObservedClient } from './ObservedClient';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { CertificateStats, CodecStats, DataChannelStats, IceCandidateStats, InboundRtpStats, InboundTrackSample, MediaPlayoutStats, MediaSourceStats, OutboundRtpStats, OutboundTrackSample, PeerConnectionSample, PeerConnectionTransportStats, RemoteInboundRtpStats, RemoteOutboundRtpStats } from './schema/ClientSample';
|
|
4
|
+
import { ObservedInboundRtp } from './ObservedInboundRtp';
|
|
5
|
+
import { createLogger } from './common/logger';
|
|
6
|
+
import { MediaKind } from './common/types';
|
|
7
|
+
import { ObservedOutboundRtp } from './ObservedOutboundRtp';
|
|
8
|
+
import { ObservedCertificate } from './ObservedCertificate';
|
|
9
|
+
import { ObservedCodec } from './ObservedCodec';
|
|
6
10
|
import { ObservedDataChannel } from './ObservedDataChannel';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
11
|
+
import { ObservedIceCandidate } from './ObservedIceCandidate';
|
|
12
|
+
import { ObservedIceCandidatePair } from './ObservedIceCandidatePair';
|
|
13
|
+
import { ObservedIceTransport } from './ObservedIceTransport';
|
|
14
|
+
import { ObservedMediaSource } from './ObservedMediaSource';
|
|
15
|
+
import { ObservedPeerConnectionTransport } from './ObservedPeerConnectionTransport';
|
|
16
|
+
import { ObservedMediaPlayout } from './ObservedMediaPlayout';
|
|
17
|
+
import { ObservedRemoteInboundRtp } from './ObservedRemoteInboundRtp';
|
|
18
|
+
import { ObservedRemoteOutboundRtp } from './ObservedRemoteOutboundRtp';
|
|
19
|
+
import { ObservedInboundTrack } from './ObservedInboundTrack';
|
|
20
|
+
import { ObservedOutboundTrack } from './ObservedOutboundTrack';
|
|
21
|
+
import { CalculatedScore } from './scores/CalculatedScore';
|
|
22
|
+
import { ObservedTurnServer } from './ObservedTurnServer';
|
|
23
|
+
import { getMedian } from './common/utils';
|
|
24
|
+
|
|
25
|
+
const logger = createLogger('ObservedPeerConnection');
|
|
14
26
|
|
|
15
27
|
export type ObservedPeerConnectionEvents = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
iceconnectionstatechange: [
|
|
29
|
+
{
|
|
30
|
+
state: string;
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
icegatheringstatechange: [
|
|
34
|
+
{
|
|
35
|
+
state: string;
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
connectionstatechange: [
|
|
39
|
+
{
|
|
40
|
+
state: string;
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
selectedcandidatepair: [];
|
|
44
|
+
|
|
45
|
+
'added-certificate': [ObservedCertificate];
|
|
46
|
+
'added-codec': [ObservedCodec];
|
|
47
|
+
'added-data-channel': [ObservedDataChannel];
|
|
48
|
+
'added-ice-candidate': [ObservedIceCandidate];
|
|
49
|
+
'added-ice-candidate-pair': [ObservedIceCandidatePair];
|
|
50
|
+
'added-ice-transport': [ObservedIceTransport];
|
|
51
|
+
'added-inbound-rtp': [ObservedInboundRtp];
|
|
52
|
+
'added-inbound-track': [ObservedInboundTrack];
|
|
53
|
+
'added-media-playout': [ObservedMediaPlayout];
|
|
54
|
+
'added-media-source': [ObservedMediaSource];
|
|
55
|
+
'added-outbound-rtp': [ObservedOutboundRtp];
|
|
56
|
+
'added-outbound-track': [ObservedOutboundTrack];
|
|
57
|
+
'added-peer-connection-transport': [ObservedPeerConnectionTransport];
|
|
58
|
+
'added-remote-inbound-rtp': [ObservedRemoteInboundRtp];
|
|
59
|
+
'added-remote-outbound-rtp': [ObservedRemoteOutboundRtp];
|
|
60
|
+
'removed-certificate': [ObservedCertificate];
|
|
61
|
+
'removed-codec': [ObservedCodec];
|
|
62
|
+
'removed-data-channel': [ObservedDataChannel];
|
|
63
|
+
'removed-ice-candidate': [ObservedIceCandidate];
|
|
64
|
+
'removed-ice-candidate-pair': [ObservedIceCandidatePair];
|
|
65
|
+
'removed-ice-transport': [ObservedIceTransport];
|
|
66
|
+
'removed-inbound-rtp': [ObservedInboundRtp];
|
|
67
|
+
'removed-inbound-track': [ObservedInboundTrack];
|
|
68
|
+
'removed-media-playout': [ObservedMediaPlayout];
|
|
69
|
+
'removed-media-source': [ObservedMediaSource];
|
|
70
|
+
'removed-outbound-rtp': [ObservedOutboundRtp];
|
|
71
|
+
'removed-outbound-track': [ObservedOutboundTrack];
|
|
72
|
+
'removed-peer-connection-transport': [ObservedPeerConnectionTransport];
|
|
73
|
+
'removed-remote-inbound-rtp': [ObservedRemoteInboundRtp];
|
|
74
|
+
'removed-remote-outbound-rtp': [ObservedRemoteOutboundRtp];
|
|
75
|
+
'updated-inbound-rtp': [ObservedInboundRtp];
|
|
76
|
+
'updated-outbound-rtp': [ObservedOutboundRtp];
|
|
77
|
+
'updated-inbound-track': [ObservedInboundTrack];
|
|
78
|
+
'updated-outbound-track': [ObservedOutboundTrack];
|
|
79
|
+
'updated-ice-candidate-pair': [ObservedIceCandidatePair];
|
|
80
|
+
'updated-ice-transport': [ObservedIceTransport];
|
|
81
|
+
'updated-peer-connection-transport': [ObservedPeerConnectionTransport];
|
|
82
|
+
'updated-media-source': [ObservedMediaSource];
|
|
83
|
+
'updated-media-playout': [ObservedMediaPlayout];
|
|
84
|
+
'updated-data-channel': [ObservedDataChannel];
|
|
85
|
+
'updated-ice-candidate': [ObservedIceCandidate];
|
|
86
|
+
'updated-certificate': [ObservedCertificate];
|
|
87
|
+
'updated-codec': [ObservedCodec];
|
|
88
|
+
'updated-remote-inbound-rtp': [ObservedRemoteInboundRtp];
|
|
89
|
+
'updated-remote-outbound-rtp': [ObservedRemoteOutboundRtp];
|
|
90
|
+
'muted-inbound-track': [ObservedInboundTrack];
|
|
91
|
+
'muted-outbound-track': [ObservedOutboundTrack];
|
|
92
|
+
'unmuted-inbound-track': [ObservedInboundTrack];
|
|
93
|
+
'unmuted-outbound-track': [ObservedOutboundTrack];
|
|
94
|
+
|
|
95
|
+
'update': [],
|
|
96
|
+
close: [];
|
|
31
97
|
};
|
|
32
98
|
|
|
33
|
-
export type ObservedPeerConnectionStats = Omit<PeerConnectionTransport, 'transportId' | 'label'>;
|
|
34
|
-
|
|
35
99
|
export declare interface ObservedPeerConnection {
|
|
36
|
-
on<U extends keyof ObservedPeerConnectionEvents>(
|
|
37
|
-
|
|
38
|
-
|
|
100
|
+
on<U extends keyof ObservedPeerConnectionEvents>(
|
|
101
|
+
event: U,
|
|
102
|
+
listener: (...args: ObservedPeerConnectionEvents[U]) => void
|
|
103
|
+
): this;
|
|
104
|
+
off<U extends keyof ObservedPeerConnectionEvents>(
|
|
105
|
+
event: U,
|
|
106
|
+
listener: (...args: ObservedPeerConnectionEvents[U]) => void
|
|
107
|
+
): this;
|
|
108
|
+
once<U extends keyof ObservedPeerConnectionEvents>(
|
|
109
|
+
event: U,
|
|
110
|
+
listener: (...args: ObservedPeerConnectionEvents[U]) => void
|
|
111
|
+
): this;
|
|
39
112
|
emit<U extends keyof ObservedPeerConnectionEvents>(event: U, ...args: ObservedPeerConnectionEvents[U]): boolean;
|
|
40
113
|
}
|
|
41
114
|
|
|
42
115
|
export class ObservedPeerConnection extends EventEmitter {
|
|
43
|
-
|
|
44
|
-
public visited = true;
|
|
116
|
+
private _visited = true;
|
|
45
117
|
|
|
118
|
+
public appData?: Record<string, unknown>;
|
|
119
|
+
public readonly calculatedScore: CalculatedScore = {
|
|
120
|
+
weight: 1,
|
|
121
|
+
value: undefined,
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
public closed = false;
|
|
46
125
|
// timestamp of the PEER_CONNECTION_OPENED event
|
|
47
|
-
public
|
|
126
|
+
public openedAt?: number;
|
|
48
127
|
// timestamp of the PEER_CONNECTION_CLOSED event
|
|
49
|
-
public
|
|
50
|
-
|
|
51
|
-
private _elapsedTimeSinceLastUpdate?: number;
|
|
52
|
-
private _statsTimestamp?: number;
|
|
53
|
-
private _stabilityScores: number[] = [];
|
|
128
|
+
public closedAt?: number;
|
|
129
|
+
public updated = Date.now();
|
|
54
130
|
|
|
55
|
-
public
|
|
131
|
+
public connectionState?: 'new' | 'connecting' | 'connected' | 'disconnected' | 'failed' | 'closed';
|
|
132
|
+
public iceConnectionState?: 'new' | 'checking' | 'connected' | 'completed' | 'failed' | 'disconnected' | 'closed';
|
|
133
|
+
public iceGatheringState?: 'new' | 'gathering' | 'complete';
|
|
56
134
|
|
|
57
|
-
public
|
|
135
|
+
public availableIncomingBitrate = 0;
|
|
136
|
+
public availableOutgoingBitrate = 0;
|
|
58
137
|
public totalInboundPacketsLost = 0;
|
|
59
138
|
public totalInboundPacketsReceived = 0;
|
|
60
139
|
public totalOutboundPacketsSent = 0;
|
|
61
140
|
public totalDataChannelBytesSent = 0;
|
|
62
141
|
public totalDataChannelBytesReceived = 0;
|
|
142
|
+
public totalDataChannelMessagesSent = 0;
|
|
143
|
+
public totalDataChannelMessagesReceived = 0;
|
|
63
144
|
|
|
64
145
|
public totalSentAudioBytes = 0;
|
|
65
146
|
public totalSentVideoBytes = 0;
|
|
@@ -75,182 +156,181 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
75
156
|
public deltaOutboundPacketsSent = 0;
|
|
76
157
|
public deltaDataChannelBytesSent = 0;
|
|
77
158
|
public deltaDataChannelBytesReceived = 0;
|
|
159
|
+
public deltaDataChannelMessagesSent = 0;
|
|
160
|
+
public deltaDataChannelMessagesReceived = 0;
|
|
78
161
|
public deltaInboundReceivedBytes = 0;
|
|
79
162
|
public deltaOutboundSentBytes = 0;
|
|
80
|
-
|
|
163
|
+
|
|
81
164
|
public deltaReceivedAudioBytes = 0;
|
|
82
165
|
public deltaReceivedVideoBytes = 0;
|
|
83
166
|
public deltaReceivedAudioPackets = 0;
|
|
84
167
|
public deltaReceivedVideoPackets = 0;
|
|
85
168
|
public deltaSentAudioBytes = 0;
|
|
86
169
|
public deltaSentVideoBytes = 0;
|
|
170
|
+
public deltaTransportSentBytes = 0;
|
|
171
|
+
public deltaTransportReceivedBytes = 0;
|
|
172
|
+
|
|
87
173
|
public receivingPacketsPerSecond = 0;
|
|
88
174
|
public sendingPacketsPerSecond = 0;
|
|
89
175
|
public sendingAudioBitrate = 0;
|
|
90
176
|
public sendingVideoBitrate = 0;
|
|
91
177
|
public receivingAudioBitrate = 0;
|
|
92
178
|
public receivingVideoBitrate = 0;
|
|
93
|
-
|
|
94
|
-
public
|
|
95
|
-
public
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
public readonly
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
public
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
179
|
+
|
|
180
|
+
public currentRttInMs?: number;
|
|
181
|
+
public currentJitter?: number;
|
|
182
|
+
|
|
183
|
+
public usingTCP = false;
|
|
184
|
+
public usingTURN = false;
|
|
185
|
+
|
|
186
|
+
public observedTurnServer?: ObservedTurnServer;
|
|
187
|
+
public readonly observedCertificates = new Map<string, ObservedCertificate>();
|
|
188
|
+
public readonly observedCodecs = new Map<string, ObservedCodec>();
|
|
189
|
+
public readonly observedDataChannels = new Map<string, ObservedDataChannel>();
|
|
190
|
+
public readonly observedIceCandidates = new Map<string, ObservedIceCandidate>();
|
|
191
|
+
public readonly observedIceCandidatesPair = new Map<string, ObservedIceCandidatePair>();
|
|
192
|
+
public readonly observedIceTransports = new Map<string, ObservedIceTransport>();
|
|
193
|
+
public readonly observedInboundRtps = new Map<number, ObservedInboundRtp>();
|
|
194
|
+
public readonly observedInboundTracks = new Map<string, ObservedInboundTrack>();
|
|
195
|
+
public readonly observedMediaPlayouts = new Map<string, ObservedMediaPlayout>();
|
|
196
|
+
public readonly observedMediaSources = new Map<string, ObservedMediaSource>();
|
|
197
|
+
public readonly observedOutboundRtps = new Map<number, ObservedOutboundRtp>();
|
|
198
|
+
public readonly observedOutboundTracks = new Map<string, ObservedOutboundTrack>();
|
|
199
|
+
public readonly observedPeerConnectionTransports = new Map<string, ObservedPeerConnectionTransport>();
|
|
200
|
+
public readonly observedRemoteInboundRtps = new Map<number, ObservedRemoteInboundRtp>();
|
|
201
|
+
public readonly observedRemoteOutboundRtps = new Map<number, ObservedRemoteOutboundRtp>();
|
|
202
|
+
|
|
203
|
+
public constructor(public readonly peerConnectionId: string, public readonly client: ObservedClient) {
|
|
113
204
|
super();
|
|
114
205
|
this.setMaxListeners(Infinity);
|
|
115
206
|
}
|
|
116
207
|
|
|
117
|
-
public get
|
|
118
|
-
return this.
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
public get roomId() {
|
|
122
|
-
return this.client.roomId;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
public get callId() {
|
|
126
|
-
return this.client.callId;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
public get clientId() {
|
|
130
|
-
return this.client.clientId;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
public get mediaUnitId() {
|
|
134
|
-
return this.client.mediaUnitId;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
public get label() {
|
|
138
|
-
return this._model.label;
|
|
208
|
+
public get score() {
|
|
209
|
+
return this.calculatedScore.value;
|
|
139
210
|
}
|
|
140
211
|
|
|
141
|
-
public
|
|
142
|
-
|
|
143
|
-
}
|
|
212
|
+
public get visited() {
|
|
213
|
+
const visited = this._visited;
|
|
144
214
|
|
|
145
|
-
|
|
146
|
-
return this.ICE.usingTURN;
|
|
147
|
-
}
|
|
215
|
+
this._visited = false;
|
|
148
216
|
|
|
149
|
-
|
|
150
|
-
return this.ICE.stats?.availableOutgoingBitrate;
|
|
217
|
+
return visited;
|
|
151
218
|
}
|
|
152
219
|
|
|
153
|
-
public get
|
|
154
|
-
return this.
|
|
220
|
+
public get codecs() {
|
|
221
|
+
return [ ...this.observedCodecs.values() ];
|
|
155
222
|
}
|
|
156
223
|
|
|
157
|
-
public get
|
|
158
|
-
|
|
159
|
-
return this._model.peerConnectionId!;
|
|
224
|
+
public get inboundRtps() {
|
|
225
|
+
return [ ...this.observedInboundRtps.values() ];
|
|
160
226
|
}
|
|
161
227
|
|
|
162
|
-
public get
|
|
163
|
-
return this.
|
|
228
|
+
public get remoteOutboundRtps() {
|
|
229
|
+
return [ ...this.observedRemoteOutboundRtps.values() ];
|
|
164
230
|
}
|
|
165
231
|
|
|
166
|
-
public get
|
|
167
|
-
return this.
|
|
232
|
+
public get outboundRtps() {
|
|
233
|
+
return [ ...this.observedOutboundRtps.values() ];
|
|
168
234
|
}
|
|
169
235
|
|
|
170
|
-
public get
|
|
171
|
-
return this.
|
|
236
|
+
public get remoteInboundRtps() {
|
|
237
|
+
return [ ...this.observedRemoteInboundRtps.values() ];
|
|
172
238
|
}
|
|
173
239
|
|
|
174
|
-
public get
|
|
175
|
-
return this.
|
|
240
|
+
public get mediaSources() {
|
|
241
|
+
return [ ...this.observedMediaSources.values() ];
|
|
176
242
|
}
|
|
177
243
|
|
|
178
|
-
public get
|
|
179
|
-
return this.
|
|
244
|
+
public get mediaPlayouts() {
|
|
245
|
+
return [ ...this.observedMediaPlayouts.values() ];
|
|
180
246
|
}
|
|
181
247
|
|
|
182
|
-
public get
|
|
183
|
-
return this.
|
|
248
|
+
public get dataChannels() {
|
|
249
|
+
return [ ...this.observedDataChannels.values() ];
|
|
184
250
|
}
|
|
185
251
|
|
|
186
|
-
public get
|
|
187
|
-
return this.
|
|
252
|
+
public get peerConnectionTransports() {
|
|
253
|
+
return [ ...this.observedPeerConnectionTransports.values() ];
|
|
188
254
|
}
|
|
189
255
|
|
|
190
|
-
public get
|
|
191
|
-
return this.
|
|
256
|
+
public get iceTransports() {
|
|
257
|
+
return [ ...this.observedIceTransports.values() ];
|
|
192
258
|
}
|
|
193
259
|
|
|
194
|
-
public get
|
|
195
|
-
return this.
|
|
260
|
+
public get iceCandidates() {
|
|
261
|
+
return [ ...this.observedIceCandidates.values() ];
|
|
196
262
|
}
|
|
197
263
|
|
|
198
|
-
public get
|
|
199
|
-
return this.
|
|
264
|
+
public get iceCandidatePairs() {
|
|
265
|
+
return [ ...this.observedIceCandidatesPair.values() ];
|
|
200
266
|
}
|
|
201
267
|
|
|
202
|
-
public
|
|
203
|
-
this.
|
|
204
|
-
this._inboundAudioTracks.forEach((track) => (track.marker = value));
|
|
205
|
-
this._inboundVideoTracks.forEach((track) => (track.marker = value));
|
|
206
|
-
this._outboundAudioTracks.forEach((track) => (track.marker = value));
|
|
207
|
-
this._outboundVideoTracks.forEach((track) => (track.marker = value));
|
|
208
|
-
this._dataChannels.forEach((channel) => (channel.marker = value));
|
|
209
|
-
this.ICE.marker = value;
|
|
268
|
+
public get certificates() {
|
|
269
|
+
return [ ...this.observedCertificates.values() ];
|
|
210
270
|
}
|
|
211
271
|
|
|
212
|
-
public
|
|
213
|
-
this.
|
|
214
|
-
|
|
215
|
-
serviceId: this.serviceId,
|
|
216
|
-
mediaUnitId: this.mediaUnitId,
|
|
217
|
-
roomId: this.roomId,
|
|
218
|
-
callId: this.callId,
|
|
219
|
-
clientId: this.clientId,
|
|
220
|
-
userId: this.client.userId,
|
|
221
|
-
peerConnectionId: this.peerConnectionId,
|
|
222
|
-
marker: this.client.marker,
|
|
223
|
-
timestamp: params.timestamp ?? Date.now(),
|
|
224
|
-
});
|
|
272
|
+
public get selectedIceCandidatePairs() {
|
|
273
|
+
return this.iceTransports.map((iceTransport) => iceTransport.getSelectedCandidatePair())
|
|
274
|
+
.filter((pair) => pair !== undefined) as ObservedIceCandidatePair[];
|
|
225
275
|
}
|
|
226
276
|
|
|
227
|
-
public get
|
|
228
|
-
return this.
|
|
277
|
+
public get selectedIceCandiadtePairForTurn() {
|
|
278
|
+
return this.selectedIceCandidatePairs
|
|
279
|
+
.filter((pair) =>
|
|
280
|
+
pair.getLocalCandidate()?.candidateType === 'relay' &&
|
|
281
|
+
pair.getRemoteCandidate()?.url?.startsWith('turn:')
|
|
282
|
+
);
|
|
229
283
|
}
|
|
230
284
|
|
|
231
285
|
public close() {
|
|
232
|
-
if (this.
|
|
233
|
-
this.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
286
|
+
if (this.closed) return;
|
|
287
|
+
this.closed = true;
|
|
288
|
+
|
|
289
|
+
this.observedCertificates.forEach((cert) => this.emit('removed-certificate', cert));
|
|
290
|
+
this.observedCodecs.forEach((codec) => this.emit('removed-codec', codec));
|
|
291
|
+
this.observedDataChannels.forEach((dc) => this.emit('removed-data-channel', dc));
|
|
292
|
+
this.observedIceCandidates.forEach((candidate) => this.emit('removed-ice-candidate', candidate));
|
|
293
|
+
this.observedIceCandidatesPair.forEach((pair) => this.emit('removed-ice-candidate-pair', pair));
|
|
294
|
+
this.observedIceTransports.forEach((transport) => this.emit('removed-ice-transport', transport));
|
|
295
|
+
this.observedInboundRtps.forEach((rtp) => this.emit('removed-inbound-rtp', rtp));
|
|
296
|
+
this.observedInboundTracks.forEach((track) => this.emit('removed-inbound-track', track));
|
|
297
|
+
this.observedMediaPlayouts.forEach((playout) => this.emit('removed-media-playout', playout));
|
|
298
|
+
this.observedMediaSources.forEach((source) => this.emit('removed-media-source', source));
|
|
299
|
+
this.observedOutboundRtps.forEach((rtp) => this.emit('removed-outbound-rtp', rtp));
|
|
300
|
+
this.observedOutboundTracks.forEach((track) => this.emit('removed-outbound-track', track));
|
|
301
|
+
this.observedPeerConnectionTransports.forEach((transport) => this.emit('removed-peer-connection-transport', transport));
|
|
302
|
+
this.observedRemoteInboundRtps.forEach((rtp) => this.emit('removed-remote-inbound-rtp', rtp));
|
|
303
|
+
this.observedRemoteOutboundRtps.forEach((rtp) => this.emit('removed-remote-outbound-rtp', rtp));
|
|
304
|
+
|
|
305
|
+
this.observedCertificates.clear();
|
|
306
|
+
this.observedCodecs.clear();
|
|
307
|
+
this.observedDataChannels.clear();
|
|
308
|
+
this.observedIceCandidates.clear();
|
|
309
|
+
this.observedIceCandidatesPair.clear();
|
|
310
|
+
this.observedIceTransports.clear();
|
|
311
|
+
this.observedInboundRtps.clear();
|
|
312
|
+
this.observedInboundTracks.clear();
|
|
313
|
+
this.observedMediaPlayouts.clear();
|
|
314
|
+
this.observedMediaSources.clear();
|
|
315
|
+
this.observedOutboundRtps.clear();
|
|
316
|
+
this.observedOutboundTracks.clear();
|
|
317
|
+
this.observedPeerConnectionTransports.clear();
|
|
318
|
+
this.observedRemoteInboundRtps.clear();
|
|
319
|
+
this.observedRemoteOutboundRtps.clear();
|
|
320
|
+
|
|
321
|
+
this.client.call.observer.observedTURN.removePeerConnection(this);
|
|
322
|
+
|
|
323
|
+
if (!this.closedAt) this.closedAt = Date.now();
|
|
324
|
+
|
|
246
325
|
this.emit('close');
|
|
247
326
|
}
|
|
248
327
|
|
|
249
|
-
public
|
|
250
|
-
|
|
251
|
-
|
|
328
|
+
public accept(sample: PeerConnectionSample) {
|
|
329
|
+
if (this.closed) return;
|
|
330
|
+
this._visited = true;
|
|
252
331
|
|
|
253
|
-
|
|
332
|
+
this.availableIncomingBitrate = 0;
|
|
333
|
+
this.availableOutgoingBitrate = 0;
|
|
254
334
|
this.deltaInboundPacketsLost = 0;
|
|
255
335
|
this.deltaInboundPacketsReceived = 0;
|
|
256
336
|
this.deltaOutboundPacketsSent = 0;
|
|
@@ -258,316 +338,767 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
258
338
|
this.deltaDataChannelBytesReceived = 0;
|
|
259
339
|
this.deltaInboundReceivedBytes = 0;
|
|
260
340
|
this.deltaOutboundSentBytes = 0;
|
|
261
|
-
|
|
262
341
|
this.deltaReceivedAudioBytes = 0;
|
|
263
342
|
this.deltaReceivedVideoBytes = 0;
|
|
264
343
|
this.deltaReceivedAudioPackets = 0;
|
|
265
344
|
this.deltaReceivedVideoPackets = 0;
|
|
266
345
|
this.deltaSentAudioBytes = 0;
|
|
267
346
|
this.deltaSentVideoBytes = 0;
|
|
347
|
+
this.deltaTransportReceivedBytes = 0;
|
|
348
|
+
this.deltaTransportSentBytes = 0;
|
|
349
|
+
|
|
268
350
|
this.sendingAudioBitrate = 0;
|
|
269
351
|
this.sendingVideoBitrate = 0;
|
|
270
352
|
this.receivingAudioBitrate = 0;
|
|
271
353
|
this.receivingVideoBitrate = 0;
|
|
272
354
|
|
|
273
|
-
|
|
355
|
+
const now = Date.now();
|
|
356
|
+
const elapsedTimeInMs = now - this.updated;
|
|
357
|
+
const elapsedTimeInSec = elapsedTimeInMs / 1000;
|
|
358
|
+
const rttMeasurementsInSec: number[] = [];
|
|
359
|
+
const jitterMeasurements: number[] = [];
|
|
360
|
+
|
|
361
|
+
if (sample.certificates) {
|
|
362
|
+
for (const certificate of sample.certificates) {
|
|
363
|
+
this._updateCertificateStats(certificate);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (sample.codecs) {
|
|
367
|
+
for (const codec of sample.codecs) {
|
|
368
|
+
this._updateCodecStats(codec);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (sample.dataChannels) {
|
|
372
|
+
for (const dataChannel of sample.dataChannels) {
|
|
373
|
+
const observedDataChannel = this._updateDataChannelStats(dataChannel);
|
|
374
|
+
|
|
375
|
+
if (!observedDataChannel) continue;
|
|
376
|
+
|
|
377
|
+
this.deltaDataChannelBytesSent += observedDataChannel.deltaBytesSent;
|
|
378
|
+
this.deltaDataChannelBytesReceived += observedDataChannel.deltaBytesReceived;
|
|
379
|
+
this.deltaDataChannelMessagesSent += observedDataChannel.deltaMessagesSent;
|
|
380
|
+
this.deltaDataChannelMessagesReceived += observedDataChannel.deltaMessagesReceived;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (sample.iceCandidates) {
|
|
384
|
+
for (const iceCandidate of sample.iceCandidates) {
|
|
385
|
+
this._updateIceCandidateStats(iceCandidate);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (sample.iceCandidatePairs) {
|
|
389
|
+
for (const iceCandidatePair of sample.iceCandidatePairs) {
|
|
390
|
+
const observedCandidatePair = this._updateIceCandidatePairStats(iceCandidatePair);
|
|
391
|
+
|
|
392
|
+
if (!observedCandidatePair) continue;
|
|
393
|
+
|
|
394
|
+
if (observedCandidatePair.currentRoundTripTime) {
|
|
395
|
+
rttMeasurementsInSec.push(observedCandidatePair.currentRoundTripTime);
|
|
396
|
+
}
|
|
397
|
+
if (observedCandidatePair.availableIncomingBitrate) {
|
|
398
|
+
this.availableIncomingBitrate += observedCandidatePair.availableIncomingBitrate;
|
|
399
|
+
}
|
|
400
|
+
if (observedCandidatePair.availableOutgoingBitrate) {
|
|
401
|
+
this.availableOutgoingBitrate += observedCandidatePair.availableOutgoingBitrate;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (sample.iceTransports) {
|
|
406
|
+
for (const iceTransport of sample.iceTransports) {
|
|
407
|
+
const observedIceTransport = this._updateIceTransportStats(iceTransport);
|
|
408
|
+
|
|
409
|
+
if (!observedIceTransport) return;
|
|
410
|
+
|
|
411
|
+
observedIceTransport.bytesReceived;
|
|
412
|
+
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (sample.inboundRtps) {
|
|
416
|
+
for (const inboundRtp of sample.inboundRtps) {
|
|
417
|
+
const observedInboundRtp = this._updateInboundRtpStats(inboundRtp);
|
|
418
|
+
|
|
419
|
+
if (!observedInboundRtp) continue;
|
|
420
|
+
|
|
421
|
+
this.deltaInboundPacketsLost += observedInboundRtp.deltaLostPackets;
|
|
422
|
+
this.deltaInboundPacketsReceived += observedInboundRtp.deltaReceivedPackets;
|
|
423
|
+
this.deltaInboundReceivedBytes += observedInboundRtp.deltaBytesReceived;
|
|
424
|
+
|
|
425
|
+
switch (inboundRtp.kind) {
|
|
426
|
+
case 'audio':
|
|
427
|
+
this.deltaReceivedAudioBytes += observedInboundRtp.deltaBytesReceived;
|
|
428
|
+
this.deltaReceivedAudioPackets += observedInboundRtp.deltaReceivedPackets;
|
|
429
|
+
break;
|
|
430
|
+
case 'video':
|
|
431
|
+
this.deltaReceivedVideoBytes += observedInboundRtp.deltaBytesReceived;
|
|
432
|
+
this.deltaReceivedVideoPackets += observedInboundRtp.deltaReceivedPackets;
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (observedInboundRtp.jitter) {
|
|
437
|
+
jitterMeasurements.push(observedInboundRtp.jitter);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (sample.mediaPlayouts) {
|
|
442
|
+
for (const mediaPlayout of sample.mediaPlayouts) {
|
|
443
|
+
this._updateMediaPlayoutStats(mediaPlayout);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (sample.mediaSources) {
|
|
447
|
+
for (const mediaSource of sample.mediaSources) {
|
|
448
|
+
this._updateMediaSourceStats(mediaSource);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (sample.outboundRtps) {
|
|
452
|
+
for (const outboundRtp of sample.outboundRtps) {
|
|
453
|
+
const observedOutboundRtp = this._updateOutboundRtpStats(outboundRtp);
|
|
454
|
+
|
|
455
|
+
if (!observedOutboundRtp) continue;
|
|
456
|
+
|
|
457
|
+
this.deltaOutboundPacketsSent += observedOutboundRtp.deltaPacketsSent ?? 0;
|
|
458
|
+
this.deltaOutboundSentBytes += observedOutboundRtp.deltaBytesSent ?? 0;
|
|
459
|
+
|
|
460
|
+
switch (outboundRtp.kind) {
|
|
461
|
+
case 'audio':
|
|
462
|
+
this.deltaSentAudioBytes += observedOutboundRtp.deltaBytesSent;
|
|
463
|
+
this.deltaSentAudioBytes += observedOutboundRtp.deltaPacketsSent;
|
|
464
|
+
break;
|
|
465
|
+
case 'video':
|
|
466
|
+
this.deltaSentVideoBytes += observedOutboundRtp.deltaBytesSent;
|
|
467
|
+
this.deltaSentVideoBytes += observedOutboundRtp.deltaPacketsSent;
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (sample.peerConnectionTransports) {
|
|
474
|
+
for (const peerConnectionTransport of sample.peerConnectionTransports) {
|
|
475
|
+
const observedTransport = this._updatePeerConnectionTransportStats(peerConnectionTransport);
|
|
476
|
+
|
|
477
|
+
if (!observedTransport) continue;
|
|
478
|
+
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
if (sample.remoteInboundRtps) {
|
|
482
|
+
for (const remoteInboundRtp of sample.remoteInboundRtps) {
|
|
483
|
+
const observedRemoteInboundRtp = this._updateRemoteInboundRtpStats(remoteInboundRtp);
|
|
484
|
+
|
|
485
|
+
if (!observedRemoteInboundRtp) continue;
|
|
486
|
+
|
|
487
|
+
if (observedRemoteInboundRtp.roundTripTime) {
|
|
488
|
+
rttMeasurementsInSec.push(observedRemoteInboundRtp.roundTripTime);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if (sample.remoteOutboundRtps) {
|
|
493
|
+
for (const remoteOutboundRtp of sample.remoteOutboundRtps) {
|
|
494
|
+
const observedRemoteOutboundRtp = this._updateRemoteOutboundRtpStats(remoteOutboundRtp);
|
|
495
|
+
|
|
496
|
+
if (!observedRemoteOutboundRtp) continue;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// tracks should be updated last as they are derived stats
|
|
501
|
+
// and depends on base stats but they all received in the sample sample
|
|
502
|
+
if (sample.inboundTracks) {
|
|
503
|
+
for (const inboundTrack of sample.inboundTracks) {
|
|
504
|
+
this._updateInboundTrackSample(inboundTrack);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (sample.outboundTracks) {
|
|
508
|
+
for (const outboundTrack of sample.outboundTracks) {
|
|
509
|
+
this._updateOutboundTrackSample(outboundTrack);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
this.totalInboundPacketsLost += this.deltaInboundPacketsLost;
|
|
514
|
+
this.totalInboundPacketsReceived += this.deltaInboundPacketsReceived;
|
|
515
|
+
this.totalOutboundPacketsSent += this.deltaOutboundPacketsSent;
|
|
516
|
+
this.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
|
|
517
|
+
this.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
|
|
518
|
+
this.totalDataChannelMessagesSent += this.deltaDataChannelMessagesSent;
|
|
519
|
+
this.totalDataChannelMessagesReceived += this.deltaDataChannelMessagesReceived;
|
|
520
|
+
this.totalReceivedAudioBytes += this.deltaReceivedAudioBytes;
|
|
521
|
+
this.totalReceivedVideoBytes += this.deltaReceivedVideoBytes;
|
|
522
|
+
this.totalSentAudioBytes += this.deltaSentAudioBytes;
|
|
523
|
+
this.totalSentVideoBytes += this.deltaSentVideoBytes;
|
|
524
|
+
this.totalReceivedAudioPacktes += this.deltaReceivedAudioPackets;
|
|
525
|
+
this.totalReceivedVideoPackets += this.deltaReceivedVideoPackets;
|
|
526
|
+
this.totalSentAudioPackets += this.deltaSentAudioBytes;
|
|
527
|
+
this.totalSentVideoPackets += this.deltaSentVideoBytes;
|
|
528
|
+
|
|
529
|
+
this.receivingPacketsPerSecond = this.deltaInboundPacketsReceived / elapsedTimeInSec;
|
|
530
|
+
this.sendingPacketsPerSecond = this.deltaOutboundPacketsSent / elapsedTimeInSec;
|
|
531
|
+
this.sendingAudioBitrate = (this.deltaSentAudioBytes * 8) / elapsedTimeInSec;
|
|
532
|
+
this.sendingVideoBitrate = (this.deltaSentVideoBytes * 8) / elapsedTimeInSec;
|
|
533
|
+
this.receivingAudioBitrate = (this.deltaReceivedAudioBytes * 8) / elapsedTimeInSec;
|
|
534
|
+
this.receivingVideoBitrate = (this.deltaReceivedVideoBytes * 8) / elapsedTimeInSec;
|
|
535
|
+
|
|
536
|
+
if (rttMeasurementsInSec.length > 0) {
|
|
537
|
+
this.currentRttInMs = getMedian(rttMeasurementsInSec, false) * 1000;
|
|
538
|
+
} else {
|
|
539
|
+
this.currentRttInMs = undefined;
|
|
540
|
+
}
|
|
541
|
+
if (jitterMeasurements.length > 0) {
|
|
542
|
+
this.currentJitter = getMedian(jitterMeasurements, false);
|
|
543
|
+
} else {
|
|
544
|
+
this.currentJitter = undefined;
|
|
545
|
+
}
|
|
546
|
+
const wasUsingTURN = this.usingTURN;
|
|
547
|
+
const selectedIceCandidatePairs = this.selectedIceCandidatePairs;
|
|
548
|
+
const selectedCandidatePairForTurn: ObservedIceCandidatePair[] = [];
|
|
549
|
+
|
|
550
|
+
this.usingTCP = false;
|
|
551
|
+
this.usingTURN = false;
|
|
552
|
+
|
|
553
|
+
for (const selectedCandidatePair of selectedIceCandidatePairs) {
|
|
554
|
+
if (selectedCandidatePair.getLocalCandidate()?.protocol === 'tcp') {
|
|
555
|
+
this.usingTCP = true;
|
|
556
|
+
}
|
|
557
|
+
if (selectedCandidatePair.getLocalCandidate()?.candidateType === 'relay' && selectedCandidatePair.getRemoteCandidate()?.url?.startsWith('turn:')) {
|
|
558
|
+
selectedCandidatePairForTurn.push(selectedCandidatePair);
|
|
559
|
+
this.usingTURN = true;
|
|
560
|
+
}
|
|
561
|
+
this.deltaTransportReceivedBytes += selectedCandidatePair.deltaBytesReceived;
|
|
562
|
+
this.deltaTransportSentBytes += selectedCandidatePair.deltaBytesSent;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (this.usingTURN) {
|
|
566
|
+
if (!this.observedTurnServer) {
|
|
567
|
+
this.observedTurnServer = this.client.call.observer.observedTURN.addPeerConnection(this);
|
|
568
|
+
}
|
|
569
|
+
this.observedTurnServer?.updateTurnUsage(...selectedCandidatePairForTurn);
|
|
570
|
+
} else if (wasUsingTURN) {
|
|
571
|
+
if (!this.usingTURN) {
|
|
572
|
+
this.client.call.observer.observedTURN.removePeerConnection(this);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
this.calculatedScore.value = sample.score;
|
|
576
|
+
this.updated = now;
|
|
577
|
+
this._checkVisited();
|
|
578
|
+
|
|
579
|
+
this.emit('update');
|
|
274
580
|
}
|
|
275
581
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
582
|
+
private _checkVisited() {
|
|
583
|
+
for (const certificate of [ ...this.observedCertificates.values() ]) {
|
|
584
|
+
if (certificate.visited) continue;
|
|
279
585
|
|
|
280
|
-
|
|
281
|
-
if (this._model.label !== sample.label) {
|
|
282
|
-
this._model.label = sample.label;
|
|
586
|
+
this.observedCertificates.delete(certificate.id);
|
|
283
587
|
}
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
this.
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
588
|
+
for (const codec of [ ...this.observedCodecs.values() ]) {
|
|
589
|
+
if (codec.visited) continue;
|
|
590
|
+
|
|
591
|
+
this.observedCodecs.delete(codec.id);
|
|
592
|
+
this.emit('removed-codec', codec);
|
|
593
|
+
}
|
|
594
|
+
for (const dataChannel of [ ...this.observedDataChannels.values() ]) {
|
|
595
|
+
if (dataChannel.visited) continue;
|
|
596
|
+
|
|
597
|
+
this.observedDataChannels.delete(dataChannel.id);
|
|
598
|
+
this.emit('removed-data-channel', dataChannel);
|
|
599
|
+
}
|
|
600
|
+
for (const iceCandidate of [ ...this.observedIceCandidates.values() ]) {
|
|
601
|
+
if (iceCandidate.visited) continue;
|
|
602
|
+
|
|
603
|
+
this.observedIceCandidates.delete(iceCandidate.id);
|
|
604
|
+
this.emit('removed-ice-candidate', iceCandidate);
|
|
605
|
+
}
|
|
606
|
+
for (const iceCandidatePair of [ ...this.observedIceCandidatesPair.values() ]) {
|
|
607
|
+
if (iceCandidatePair.visited) continue;
|
|
608
|
+
|
|
609
|
+
this.observedIceCandidatesPair.delete(iceCandidatePair.id);
|
|
610
|
+
this.emit('removed-ice-candidate-pair', iceCandidatePair);
|
|
611
|
+
}
|
|
612
|
+
for (const iceTransport of [ ...this.observedIceTransports.values() ]) {
|
|
613
|
+
if (iceTransport.visited) continue;
|
|
614
|
+
|
|
615
|
+
this.observedIceTransports.delete(iceTransport.id);
|
|
616
|
+
this.emit('removed-ice-transport', iceTransport);
|
|
617
|
+
}
|
|
618
|
+
for (const inboundRtp of [ ...this.observedInboundRtps.values() ]) {
|
|
619
|
+
if (inboundRtp.visited) continue;
|
|
620
|
+
|
|
621
|
+
this.observedInboundRtps.delete(inboundRtp.ssrc);
|
|
622
|
+
this.emit('removed-inbound-rtp', inboundRtp);
|
|
623
|
+
}
|
|
624
|
+
for (const inboundTrack of [ ...this.observedInboundTracks.values() ]) {
|
|
625
|
+
if (inboundTrack.visited) continue;
|
|
626
|
+
|
|
627
|
+
this.observedInboundTracks.delete(inboundTrack.id);
|
|
628
|
+
this.emit('removed-inbound-track', inboundTrack);
|
|
629
|
+
}
|
|
630
|
+
for (const mediaPlayout of [ ...this.observedMediaPlayouts.values() ]) {
|
|
631
|
+
if (mediaPlayout.visited) continue;
|
|
632
|
+
|
|
633
|
+
this.observedMediaPlayouts.delete(mediaPlayout.id);
|
|
634
|
+
this.emit('removed-media-playout', mediaPlayout);
|
|
635
|
+
}
|
|
636
|
+
for (const mediaSource of [ ...this.observedMediaSources.values() ]) {
|
|
637
|
+
if (mediaSource.visited) continue;
|
|
638
|
+
|
|
639
|
+
this.observedMediaSources.delete(mediaSource.id);
|
|
640
|
+
this.emit('removed-media-source', mediaSource);
|
|
641
|
+
}
|
|
642
|
+
for (const outboundRtp of [ ...this.observedOutboundRtps.values() ]) {
|
|
643
|
+
if (outboundRtp.visited) continue;
|
|
644
|
+
|
|
645
|
+
this.observedOutboundRtps.delete(outboundRtp.ssrc);
|
|
646
|
+
this.emit('removed-outbound-rtp', outboundRtp);
|
|
647
|
+
}
|
|
648
|
+
for (const outboundTrack of [ ...this.observedOutboundTracks.values() ]) {
|
|
649
|
+
if (outboundTrack.visited) continue;
|
|
312
650
|
|
|
313
|
-
|
|
314
|
-
this.
|
|
315
|
-
}
|
|
316
|
-
this.
|
|
651
|
+
this.observedOutboundTracks.delete(outboundTrack.id);
|
|
652
|
+
this.emit('removed-outbound-track', outboundTrack);
|
|
653
|
+
}
|
|
654
|
+
for (const peerConnectionTransport of [ ...this.observedPeerConnectionTransports.values() ]) {
|
|
655
|
+
if (peerConnectionTransport.visited) continue;
|
|
656
|
+
|
|
657
|
+
this.observedPeerConnectionTransports.delete(peerConnectionTransport.id);
|
|
658
|
+
this.emit('removed-peer-connection-transport', peerConnectionTransport);
|
|
659
|
+
}
|
|
660
|
+
for (const remoteInboundRtp of [ ...this.observedRemoteInboundRtps.values() ]) {
|
|
661
|
+
if (remoteInboundRtp.visited) continue;
|
|
317
662
|
|
|
318
|
-
|
|
663
|
+
this.observedRemoteInboundRtps.delete(remoteInboundRtp.ssrc);
|
|
664
|
+
this.emit('removed-remote-inbound-rtp', remoteInboundRtp);
|
|
665
|
+
}
|
|
666
|
+
for (const remoteOutboundRtp of [ ...this.observedRemoteOutboundRtps.values() ]) {
|
|
667
|
+
if (remoteOutboundRtp.visited) continue;
|
|
319
668
|
|
|
320
|
-
|
|
669
|
+
this.observedRemoteOutboundRtps.delete(remoteOutboundRtp.ssrc);
|
|
670
|
+
this.emit('removed-remote-outbound-rtp', remoteOutboundRtp);
|
|
671
|
+
}
|
|
321
672
|
}
|
|
322
673
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
674
|
+
private _updateCertificateStats(stats: CertificateStats) {
|
|
675
|
+
let observedCertificate = this.observedCertificates.get(stats.id);
|
|
676
|
+
|
|
677
|
+
if (!observedCertificate) {
|
|
678
|
+
if (!stats.timestamp || !stats.id || !stats.fingerprint) {
|
|
679
|
+
return logger.warn(
|
|
680
|
+
`ObservedPeerConnection received an invalid CertificateStats (missing timestamp OR id OR fingerprint field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
681
|
+
stats
|
|
682
|
+
);
|
|
683
|
+
}
|
|
327
684
|
|
|
328
|
-
|
|
329
|
-
this._inboundVideoTracks.delete(result.trackId);
|
|
330
|
-
});
|
|
331
|
-
this._inboundVideoTracks.set(result.trackId, result);
|
|
685
|
+
observedCertificate = new ObservedCertificate(stats.timestamp, stats.id, this);
|
|
332
686
|
|
|
333
|
-
|
|
687
|
+
observedCertificate.update(stats);
|
|
334
688
|
|
|
335
|
-
|
|
689
|
+
this.observedCertificates.set(stats.id, observedCertificate);
|
|
690
|
+
this.emit('added-certificate', observedCertificate);
|
|
691
|
+
} else {
|
|
692
|
+
observedCertificate.update(stats);
|
|
693
|
+
this.emit('updated-certificate', observedCertificate);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
return observedCertificate;
|
|
336
697
|
}
|
|
337
698
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const result = new ObservedOutboundAudioTrack(config, this);
|
|
699
|
+
private _updateCodecStats(stats: CodecStats) {
|
|
700
|
+
let observedCodec = this.observedCodecs.get(stats.id);
|
|
342
701
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
702
|
+
if (!observedCodec) {
|
|
703
|
+
if (!stats.timestamp || !stats.id || !stats.mimeType) {
|
|
704
|
+
return logger.warn(
|
|
705
|
+
`ObservedPeerConnection received an invalid CodecStats (missing timestamp OR id OR mimeType field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
706
|
+
stats
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
observedCodec = new ObservedCodec(stats.timestamp, stats.id, stats.mimeType, this);
|
|
347
711
|
|
|
348
|
-
|
|
712
|
+
observedCodec.update(stats);
|
|
713
|
+
|
|
714
|
+
this.observedCodecs.set(stats.id, observedCodec);
|
|
715
|
+
this.emit('added-codec', observedCodec);
|
|
716
|
+
} else {
|
|
717
|
+
observedCodec.update(stats);
|
|
718
|
+
}
|
|
719
|
+
this.emit('updated-codec', observedCodec);
|
|
349
720
|
|
|
350
|
-
return
|
|
721
|
+
return observedCodec;
|
|
351
722
|
}
|
|
352
723
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
724
|
+
private _updateDataChannelStats(stats: DataChannelStats) {
|
|
725
|
+
let observedDataChannel = this.observedDataChannels.get(stats.id);
|
|
726
|
+
|
|
727
|
+
if (!observedDataChannel) {
|
|
728
|
+
if (!stats.timestamp || !stats.id) {
|
|
729
|
+
return logger.warn(
|
|
730
|
+
`ObservedPeerConnection received an invalid DataChannelStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
731
|
+
stats
|
|
732
|
+
);
|
|
733
|
+
}
|
|
357
734
|
|
|
358
|
-
|
|
359
|
-
this._outboundVideoTracks.delete(result.trackId);
|
|
360
|
-
});
|
|
361
|
-
this._outboundVideoTracks.set(result.trackId, result);
|
|
735
|
+
observedDataChannel = new ObservedDataChannel(stats.timestamp, stats.id, this);
|
|
362
736
|
|
|
363
|
-
|
|
737
|
+
observedDataChannel.update(stats);
|
|
364
738
|
|
|
365
|
-
|
|
739
|
+
this.observedDataChannels.set(stats.id, observedDataChannel);
|
|
740
|
+
this.emit('added-data-channel', observedDataChannel);
|
|
741
|
+
} else {
|
|
742
|
+
observedDataChannel.update(stats);
|
|
743
|
+
}
|
|
744
|
+
this.emit('updated-data-channel', observedDataChannel);
|
|
745
|
+
|
|
746
|
+
return observedDataChannel;
|
|
366
747
|
}
|
|
367
748
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const result = new ObservedDataChannel({
|
|
372
|
-
channelId,
|
|
373
|
-
}, this);
|
|
749
|
+
private _updateIceCandidateStats(stats: IceCandidateStats) {
|
|
750
|
+
let observedIceCandidate = this.observedIceCandidates.get(stats.id);
|
|
374
751
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
752
|
+
if (!observedIceCandidate) {
|
|
753
|
+
if (!stats.timestamp || !stats.id) {
|
|
754
|
+
return logger.warn(
|
|
755
|
+
`ObservedPeerConnection received an invalid IceCandidateStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
756
|
+
stats
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
observedIceCandidate = new ObservedIceCandidate(stats.timestamp, stats.id, this);
|
|
379
761
|
|
|
380
|
-
|
|
762
|
+
observedIceCandidate.update(stats);
|
|
763
|
+
|
|
764
|
+
this.observedIceCandidates.set(stats.id, observedIceCandidate);
|
|
765
|
+
this.emit('added-ice-candidate', observedIceCandidate);
|
|
766
|
+
} else {
|
|
767
|
+
observedIceCandidate.update(stats);
|
|
768
|
+
}
|
|
769
|
+
this.emit('updated-ice-candidate', observedIceCandidate);
|
|
381
770
|
|
|
382
|
-
return
|
|
771
|
+
return observedIceCandidate;
|
|
383
772
|
}
|
|
384
773
|
|
|
385
|
-
|
|
386
|
-
let
|
|
387
|
-
|
|
388
|
-
|
|
774
|
+
private _updateIceCandidatePairStats(stats: IceCandidateStats) {
|
|
775
|
+
let observedIceCandidatePair = this.observedIceCandidatesPair.get(stats.id);
|
|
776
|
+
|
|
777
|
+
if (!observedIceCandidatePair) {
|
|
778
|
+
if (!stats.timestamp || !stats.id) {
|
|
779
|
+
return logger.warn(
|
|
780
|
+
`ObservedPeerConnection received an invalid IceCandidateStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
781
|
+
stats
|
|
782
|
+
);
|
|
783
|
+
}
|
|
389
784
|
|
|
390
|
-
|
|
391
|
-
track.updateMetrics();
|
|
785
|
+
observedIceCandidatePair = new ObservedIceCandidatePair(stats.timestamp, stats.id, this);
|
|
392
786
|
|
|
393
|
-
|
|
394
|
-
this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
|
|
395
|
-
this.deltaInboundReceivedBytes += track.deltaBytesReceived;
|
|
396
|
-
|
|
397
|
-
this.deltaReceivedAudioBytes += track.deltaBytesReceived;
|
|
398
|
-
this.deltaReceivedAudioPackets += track.deltaReceivedPackets;
|
|
787
|
+
observedIceCandidatePair.update(stats);
|
|
399
788
|
|
|
400
|
-
this.
|
|
789
|
+
this.observedIceCandidatesPair.set(stats.id, observedIceCandidatePair);
|
|
790
|
+
this.emit('added-ice-candidate-pair', observedIceCandidatePair);
|
|
791
|
+
} else {
|
|
792
|
+
observedIceCandidatePair.update(stats);
|
|
793
|
+
}
|
|
794
|
+
this.emit('updated-ice-candidate-pair', observedIceCandidatePair);
|
|
795
|
+
|
|
796
|
+
return observedIceCandidatePair;
|
|
797
|
+
}
|
|
401
798
|
|
|
402
|
-
|
|
403
|
-
|
|
799
|
+
private _updateIceTransportStats(stats: IceCandidateStats) {
|
|
800
|
+
let observedIceTransport = this.observedIceTransports.get(stats.id);
|
|
404
801
|
|
|
405
|
-
|
|
406
|
-
|
|
802
|
+
if (!observedIceTransport) {
|
|
803
|
+
if (!stats.timestamp || !stats.id) {
|
|
804
|
+
return logger.warn(
|
|
805
|
+
`ObservedPeerConnection received an invalid IceCandidateStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
806
|
+
stats
|
|
807
|
+
);
|
|
808
|
+
}
|
|
407
809
|
|
|
408
|
-
|
|
409
|
-
track.updateMetrics();
|
|
810
|
+
observedIceTransport = new ObservedIceTransport(stats.timestamp, stats.id, this);
|
|
410
811
|
|
|
411
|
-
|
|
412
|
-
this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
|
|
413
|
-
this.deltaInboundReceivedBytes += track.deltaBytesReceived;
|
|
414
|
-
|
|
415
|
-
this.deltaReceivedVideoBytes += track.deltaBytesReceived;
|
|
416
|
-
this.deltaReceivedVideoPackets += track.deltaReceivedPackets;
|
|
812
|
+
observedIceTransport.update(stats);
|
|
417
813
|
|
|
418
|
-
this.
|
|
814
|
+
this.observedIceTransports.set(stats.id, observedIceTransport);
|
|
815
|
+
this.emit('added-ice-transport', observedIceTransport);
|
|
816
|
+
} else {
|
|
817
|
+
observedIceTransport.update(stats);
|
|
818
|
+
}
|
|
819
|
+
this.emit('updated-ice-transport', observedIceTransport);
|
|
419
820
|
|
|
420
|
-
|
|
421
|
-
|
|
821
|
+
return observedIceTransport;
|
|
822
|
+
}
|
|
422
823
|
|
|
423
|
-
|
|
424
|
-
|
|
824
|
+
private _updateInboundRtpStats(stats: InboundRtpStats) {
|
|
825
|
+
let observedInboundRtp = this.observedInboundRtps.get(stats.ssrc);
|
|
425
826
|
|
|
426
|
-
|
|
427
|
-
|
|
827
|
+
if (!observedInboundRtp) {
|
|
828
|
+
if (!stats.timestamp || !stats.id || !stats.ssrc || !stats.kind || !stats.trackIdentifier) {
|
|
829
|
+
return logger.warn(
|
|
830
|
+
`ObservedPeerConnection received an invalid InboundRtpStats (missing timestamp OR id OR ssrc OR kind OR trackIdentifier field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
831
|
+
stats
|
|
832
|
+
);
|
|
833
|
+
}
|
|
428
834
|
|
|
429
|
-
|
|
430
|
-
|
|
835
|
+
observedInboundRtp = new ObservedInboundRtp(
|
|
836
|
+
stats.timestamp,
|
|
837
|
+
stats.id,
|
|
838
|
+
stats.ssrc,
|
|
839
|
+
stats.kind as MediaKind,
|
|
840
|
+
stats.trackIdentifier,
|
|
841
|
+
this
|
|
842
|
+
);
|
|
431
843
|
|
|
432
|
-
|
|
433
|
-
this.deltaSentAudioBytes += track.deltaSentPackets;
|
|
434
|
-
|
|
435
|
-
this.sendingAudioBitrate += track.bitrate;
|
|
844
|
+
observedInboundRtp.update(stats);
|
|
436
845
|
|
|
437
|
-
|
|
438
|
-
|
|
846
|
+
this.observedInboundRtps.set(stats.ssrc, observedInboundRtp);
|
|
847
|
+
this.emit('added-inbound-rtp', observedInboundRtp);
|
|
848
|
+
} else {
|
|
849
|
+
observedInboundRtp.update(stats);
|
|
850
|
+
}
|
|
851
|
+
this.emit('updated-inbound-rtp', observedInboundRtp);
|
|
439
852
|
|
|
440
|
-
|
|
441
|
-
|
|
853
|
+
return observedInboundRtp;
|
|
854
|
+
}
|
|
442
855
|
|
|
443
|
-
|
|
444
|
-
|
|
856
|
+
private _updateInboundTrackSample(stats: InboundTrackSample) {
|
|
857
|
+
let observedInboundTrack = this.observedInboundTracks.get(stats.id);
|
|
445
858
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
859
|
+
if (!observedInboundTrack) {
|
|
860
|
+
if (!stats.timestamp || !stats.id || !stats.kind) {
|
|
861
|
+
return logger.warn(
|
|
862
|
+
`ObservedPeerConnection received an invalid InboundTrackSample (missing timestamp OR id OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
863
|
+
stats
|
|
864
|
+
);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
const inboundRtp = [ ...this.observedInboundRtps.values() ].find((inbRtp) => inbRtp.trackIdentifier === stats.id);
|
|
868
|
+
const mediaPlayout = inboundRtp ?
|
|
869
|
+
[ ...this.observedMediaPlayouts.values() ].find((mp) => mp.id === inboundRtp.playoutId) : undefined;
|
|
870
|
+
|
|
871
|
+
observedInboundTrack = new ObservedInboundTrack(
|
|
872
|
+
stats.timestamp,
|
|
873
|
+
stats.id,
|
|
874
|
+
stats.kind as MediaKind,
|
|
875
|
+
this,
|
|
876
|
+
inboundRtp,
|
|
877
|
+
mediaPlayout,
|
|
878
|
+
);
|
|
879
|
+
|
|
880
|
+
observedInboundTrack.update(stats);
|
|
451
881
|
|
|
452
|
-
this.
|
|
882
|
+
this.observedInboundTracks.set(stats.id, observedInboundTrack);
|
|
883
|
+
this.emit('added-inbound-track', observedInboundTrack);
|
|
884
|
+
} else {
|
|
885
|
+
observedInboundTrack.update(stats);
|
|
886
|
+
}
|
|
887
|
+
this.emit('updated-inbound-track', observedInboundTrack);
|
|
453
888
|
|
|
454
|
-
|
|
455
|
-
|
|
889
|
+
return observedInboundTrack;
|
|
890
|
+
}
|
|
456
891
|
|
|
457
|
-
|
|
458
|
-
|
|
892
|
+
private _updateMediaPlayoutStats(stats: MediaPlayoutStats) {
|
|
893
|
+
let observedMediaPlayout = this.observedMediaPlayouts.get(stats.id);
|
|
459
894
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
895
|
+
if (!observedMediaPlayout) {
|
|
896
|
+
if (!stats.timestamp || !stats.id || !stats.kind) {
|
|
897
|
+
return logger.warn(
|
|
898
|
+
`ObservedPeerConnection received an invalid InboundRtpStats (missing timestamp OR id OR kind OR trackIdentifier field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
899
|
+
stats
|
|
900
|
+
);
|
|
901
|
+
}
|
|
464
902
|
|
|
465
|
-
|
|
466
|
-
|
|
903
|
+
observedMediaPlayout = new ObservedMediaPlayout(
|
|
904
|
+
stats.timestamp,
|
|
905
|
+
stats.id,
|
|
906
|
+
stats.kind as MediaKind,
|
|
907
|
+
this
|
|
908
|
+
);
|
|
467
909
|
|
|
468
|
-
|
|
910
|
+
observedMediaPlayout.update(stats);
|
|
469
911
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
912
|
+
this.observedMediaPlayouts.set(stats.id, observedMediaPlayout);
|
|
913
|
+
this.emit('added-media-playout', observedMediaPlayout);
|
|
914
|
+
} else {
|
|
915
|
+
observedMediaPlayout.update(stats);
|
|
473
916
|
}
|
|
917
|
+
this.emit('updated-media-playout', observedMediaPlayout);
|
|
474
918
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
919
|
+
return observedMediaPlayout;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
private _updateMediaSourceStats(stats: MediaSourceStats) {
|
|
923
|
+
let observedMediaSource = this.observedMediaSources.get(stats.id);
|
|
924
|
+
|
|
925
|
+
if (!observedMediaSource) {
|
|
926
|
+
if (!stats.timestamp || !stats.id || !stats.kind) {
|
|
927
|
+
return logger.warn(
|
|
928
|
+
`ObservedPeerConnection received an invalid InboundRtpStats (missing timestamp OR id OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
929
|
+
stats
|
|
930
|
+
);
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
observedMediaSource = new ObservedMediaSource(
|
|
934
|
+
stats.timestamp,
|
|
935
|
+
stats.id,
|
|
936
|
+
stats.kind as MediaKind,
|
|
937
|
+
this
|
|
938
|
+
);
|
|
939
|
+
|
|
940
|
+
observedMediaSource.update(stats);
|
|
941
|
+
|
|
942
|
+
this.observedMediaSources.set(stats.id, observedMediaSource);
|
|
943
|
+
this.emit('added-media-source', observedMediaSource);
|
|
944
|
+
} else {
|
|
945
|
+
observedMediaSource.update(stats);
|
|
946
|
+
}
|
|
947
|
+
this.emit('updated-media-source', observedMediaSource);
|
|
948
|
+
|
|
949
|
+
return observedMediaSource;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
private _updateOutboundRtpStats(stats: OutboundRtpStats) {
|
|
953
|
+
let observedOutboundRtp = this.observedOutboundRtps.get(stats.ssrc);
|
|
954
|
+
|
|
955
|
+
if (!observedOutboundRtp) {
|
|
956
|
+
if (!stats.timestamp || !stats.id || !stats.ssrc || !stats.kind) {
|
|
957
|
+
return logger.warn(
|
|
958
|
+
`ObservedPeerConnection received an invalid OutboundRtpStats (missing timestamp OR id OR ssrc OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
959
|
+
stats
|
|
960
|
+
);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
observedOutboundRtp = new ObservedOutboundRtp(
|
|
964
|
+
stats.timestamp,
|
|
965
|
+
stats.id,
|
|
966
|
+
stats.ssrc,
|
|
967
|
+
stats.kind as MediaKind,
|
|
968
|
+
this
|
|
969
|
+
);
|
|
970
|
+
|
|
971
|
+
observedOutboundRtp.update(stats);
|
|
972
|
+
|
|
973
|
+
this.observedOutboundRtps.set(stats.ssrc, observedOutboundRtp);
|
|
974
|
+
this.emit('added-outbound-rtp', observedOutboundRtp);
|
|
975
|
+
} else {
|
|
976
|
+
observedOutboundRtp.update(stats);
|
|
977
|
+
}
|
|
978
|
+
this.emit('updated-outbound-rtp', observedOutboundRtp);
|
|
979
|
+
|
|
980
|
+
return observedOutboundRtp;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
public _updateOutboundTrackSample(stats: OutboundTrackSample) {
|
|
984
|
+
let observedOutboundTrack = this.observedOutboundTracks.get(stats.id);
|
|
489
985
|
|
|
490
|
-
if (
|
|
491
|
-
|
|
492
|
-
|
|
986
|
+
if (!observedOutboundTrack) {
|
|
987
|
+
if (!stats.timestamp || !stats.id || !stats.kind) {
|
|
988
|
+
return logger.warn(
|
|
989
|
+
`ObservedPeerConnection received an invalid OutboundTrackSample (missing timestamp OR id OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
990
|
+
stats
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
const observedMediaSource = [ ...this.observedMediaSources.values() ].find((mediaSource) => mediaSource.trackIdentifier === stats.id);
|
|
994
|
+
const outboundRtps = observedMediaSource
|
|
995
|
+
? [ ...this.observedOutboundRtps.values() ].filter((outboundRtp) => outboundRtp.mediaSourceId === observedMediaSource?.id) : undefined;
|
|
996
|
+
|
|
997
|
+
observedOutboundTrack = new ObservedOutboundTrack(
|
|
998
|
+
stats.timestamp,
|
|
999
|
+
stats.id,
|
|
1000
|
+
stats.kind as MediaKind,
|
|
1001
|
+
this,
|
|
1002
|
+
outboundRtps,
|
|
1003
|
+
observedMediaSource,
|
|
1004
|
+
);
|
|
1005
|
+
|
|
1006
|
+
observedOutboundTrack.update(stats);
|
|
1007
|
+
|
|
1008
|
+
this.observedOutboundTracks.set(stats.id, observedOutboundTrack);
|
|
1009
|
+
this.emit('added-outbound-track', observedOutboundTrack);
|
|
493
1010
|
} else {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
1011
|
+
observedOutboundTrack.update(stats);
|
|
1012
|
+
}
|
|
1013
|
+
this.emit('updated-outbound-track', observedOutboundTrack);
|
|
1014
|
+
|
|
1015
|
+
return observedOutboundTrack;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
private _updatePeerConnectionTransportStats(stats: PeerConnectionTransportStats) {
|
|
1019
|
+
let observedPeerConnectionTransport = this.observedPeerConnectionTransports.get(stats.id);
|
|
1020
|
+
|
|
1021
|
+
if (!observedPeerConnectionTransport) {
|
|
1022
|
+
if (!stats.timestamp || !stats.id) {
|
|
1023
|
+
return logger.warn(
|
|
1024
|
+
`ObservedPeerConnection received an invalid PeerConnectionTransportStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
1025
|
+
stats
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
observedPeerConnectionTransport = new ObservedPeerConnectionTransport(stats.timestamp, stats.id, this);
|
|
1030
|
+
|
|
1031
|
+
observedPeerConnectionTransport.update(stats);
|
|
1032
|
+
|
|
1033
|
+
this.observedPeerConnectionTransports.set(stats.id, observedPeerConnectionTransport);
|
|
1034
|
+
this.emit('added-peer-connection-transport', observedPeerConnectionTransport);
|
|
1035
|
+
} else {
|
|
1036
|
+
observedPeerConnectionTransport.update(stats);
|
|
1037
|
+
}
|
|
1038
|
+
this.emit('updated-peer-connection-transport', observedPeerConnectionTransport);
|
|
1039
|
+
|
|
1040
|
+
return observedPeerConnectionTransport;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
private _updateRemoteInboundRtpStats(stats: RemoteInboundRtpStats) {
|
|
1044
|
+
let observedRemoteInboundRtp = this.observedRemoteInboundRtps.get(stats.ssrc);
|
|
1045
|
+
|
|
1046
|
+
if (!observedRemoteInboundRtp) {
|
|
1047
|
+
if (!stats.timestamp || !stats.id || !stats.ssrc || !stats.kind) {
|
|
1048
|
+
return logger.warn(
|
|
1049
|
+
`ObservedPeerConnection received an invalid RemoteInboundRtpStats (missing timestamp OR id OR ssrc OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
1050
|
+
stats
|
|
1051
|
+
);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
observedRemoteInboundRtp = new ObservedRemoteInboundRtp(
|
|
1055
|
+
stats.timestamp,
|
|
1056
|
+
stats.id,
|
|
1057
|
+
stats.ssrc,
|
|
1058
|
+
stats.kind as MediaKind,
|
|
1059
|
+
this
|
|
1060
|
+
);
|
|
1061
|
+
|
|
1062
|
+
observedRemoteInboundRtp.update(stats);
|
|
1063
|
+
|
|
1064
|
+
this.observedRemoteInboundRtps.set(stats.ssrc, observedRemoteInboundRtp);
|
|
1065
|
+
this.emit('added-remote-inbound-rtp', observedRemoteInboundRtp);
|
|
1066
|
+
} else {
|
|
1067
|
+
observedRemoteInboundRtp.update(stats);
|
|
1068
|
+
}
|
|
1069
|
+
this.emit('updated-remote-inbound-rtp', observedRemoteInboundRtp);
|
|
1070
|
+
|
|
1071
|
+
return observedRemoteInboundRtp;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
private _updateRemoteOutboundRtpStats(stats: RemoteOutboundRtpStats) {
|
|
1075
|
+
let observedRemoteOutboundRtp = this.observedRemoteOutboundRtps.get(stats.ssrc);
|
|
1076
|
+
|
|
1077
|
+
if (!observedRemoteOutboundRtp) {
|
|
1078
|
+
if (!stats.timestamp || !stats.id || !stats.ssrc || !stats.kind) {
|
|
1079
|
+
return logger.warn(
|
|
1080
|
+
`ObservedPeerConnection received an invalid RemoteOutboundRtpStats (missing timestamp OR id OR ssrc OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`,
|
|
1081
|
+
stats
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
observedRemoteOutboundRtp = new ObservedRemoteOutboundRtp(
|
|
1086
|
+
stats.timestamp,
|
|
1087
|
+
stats.id,
|
|
1088
|
+
stats.ssrc,
|
|
1089
|
+
stats.kind as MediaKind,
|
|
1090
|
+
this
|
|
1091
|
+
);
|
|
1092
|
+
|
|
1093
|
+
observedRemoteOutboundRtp.update(stats);
|
|
1094
|
+
|
|
1095
|
+
this.observedRemoteOutboundRtps.set(stats.ssrc, observedRemoteOutboundRtp);
|
|
1096
|
+
this.emit('added-remote-outbound-rtp', observedRemoteOutboundRtp);
|
|
1097
|
+
} else {
|
|
1098
|
+
observedRemoteOutboundRtp.update(stats);
|
|
1099
|
+
}
|
|
1100
|
+
this.emit('updated-remote-outbound-rtp', observedRemoteOutboundRtp);
|
|
1101
|
+
|
|
1102
|
+
return observedRemoteOutboundRtp;
|
|
1103
|
+
}
|
|
1104
|
+
}
|