@observertc/observer-js 0.40.8-beta → 0.40.10-beta
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/lib/ObservedClient.d.ts +5 -1
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +3 -1
- package/lib/ObservedDataChannel.d.ts +5 -1
- package/lib/ObservedDataChannel.d.ts.map +1 -1
- package/lib/ObservedDataChannel.js +3 -1
- package/lib/ObservedICE.d.ts +17 -1
- package/lib/ObservedICE.d.ts.map +1 -1
- package/lib/ObservedICE.js +37 -2
- package/lib/ObservedInboundTrack.d.ts +5 -1
- package/lib/ObservedInboundTrack.d.ts.map +1 -1
- package/lib/ObservedInboundTrack.js +3 -1
- package/lib/ObservedOutboundTrack.d.ts +5 -1
- package/lib/ObservedOutboundTrack.d.ts.map +1 -1
- package/lib/ObservedOutboundTrack.js +3 -1
- package/lib/ObservedPeerConnection.d.ts +5 -1
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/ObservedPeerConnection.js +8 -4
- package/lib/ObservedSfu.d.ts +5 -1
- package/lib/ObservedSfu.d.ts.map +1 -1
- package/lib/ObservedSfu.js +6 -2
- package/lib/ObservedSfuInboundRtpPad.d.ts +5 -1
- package/lib/ObservedSfuInboundRtpPad.d.ts.map +1 -1
- package/lib/ObservedSfuInboundRtpPad.js +6 -2
- package/lib/ObservedSfuOutboundRtpPad.d.ts +5 -1
- package/lib/ObservedSfuOutboundRtpPad.d.ts.map +1 -1
- package/lib/ObservedSfuOutboundRtpPad.js +6 -2
- package/lib/ObservedSfuSctpChannel.d.ts +5 -1
- package/lib/ObservedSfuSctpChannel.d.ts.map +1 -1
- package/lib/ObservedSfuSctpChannel.js +6 -2
- package/lib/ObservedSfuTransport.d.ts +5 -1
- package/lib/ObservedSfuTransport.d.ts.map +1 -1
- package/lib/ObservedSfuTransport.js +6 -2
- package/lib/Observer.d.ts +7 -0
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +70 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/{CallSummary.d.ts → monitors/CallSummary.d.ts} +7 -1
- package/lib/monitors/CallSummary.d.ts.map +1 -0
- package/lib/monitors/CallSummaryMonitor.d.ts +25 -0
- package/lib/monitors/CallSummaryMonitor.d.ts.map +1 -0
- package/lib/monitors/CallSummaryMonitor.js +82 -0
- package/lib/monitors/TurnUsageMonitor.d.ts +37 -0
- package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -0
- package/lib/monitors/TurnUsageMonitor.js +80 -0
- package/package.json +3 -3
- package/src/ObservedClient.ts +7 -3
- package/src/ObservedDataChannel.ts +6 -2
- package/src/ObservedICE.ts +53 -4
- package/src/ObservedInboundTrack.ts +6 -2
- package/src/ObservedOutboundTrack.ts +6 -2
- package/src/ObservedPeerConnection.ts +13 -6
- package/src/ObservedSfu.ts +10 -3
- package/src/ObservedSfuInboundRtpPad.ts +9 -3
- package/src/ObservedSfuOutboundRtpPad.ts +9 -3
- package/src/ObservedSfuSctpChannel.ts +9 -3
- package/src/ObservedSfuTransport.ts +10 -4
- package/src/Observer.ts +86 -0
- package/src/index.ts +1 -0
- package/src/{CallSummary.ts → monitors/CallSummary.ts} +8 -2
- package/src/monitors/CallSummaryMonitor.ts +107 -0
- package/src/monitors/TurnUsageMonitor.ts +124 -0
- package/lib/CallSummary.d.ts.map +0 -1
- /package/lib/{CallSummary.js → monitors/CallSummary.js} +0 -0
package/lib/Observer.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { EventEmitter } from 'events';
|
|
|
5
5
|
import { PartialBy } from './common/utils';
|
|
6
6
|
import { ObserverSinkContext } from './common/types';
|
|
7
7
|
import { ObservedSfu, ObservedSfuModel } from './ObservedSfu';
|
|
8
|
+
import { CallSummaryMonitor } from './monitors/CallSummaryMonitor';
|
|
9
|
+
import { TurnUsageMonitor } from './monitors/TurnUsageMonitor';
|
|
8
10
|
export type ObserverEvents = {
|
|
9
11
|
'newcall': [ObservedCall];
|
|
10
12
|
'newsfu': [ObservedSfu];
|
|
@@ -42,6 +44,7 @@ export declare class Observer extends EventEmitter {
|
|
|
42
44
|
readonly reports: ReportsCollector;
|
|
43
45
|
private readonly _observedCalls;
|
|
44
46
|
private readonly _observedSfus;
|
|
47
|
+
private readonly _monitors;
|
|
45
48
|
private _reportTimer?;
|
|
46
49
|
private _closed;
|
|
47
50
|
constructor(config: ObserverConfig);
|
|
@@ -50,6 +53,10 @@ export declare class Observer extends EventEmitter {
|
|
|
50
53
|
started?: number;
|
|
51
54
|
}): ObservedCall<T>;
|
|
52
55
|
createObservedSfu<AppData extends Record<string, unknown> = Record<string, unknown>>(model: ObservedSfuModel, appData: AppData): ObservedSfu<AppData>;
|
|
56
|
+
createCallSummaryMonitor(options?: {
|
|
57
|
+
timeoutAfterCallClose?: number;
|
|
58
|
+
}): CallSummaryMonitor;
|
|
59
|
+
createTurnUsageMonitor(): TurnUsageMonitor;
|
|
53
60
|
get observedCalls(): ReadonlyMap<string, ObservedCall>;
|
|
54
61
|
get observedSfus(): ReadonlyMap<string, ObservedSfu>;
|
|
55
62
|
get closed(): boolean;
|
package/lib/Observer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Observer.d.ts","sourceRoot":"","sources":["../src/Observer.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"Observer.d.ts","sourceRoot":"","sources":["../src/Observer.ts"],"names":[],"mappings":"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"}
|
package/lib/Observer.js
CHANGED
|
@@ -18,6 +18,8 @@ const ReportsCollector_1 = require("./ReportsCollector");
|
|
|
18
18
|
const events_1 = require("events");
|
|
19
19
|
const callEventReports_1 = require("./common/callEventReports");
|
|
20
20
|
const ObservedSfu_1 = require("./ObservedSfu");
|
|
21
|
+
const CallSummaryMonitor_1 = require("./monitors/CallSummaryMonitor");
|
|
22
|
+
const TurnUsageMonitor_1 = require("./monitors/TurnUsageMonitor");
|
|
21
23
|
const logger = (0, logger_1.createLogger)('Observer');
|
|
22
24
|
class Observer extends events_1.EventEmitter {
|
|
23
25
|
static create(providedConfig) {
|
|
@@ -39,6 +41,7 @@ class Observer extends events_1.EventEmitter {
|
|
|
39
41
|
this.reports = new ReportsCollector_1.ReportsCollector();
|
|
40
42
|
this._observedCalls = new Map();
|
|
41
43
|
this._observedSfus = new Map();
|
|
44
|
+
this._monitors = new Map();
|
|
42
45
|
this._closed = false;
|
|
43
46
|
this.setMaxListeners(Infinity);
|
|
44
47
|
logger.debug('Observer is created with config', this.config);
|
|
@@ -93,6 +96,73 @@ class Observer extends events_1.EventEmitter {
|
|
|
93
96
|
this.emit('newsfu', sfu);
|
|
94
97
|
return sfu;
|
|
95
98
|
}
|
|
99
|
+
createCallSummaryMonitor(options) {
|
|
100
|
+
if (this._closed)
|
|
101
|
+
throw new Error('Cannot create a call summary monitor on a closed observer');
|
|
102
|
+
const existingMonitor = this._monitors.get(CallSummaryMonitor_1.CallSummaryMonitor.name);
|
|
103
|
+
if (existingMonitor)
|
|
104
|
+
return existingMonitor;
|
|
105
|
+
const monitor = new CallSummaryMonitor_1.CallSummaryMonitor();
|
|
106
|
+
const onNewCall = (call) => {
|
|
107
|
+
monitor.addCall(call);
|
|
108
|
+
call.once('close', () => {
|
|
109
|
+
var _a;
|
|
110
|
+
return setTimeout(() => {
|
|
111
|
+
const summary = monitor.takeSummary(call.callId);
|
|
112
|
+
summary && monitor.emit('summary', summary);
|
|
113
|
+
}, (_a = options === null || options === void 0 ? void 0 : options.timeoutAfterCallClose) !== null && _a !== void 0 ? _a : 1000);
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
monitor.once('close', () => {
|
|
117
|
+
this._monitors.delete(CallSummaryMonitor_1.CallSummaryMonitor.name);
|
|
118
|
+
this.off('newcall', onNewCall);
|
|
119
|
+
});
|
|
120
|
+
this._monitors.set(CallSummaryMonitor_1.CallSummaryMonitor.name, monitor);
|
|
121
|
+
this.on('newcall', onNewCall);
|
|
122
|
+
this.once('close', () => {
|
|
123
|
+
monitor.close();
|
|
124
|
+
});
|
|
125
|
+
return monitor;
|
|
126
|
+
}
|
|
127
|
+
createTurnUsageMonitor() {
|
|
128
|
+
if (this._closed)
|
|
129
|
+
throw new Error('Cannot create a turn usage monitor on a closed observer');
|
|
130
|
+
const existingMonitor = this._monitors.get(TurnUsageMonitor_1.TurnUsageMonitor.name);
|
|
131
|
+
if (existingMonitor)
|
|
132
|
+
return existingMonitor;
|
|
133
|
+
const monitor = new TurnUsageMonitor_1.TurnUsageMonitor();
|
|
134
|
+
const onNewCall = (call) => {
|
|
135
|
+
const onNewClient = (client) => {
|
|
136
|
+
const onNewPeerConnection = (pc) => {
|
|
137
|
+
const onUsingTurnChanged = (usingTurn) => {
|
|
138
|
+
if (usingTurn)
|
|
139
|
+
monitor.addPeerConnection(pc);
|
|
140
|
+
else
|
|
141
|
+
monitor.removePeerConnection(pc);
|
|
142
|
+
};
|
|
143
|
+
pc.once('close', () => {
|
|
144
|
+
pc.ICE.off('usingturnchanged', onUsingTurnChanged);
|
|
145
|
+
monitor.removePeerConnection(pc);
|
|
146
|
+
});
|
|
147
|
+
pc.ICE.on('usingturnchanged', onUsingTurnChanged);
|
|
148
|
+
};
|
|
149
|
+
client.once('close', () => client.off('newpeerconnection', onNewPeerConnection));
|
|
150
|
+
client.on('newpeerconnection', onNewPeerConnection);
|
|
151
|
+
};
|
|
152
|
+
call.once('close', () => call.off('newclient', onNewClient));
|
|
153
|
+
call.on('newclient', onNewClient);
|
|
154
|
+
};
|
|
155
|
+
monitor.once('close', () => {
|
|
156
|
+
this._monitors.delete(CallSummaryMonitor_1.CallSummaryMonitor.name);
|
|
157
|
+
this.off('newcall', onNewCall);
|
|
158
|
+
});
|
|
159
|
+
this._monitors.set(CallSummaryMonitor_1.CallSummaryMonitor.name, monitor);
|
|
160
|
+
this.on('newcall', onNewCall);
|
|
161
|
+
this.once('close', () => {
|
|
162
|
+
monitor.close();
|
|
163
|
+
});
|
|
164
|
+
return monitor;
|
|
165
|
+
}
|
|
96
166
|
get observedCalls() {
|
|
97
167
|
return this._observedCalls;
|
|
98
168
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * as ReportSchema from '@observertc/report-schemas-js';
|
|
|
5
5
|
export type { LogLevel, Logger } from './common/logger';
|
|
6
6
|
export type { Samples, ClientSample, SfuSample, ExtensionStat, PeerConnectionTransport, IceCandidatePair, MediaSourceStat, MediaCodecStats, InboundAudioTrack, InboundVideoTrack, OutboundAudioTrack, OutboundVideoTrack, IceLocalCandidate, IceRemoteCandidate, CustomCallEvent, SfuTransport, SfuInboundRtpPad, SfuOutboundRtpPad, SfuSctpChannel, SfuExtensionStats, DataChannel, } from '@observertc/sample-schemas-js';
|
|
7
7
|
export type { CallEventReport, CallMetaReport, ClientDataChannelReport, ClientExtensionReport, IceCandidatePairReport, InboundAudioTrackReport, InboundVideoTrackReport, ObserverEventReport, OutboundAudioTrackReport, OutboundVideoTrackReport, PeerConnectionTransportReport, SfuEventReport, SfuExtensionReport, SfuInboundRtpPadReport, SfuMetaReport, SfuOutboundRtpPadReport, SfuSctpStreamReport, SFUTransportReport, } from '@observertc/report-schemas-js';
|
|
8
|
+
export type { ObservedCall, ObservedCallModel } from './ObservedCall';
|
|
8
9
|
export type { ObservedClient, ObservedClientModel } from './ObservedClient';
|
|
9
10
|
export type { ObservedPeerConnection, ObservedPeerConnectionModel, ObservedPeerConnectionEvents } from './ObservedPeerConnection';
|
|
10
11
|
export type { ObservedInboundTrack, ObservedInboundTrackModel, ObservedInboundTrackEvents } from './ObservedInboundTrack';
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAC;AAE9D,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAExD,YAAY,EACX,OAAO,EACP,YAAY,EACZ,SAAS,EACT,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,WAAW,GACX,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EACX,eAAe,EACf,cAAc,EACd,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAClI,YAAY,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAC1H,YAAY,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE9H,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACtD,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,YAE9D;AAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAA8B,MAAM,iBAAiB,CAAC;AAC/E,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAG3D"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAC;AAE9D,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAExD,YAAY,EACX,OAAO,EACP,YAAY,EACZ,SAAS,EACT,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,WAAW,GACX,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EACX,eAAe,EACf,cAAc,EACd,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAClI,YAAY,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAC1H,YAAY,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE9H,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACtD,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,YAE9D;AAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAA8B,MAAM,iBAAiB,CAAC;AAC/E,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAG3D"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
export interface ClientSummary {
|
|
2
2
|
clientId: string;
|
|
3
|
-
|
|
3
|
+
mediaUnitId: string;
|
|
4
|
+
userId?: string;
|
|
4
5
|
joined: number;
|
|
5
6
|
durationInMs: number;
|
|
7
|
+
avgOutboundAudioBitrate: number;
|
|
8
|
+
avgOutboundVideoBitrate: number;
|
|
9
|
+
avgInboundAudioBitrate: number;
|
|
10
|
+
avgInboundVideoBitrate: number;
|
|
11
|
+
ewmaRttInMs: number;
|
|
6
12
|
}
|
|
7
13
|
export interface CallSummary {
|
|
8
14
|
serviceId: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallSummary.d.ts","sourceRoot":"","sources":["../../src/monitors/CallSummary.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,CAAC;IAChC,uBAAuB,EAAE,MAAM,CAAC;IAChC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,aAAa,EAAE,CAAC;CACzB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { CallSummary } from './CallSummary';
|
|
4
|
+
import { ObservedCall } from '../ObservedCall';
|
|
5
|
+
export type CallSummaryMonitorEvents = {
|
|
6
|
+
close: [];
|
|
7
|
+
summary: [CallSummary];
|
|
8
|
+
};
|
|
9
|
+
export declare interface CallSummaryMonitor {
|
|
10
|
+
on<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
|
|
11
|
+
off<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
|
|
12
|
+
once<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
|
|
13
|
+
emit<U extends keyof CallSummaryMonitorEvents>(event: U, ...args: CallSummaryMonitorEvents[U]): boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare class CallSummaryMonitor extends EventEmitter {
|
|
16
|
+
private readonly _summaries;
|
|
17
|
+
private _closed;
|
|
18
|
+
constructor();
|
|
19
|
+
addCall(call: ObservedCall): void;
|
|
20
|
+
private _addClient;
|
|
21
|
+
takeSummary(callId: string): CallSummary | undefined;
|
|
22
|
+
get closed(): boolean;
|
|
23
|
+
close(): void;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=CallSummaryMonitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallSummaryMonitor.d.ts","sourceRoot":"","sources":["../../src/monitors/CallSummaryMonitor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC;CACvB,CAAA;AAED,MAAM,CAAC,OAAO,WAAW,kBAAkB;IAC1C,EAAE,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvH,GAAG,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACxH,IAAI,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACzH,IAAI,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACxG;AAED,qBAAa,kBAAmB,SAAQ,YAAY;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAE7D,OAAO,CAAC,OAAO,CAAS;;IAKjB,OAAO,CAAC,IAAI,EAAE,YAAY;IAyBjC,OAAO,CAAC,UAAU;IAoCX,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAU3D,IAAW,MAAM,YAEhB;IAEM,KAAK;CAMZ"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CallSummaryMonitor = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
class CallSummaryMonitor extends events_1.EventEmitter {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this._summaries = new Map();
|
|
9
|
+
this._closed = false;
|
|
10
|
+
}
|
|
11
|
+
addCall(call) {
|
|
12
|
+
if (this.closed)
|
|
13
|
+
return;
|
|
14
|
+
let callSummary = this._summaries.get(call.callId);
|
|
15
|
+
if (!callSummary) {
|
|
16
|
+
callSummary = {
|
|
17
|
+
callId: call.callId,
|
|
18
|
+
roomId: call.roomId,
|
|
19
|
+
serviceId: call.serviceId,
|
|
20
|
+
clients: [],
|
|
21
|
+
durationInMs: 0,
|
|
22
|
+
started: call.created,
|
|
23
|
+
};
|
|
24
|
+
this._summaries.set(call.callId, callSummary);
|
|
25
|
+
}
|
|
26
|
+
const constCallSummary = callSummary;
|
|
27
|
+
const onNewClient = (client) => this._addClient(constCallSummary, client);
|
|
28
|
+
call.once('close', () => {
|
|
29
|
+
call.off('newclient', onNewClient);
|
|
30
|
+
});
|
|
31
|
+
call.on('newclient', onNewClient);
|
|
32
|
+
}
|
|
33
|
+
_addClient(callSummary, client) {
|
|
34
|
+
if (this.closed)
|
|
35
|
+
return;
|
|
36
|
+
const clientSummary = {
|
|
37
|
+
clientId: client.clientId,
|
|
38
|
+
mediaUnitId: client.mediaUnitId,
|
|
39
|
+
durationInMs: 0,
|
|
40
|
+
avgInboundAudioBitrate: 0,
|
|
41
|
+
avgInboundVideoBitrate: 0,
|
|
42
|
+
avgOutboundAudioBitrate: 0,
|
|
43
|
+
avgOutboundVideoBitrate: 0,
|
|
44
|
+
ewmaRttInMs: 0,
|
|
45
|
+
joined: client.created,
|
|
46
|
+
userId: client.userId,
|
|
47
|
+
};
|
|
48
|
+
callSummary.clients.push(clientSummary);
|
|
49
|
+
const updateClient = () => {
|
|
50
|
+
if (client.avgRttInMs) {
|
|
51
|
+
clientSummary.ewmaRttInMs = (clientSummary.ewmaRttInMs * 0.9) + (client.avgRttInMs * 0.1);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
client.on('update', updateClient);
|
|
55
|
+
client.once('close', () => {
|
|
56
|
+
const elapsedTimeInS = (Date.now() - client.created) / 1000;
|
|
57
|
+
clientSummary.avgInboundAudioBitrate = (client.totalReceivedBytes * 8) / elapsedTimeInS;
|
|
58
|
+
clientSummary.avgInboundVideoBitrate = (client.totalReceivedBytes * 8) / elapsedTimeInS;
|
|
59
|
+
clientSummary.avgOutboundAudioBitrate = (client.totalSentBytes * 8) / elapsedTimeInS;
|
|
60
|
+
clientSummary.avgOutboundVideoBitrate = (client.totalSentBytes * 8) / elapsedTimeInS;
|
|
61
|
+
clientSummary.durationInMs = elapsedTimeInS * 1000;
|
|
62
|
+
client.off('update', updateClient);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
takeSummary(callId) {
|
|
66
|
+
if (this.closed)
|
|
67
|
+
return;
|
|
68
|
+
const summary = this._summaries.get(callId);
|
|
69
|
+
this._summaries.delete(callId);
|
|
70
|
+
return summary;
|
|
71
|
+
}
|
|
72
|
+
get closed() {
|
|
73
|
+
return this._closed;
|
|
74
|
+
}
|
|
75
|
+
close() {
|
|
76
|
+
if (this._closed)
|
|
77
|
+
return;
|
|
78
|
+
this._closed = true;
|
|
79
|
+
this.emit('close');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.CallSummaryMonitor = CallSummaryMonitor;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { ObservedPeerConnection } from '../ObservedPeerConnection';
|
|
4
|
+
export type TurnUsageMonitorEvents = {
|
|
5
|
+
close: [];
|
|
6
|
+
'newturnip': [string];
|
|
7
|
+
update: [TurnUsage];
|
|
8
|
+
addpeerconnection: [ObservedPeerConnection];
|
|
9
|
+
removepeerconnection: [ObservedPeerConnection];
|
|
10
|
+
};
|
|
11
|
+
export type TurnUsage = {
|
|
12
|
+
turnIp: string;
|
|
13
|
+
totalBytesSent: number;
|
|
14
|
+
totalBytesReceived: number;
|
|
15
|
+
totalPacketsSent: number;
|
|
16
|
+
totalPacketsReceived: number;
|
|
17
|
+
};
|
|
18
|
+
export declare interface TurnUsageMonitor {
|
|
19
|
+
on<U extends keyof TurnUsageMonitorEvents>(event: U, listener: (...args: TurnUsageMonitorEvents[U]) => void): this;
|
|
20
|
+
off<U extends keyof TurnUsageMonitorEvents>(event: U, listener: (...args: TurnUsageMonitorEvents[U]) => void): this;
|
|
21
|
+
once<U extends keyof TurnUsageMonitorEvents>(event: U, listener: (...args: TurnUsageMonitorEvents[U]) => void): this;
|
|
22
|
+
emit<U extends keyof TurnUsageMonitorEvents>(event: U, ...args: TurnUsageMonitorEvents[U]): boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare class TurnUsageMonitor extends EventEmitter {
|
|
25
|
+
private readonly _connections;
|
|
26
|
+
private readonly _turnUsage;
|
|
27
|
+
private _closed;
|
|
28
|
+
constructor();
|
|
29
|
+
addPeerConnection(peerConnection: ObservedPeerConnection): void;
|
|
30
|
+
removePeerConnection(peerConnection: ObservedPeerConnection): void;
|
|
31
|
+
get turnIps(): string[];
|
|
32
|
+
get peerConnections(): ObservedPeerConnection[];
|
|
33
|
+
getUsage(turnIp: string): TurnUsage | undefined;
|
|
34
|
+
get closed(): boolean;
|
|
35
|
+
close(): void;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=TurnUsageMonitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TurnUsageMonitor.d.ts","sourceRoot":"","sources":["../../src/monitors/TurnUsageMonitor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,MAAM,MAAM,sBAAsB,GAAG;IACpC,KAAK,EAAE,EAAE,CAAC;IACV,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;IACpB,iBAAiB,EAAE,CAAC,sBAAsB,CAAC,CAAC;IAC5C,oBAAoB,EAAE,CAAC,sBAAsB,CAAC,CAAC;CAC/C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;CAC7B,CAAA;AAQD,MAAM,CAAC,OAAO,WAAW,gBAAgB;IACxC,EAAE,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACnH,GAAG,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACpH,IAAI,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACrH,IAAI,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACpG;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;IACtE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAE3D,OAAO,CAAC,OAAO,CAAS;;IAKjB,iBAAiB,CAAC,cAAc,EAAE,sBAAsB;IA4CxD,oBAAoB,CAAC,cAAc,EAAE,sBAAsB;IAelE,IAAW,OAAO,aAEjB;IAED,IAAW,eAAe,6BAEzB;IAEM,QAAQ,CAAC,MAAM,EAAE,MAAM;IAI9B,IAAW,MAAM,YAEhB;IAEM,KAAK;CAMZ"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TurnUsageMonitor = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
class TurnUsageMonitor extends events_1.EventEmitter {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this._connections = new Map();
|
|
9
|
+
this._turnUsage = new Map();
|
|
10
|
+
this._closed = false;
|
|
11
|
+
}
|
|
12
|
+
addPeerConnection(peerConnection) {
|
|
13
|
+
if (this.closed)
|
|
14
|
+
return;
|
|
15
|
+
if (this._connections.has(peerConnection.peerConnectionId))
|
|
16
|
+
return;
|
|
17
|
+
const ice = peerConnection.ICE;
|
|
18
|
+
const onUpdate = () => {
|
|
19
|
+
var _a;
|
|
20
|
+
const turnIp = (_a = ice === null || ice === void 0 ? void 0 : ice.selectedRemoteCandidate) === null || _a === void 0 ? void 0 : _a.address;
|
|
21
|
+
if (!peerConnection.usingTURN || !turnIp)
|
|
22
|
+
return;
|
|
23
|
+
let usage = this._turnUsage.get(turnIp);
|
|
24
|
+
if (!usage) {
|
|
25
|
+
usage = {
|
|
26
|
+
turnIp,
|
|
27
|
+
totalBytesSent: 0,
|
|
28
|
+
totalBytesReceived: 0,
|
|
29
|
+
totalPacketsSent: 0,
|
|
30
|
+
totalPacketsReceived: 0,
|
|
31
|
+
};
|
|
32
|
+
this._turnUsage.set(turnIp, usage);
|
|
33
|
+
this.emit('newturnip', turnIp);
|
|
34
|
+
}
|
|
35
|
+
usage.totalBytesSent += ice.deltaBytesSent;
|
|
36
|
+
usage.totalBytesReceived += ice.deltaBytesReceived;
|
|
37
|
+
usage.totalPacketsSent += ice.deltaPacketsSent;
|
|
38
|
+
usage.totalPacketsReceived += ice.deltaPacketsReceived;
|
|
39
|
+
this.emit('update', usage);
|
|
40
|
+
};
|
|
41
|
+
peerConnection.ICE.on('update', onUpdate);
|
|
42
|
+
this._connections.set(peerConnection.peerConnectionId, {
|
|
43
|
+
peerConnection,
|
|
44
|
+
onUpdate
|
|
45
|
+
});
|
|
46
|
+
this.emit('addpeerconnection', peerConnection);
|
|
47
|
+
}
|
|
48
|
+
removePeerConnection(peerConnection) {
|
|
49
|
+
var _a;
|
|
50
|
+
if (this.closed)
|
|
51
|
+
return;
|
|
52
|
+
if (!this._connections.has(peerConnection.peerConnectionId))
|
|
53
|
+
return;
|
|
54
|
+
const { onUpdate } = (_a = this._connections.get(peerConnection.peerConnectionId)) !== null && _a !== void 0 ? _a : {};
|
|
55
|
+
if (!onUpdate)
|
|
56
|
+
return;
|
|
57
|
+
peerConnection.ICE.off('update', onUpdate);
|
|
58
|
+
this._connections.delete(peerConnection.peerConnectionId);
|
|
59
|
+
this.emit('removepeerconnection', peerConnection);
|
|
60
|
+
}
|
|
61
|
+
get turnIps() {
|
|
62
|
+
return Array.from(this._turnUsage.keys());
|
|
63
|
+
}
|
|
64
|
+
get peerConnections() {
|
|
65
|
+
return Array.from(this._connections.values()).map(({ peerConnection }) => peerConnection);
|
|
66
|
+
}
|
|
67
|
+
getUsage(turnIp) {
|
|
68
|
+
return this._turnUsage.get(turnIp);
|
|
69
|
+
}
|
|
70
|
+
get closed() {
|
|
71
|
+
return this._closed;
|
|
72
|
+
}
|
|
73
|
+
close() {
|
|
74
|
+
if (this._closed)
|
|
75
|
+
return;
|
|
76
|
+
this._closed = true;
|
|
77
|
+
this.emit('close');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.TurnUsageMonitor = TurnUsageMonitor;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@observertc/observer-js",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.10-beta",
|
|
4
4
|
"description": "Server Side NodeJS Library for processing ObserveRTC Samples",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"uuid": "^8.3.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
+
"@types/events": "^3.0.0",
|
|
34
35
|
"@types/jest": "^27.5.2",
|
|
35
36
|
"@types/node": "^20.9.0",
|
|
37
|
+
"@types/uuid": "^8.3.4",
|
|
36
38
|
"@typescript-eslint/eslint-plugin": "^5.38.0",
|
|
37
39
|
"@typescript-eslint/parser": "^5.38.0",
|
|
38
|
-
"@types/events": "^3.0.0",
|
|
39
|
-
"@types/uuid": "^8.3.4",
|
|
40
40
|
"bufferutil": "^4.0.6",
|
|
41
41
|
"eslint": "^8.24.0",
|
|
42
42
|
"jest": "^27.5.0",
|
package/src/ObservedClient.ts
CHANGED
|
@@ -24,7 +24,9 @@ export type ObservedClientModel= {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export type ObservedClientEvents = {
|
|
27
|
-
update: [
|
|
27
|
+
update: [{
|
|
28
|
+
elapsedTimeInMs: number,
|
|
29
|
+
}],
|
|
28
30
|
close: [],
|
|
29
31
|
newpeerconnection: [ObservedPeerConnection],
|
|
30
32
|
iceconnectionstatechange: [{
|
|
@@ -758,9 +760,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
758
760
|
this.inboundVideoBitrate = (this.deltaReceivedVideoBytes * 8) / (Math.max(elapsedTimeInMs, 1) / 1000);
|
|
759
761
|
|
|
760
762
|
this.avgRttInMs = this._peerConnections.size ? sumRttInMs / this._peerConnections.size : undefined;
|
|
761
|
-
|
|
763
|
+
|
|
762
764
|
this._updated = now;
|
|
763
|
-
this.emit('update'
|
|
765
|
+
this.emit('update', {
|
|
766
|
+
elapsedTimeInMs,
|
|
767
|
+
});
|
|
764
768
|
}
|
|
765
769
|
|
|
766
770
|
private _createPeerConnection(peerConnectionId: string, label?: string): ObservedPeerConnection {
|
|
@@ -10,7 +10,9 @@ export type ObservedDataChannelModel = {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export type ObservedDataChannelEvents = {
|
|
13
|
-
update: [
|
|
13
|
+
update: [{
|
|
14
|
+
elapsedTimeInMs: number;
|
|
15
|
+
}],
|
|
14
16
|
close: [],
|
|
15
17
|
};
|
|
16
18
|
|
|
@@ -184,6 +186,8 @@ export class ObservedDataChannel extends EventEmitter {
|
|
|
184
186
|
|
|
185
187
|
this._stats = sample;
|
|
186
188
|
this._updated = timestamp;
|
|
187
|
-
this.emit('update'
|
|
189
|
+
this.emit('update', {
|
|
190
|
+
elapsedTimeInMs,
|
|
191
|
+
});
|
|
188
192
|
}
|
|
189
193
|
}
|
package/src/ObservedICE.ts
CHANGED
|
@@ -5,13 +5,16 @@ import { IceCandidatePairReport } from '@observertc/report-schemas-js';
|
|
|
5
5
|
import { CallMetaType, createCallMetaReport } from './common/callMetaReports';
|
|
6
6
|
|
|
7
7
|
export type ObservedICEEvents = {
|
|
8
|
-
update: [
|
|
8
|
+
update: [{
|
|
9
|
+
elapsedTimeInMs: number;
|
|
10
|
+
}],
|
|
9
11
|
'new-local-candidate': [IceLocalCandidate],
|
|
10
12
|
'new-remote-candidate': [IceRemoteCandidate],
|
|
11
13
|
'new-selected-candidate-pair': [{
|
|
12
14
|
localCandidate: IceLocalCandidate,
|
|
13
15
|
remoteCandidate: IceRemoteCandidate,
|
|
14
16
|
}],
|
|
17
|
+
usingturnchanged: [boolean],
|
|
15
18
|
close: [],
|
|
16
19
|
};
|
|
17
20
|
|
|
@@ -32,6 +35,20 @@ export class ObservedICE extends EventEmitter {
|
|
|
32
35
|
private readonly _localCandidates = new Map<string, IceLocalCandidate>();
|
|
33
36
|
private readonly _remoteCandidates = new Map<string, IceLocalCandidate>();
|
|
34
37
|
|
|
38
|
+
public usingTURN = false;
|
|
39
|
+
|
|
40
|
+
public deltaBytesReceived = 0;
|
|
41
|
+
public deltaBytesSent = 0;
|
|
42
|
+
public deltaPacketsReceived = 0;
|
|
43
|
+
public deltaPacketsSent = 0;
|
|
44
|
+
|
|
45
|
+
public totalBytesReceived = 0;
|
|
46
|
+
public totalBytesSent = 0;
|
|
47
|
+
public totalPacketsReceived = 0;
|
|
48
|
+
public totalPacketsSent = 0;
|
|
49
|
+
|
|
50
|
+
public currentRttInMs?: number;
|
|
51
|
+
|
|
35
52
|
private _selectedLocalCandidateId?: string;
|
|
36
53
|
private _selectedRemoteCandidateId?: string;
|
|
37
54
|
private _updated = Date.now();
|
|
@@ -131,8 +148,18 @@ export class ObservedICE extends EventEmitter {
|
|
|
131
148
|
}
|
|
132
149
|
}
|
|
133
150
|
|
|
134
|
-
public
|
|
151
|
+
public resetMetrics() {
|
|
152
|
+
this.deltaBytesReceived = 0;
|
|
153
|
+
this.deltaBytesSent = 0;
|
|
154
|
+
this.deltaPacketsReceived = 0;
|
|
155
|
+
this.deltaPacketsSent = 0;
|
|
135
156
|
|
|
157
|
+
this.currentRttInMs = undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public update(candidatePair: IceCandidatePair, timestamp: number) {
|
|
161
|
+
const now = Date.now();
|
|
162
|
+
const elapsedTimeInMs = now - this._updated;
|
|
136
163
|
const report: IceCandidatePairReport = {
|
|
137
164
|
serviceId: this.peerConnection.client.serviceId,
|
|
138
165
|
mediaUnitId: this.peerConnection.client.mediaUnitId,
|
|
@@ -149,6 +176,18 @@ export class ObservedICE extends EventEmitter {
|
|
|
149
176
|
this.reports.addIceCandidatePairReport(report);
|
|
150
177
|
|
|
151
178
|
if (!candidatePair.nominated) return;
|
|
179
|
+
|
|
180
|
+
this.deltaBytesReceived = (candidatePair.bytesReceived ?? 0) - (this._stats?.bytesReceived ?? 0);
|
|
181
|
+
this.deltaBytesSent = (candidatePair.bytesSent ?? 0) - (this._stats?.bytesSent ?? 0);
|
|
182
|
+
this.deltaPacketsReceived = (candidatePair.packetsReceived ?? 0) - (this._stats?.packetsReceived ?? 0);
|
|
183
|
+
this.deltaPacketsSent = (candidatePair.packetsSent ?? 0) - (this._stats?.packetsSent ?? 0);
|
|
184
|
+
|
|
185
|
+
this.totalBytesReceived += this.deltaBytesReceived;
|
|
186
|
+
this.totalBytesSent += this.deltaBytesSent;
|
|
187
|
+
this.totalPacketsReceived += this.deltaPacketsReceived;
|
|
188
|
+
this.totalPacketsSent += this.deltaPacketsSent;
|
|
189
|
+
|
|
190
|
+
this.currentRttInMs = candidatePair.currentRoundTripTime ? candidatePair.currentRoundTripTime * 1000 : undefined;
|
|
152
191
|
|
|
153
192
|
this._stats = candidatePair;
|
|
154
193
|
|
|
@@ -167,14 +206,24 @@ export class ObservedICE extends EventEmitter {
|
|
|
167
206
|
const remoteCandidate = this._remoteCandidates.get(candidatePair.remoteCandidateId);
|
|
168
207
|
|
|
169
208
|
if (localCandidate && remoteCandidate) {
|
|
209
|
+
const wasUsingTURN = this.usingTURN;
|
|
210
|
+
|
|
211
|
+
this.usingTURN = remoteCandidate.candidateType?.toLocaleLowerCase() === 'relay';
|
|
212
|
+
|
|
170
213
|
this.emit('new-selected-candidate-pair', {
|
|
171
214
|
localCandidate,
|
|
172
215
|
remoteCandidate,
|
|
173
216
|
});
|
|
217
|
+
|
|
218
|
+
if (wasUsingTURN !== this.usingTURN) {
|
|
219
|
+
this.emit('usingturnchanged', this.usingTURN);
|
|
220
|
+
}
|
|
174
221
|
}
|
|
175
222
|
}
|
|
176
223
|
|
|
177
|
-
this._updated =
|
|
178
|
-
this.emit('update'
|
|
224
|
+
this._updated = now;
|
|
225
|
+
this.emit('update', {
|
|
226
|
+
elapsedTimeInMs,
|
|
227
|
+
});
|
|
179
228
|
}
|
|
180
229
|
}
|
|
@@ -13,7 +13,9 @@ export type ObservedInboundTrackModel<K extends MediaKind> = {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export type ObservedInboundTrackEvents<K extends MediaKind> = {
|
|
16
|
-
update: [
|
|
16
|
+
update: [{
|
|
17
|
+
elapsedTimeInMs: number;
|
|
18
|
+
}],
|
|
17
19
|
close: [],
|
|
18
20
|
remoteoutboundtrack: [ObservedOutboundTrack<K>],
|
|
19
21
|
};
|
|
@@ -272,7 +274,9 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
|
|
|
272
274
|
this._stats.set(sample.ssrc, stats);
|
|
273
275
|
|
|
274
276
|
this._updated = now;
|
|
275
|
-
this.emit('update'
|
|
277
|
+
this.emit('update', {
|
|
278
|
+
elapsedTimeInMs,
|
|
279
|
+
});
|
|
276
280
|
}
|
|
277
281
|
|
|
278
282
|
public updateMetrics() {
|
|
@@ -12,7 +12,9 @@ export type ObservedOutboundTrackModel<K extends MediaKind> = {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export type ObservedOutboundTrackEvents = {
|
|
15
|
-
update: [
|
|
15
|
+
update: [{
|
|
16
|
+
elapsedTimeInMs: number;
|
|
17
|
+
}],
|
|
16
18
|
close: [],
|
|
17
19
|
};
|
|
18
20
|
|
|
@@ -242,7 +244,9 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
this._updated = now;
|
|
245
|
-
this.emit('update'
|
|
247
|
+
this.emit('update', {
|
|
248
|
+
elapsedTimeInMs,
|
|
249
|
+
});
|
|
246
250
|
}
|
|
247
251
|
|
|
248
252
|
public connectInboundTrack(track: ObservedInboundTrack<Kind>) {
|