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