@observertc/observer-js 0.40.10-beta → 0.40.12
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/README.md +52 -24
- package/lib/ObservedClient.d.ts +9 -0
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +19 -8
- package/lib/ObservedICE.d.ts +2 -2
- package/lib/ObservedICE.d.ts.map +1 -1
- package/lib/ObservedICE.js +4 -4
- package/lib/ObservedOutboundTrack.d.ts +1 -0
- package/lib/ObservedOutboundTrack.d.ts.map +1 -1
- package/lib/ObservedOutboundTrack.js +7 -0
- package/lib/ObservedSfu.d.ts.map +1 -1
- package/lib/ObservedSfu.js +1 -0
- package/lib/Observer.d.ts +4 -2
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +4 -4
- package/lib/common/CallEventType.d.ts +2 -1
- package/lib/common/CallEventType.d.ts.map +1 -1
- package/lib/common/CallEventType.js +2 -1
- package/lib/common/callMetaReports.d.ts +1 -1
- package/lib/common/callMetaReports.d.ts.map +1 -1
- package/lib/common/callMetaReports.js +1 -1
- package/lib/monitors/CallSummary.d.ts +4 -0
- package/lib/monitors/CallSummary.d.ts.map +1 -1
- package/lib/monitors/CallSummaryMonitor.d.ts +8 -1
- package/lib/monitors/CallSummaryMonitor.d.ts.map +1 -1
- package/lib/monitors/CallSummaryMonitor.js +55 -1
- package/lib/monitors/TurnUsageMonitor.d.ts +2 -0
- package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -1
- package/lib/monitors/TurnUsageMonitor.js +9 -0
- package/package.json +1 -1
- package/src/ObservedClient.ts +60 -10
- package/src/ObservedICE.ts +12 -4
- package/src/ObservedOutboundTrack.ts +9 -0
- package/src/ObservedSfu.ts +2 -0
- package/src/Observer.ts +13 -7
- package/src/common/CallEventType.ts +1 -1
- package/src/common/callMetaReports.ts +1 -0
- package/src/monitors/CallSummary.ts +5 -0
- package/src/monitors/CallSummaryMonitor.ts +76 -4
- package/src/monitors/TurnUsageMonitor.ts +13 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Server side component for monitoring WebRTC
|
|
1
|
+
Server side component for monitoring WebRTC applications and services
|
|
2
2
|
---
|
|
3
3
|
|
|
4
4
|
Table of Contents:
|
|
@@ -6,9 +6,7 @@ Table of Contents:
|
|
|
6
6
|
* [Quick Start](#quick-start)
|
|
7
7
|
* [Configurations](#configurations)
|
|
8
8
|
* [NPM package](#npm-package)
|
|
9
|
-
* [API docs](#api-docs)
|
|
10
9
|
* [Schemas](#schemas)
|
|
11
|
-
* [Getting Involved](#getting-involved)
|
|
12
10
|
* [License](#license)
|
|
13
11
|
|
|
14
12
|
## Qucik Start
|
|
@@ -25,29 +23,23 @@ Use it in your server side NodeJS app.
|
|
|
25
23
|
import { createObserver, ClientSample } from "@observertc/observer-js";
|
|
26
24
|
|
|
27
25
|
const observer = createObserver({
|
|
28
|
-
|
|
26
|
+
defaultServiceId: 'my-service-name',
|
|
27
|
+
defaultMediaUnitId: 'my-reporting-component',
|
|
29
28
|
});
|
|
30
29
|
|
|
31
|
-
const
|
|
30
|
+
const observedCall = observer.createObservedCall({
|
|
32
31
|
roomId: 'roomId',
|
|
33
32
|
callId: 'room-session-id',
|
|
34
|
-
clientId: 'reporting-client-id',
|
|
35
33
|
});
|
|
36
34
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
observer.addEvaluator(async context => {
|
|
42
|
-
const { endedCalls } = context;
|
|
43
|
-
|
|
44
|
-
// Observe call durations
|
|
45
|
-
for (const endedCall of endedCalls) {
|
|
46
|
-
const elapsedTimeInMins = (endedCall.ended - Number(endedCall.started)) / (60 * 1000);
|
|
47
|
-
console.log(`Call ${endedCall.callId} duration was ${elapsedTimeInMins} minutes`);
|
|
48
|
-
}
|
|
35
|
+
const observedClient = observedCall.createObservedClient({
|
|
36
|
+
clientId: 'client-id',
|
|
37
|
+
mediaUnitId: 'media-unit-id',
|
|
49
38
|
});
|
|
50
39
|
|
|
40
|
+
const clientSample: ClientSample; // Receive your samples, for example, from a WebSocket
|
|
41
|
+
|
|
42
|
+
observedClient.accept(clientSample);
|
|
51
43
|
```
|
|
52
44
|
|
|
53
45
|
The above example do as follows:
|
|
@@ -55,9 +47,49 @@ The above example do as follows:
|
|
|
55
47
|
2. create a client source object to accept client samples
|
|
56
48
|
3. add an evaluator process to evaluate ended calls
|
|
57
49
|
|
|
58
|
-
|
|
50
|
+
### Get a Summary of a call when it ends
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
|
|
54
|
+
const monitor = observer.createCallSummaryMonitor('summary', (summary) => {
|
|
55
|
+
console.log('Call Summary', summary);
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### How Many Clients are using TURN?
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
const monitor = observer.createTurnUsageMonitor('turn', (turn) => {
|
|
63
|
+
console.log('TURN', turn);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// at any point of time you can get the current state of the turn usage
|
|
59
67
|
|
|
60
|
-
|
|
68
|
+
console.log('Currently ', monitor.clients.size, 'clients are using TURN');
|
|
69
|
+
|
|
70
|
+
// you can get the incoming and outgoing bytes of the TURN server
|
|
71
|
+
console.log(`${YOUR_TURN_SERVER_ADDRESS} usage:`, monitor.getUsage(YOUR_TURN_SERVER_ADDRESS));
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Monitor Calls and Clients as they updated
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
observer.on('newcall', (call) => {
|
|
79
|
+
call.on('update', () => {
|
|
80
|
+
console.log('Call Updated', call.callId);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
call.on('newclient', (client) => {
|
|
84
|
+
|
|
85
|
+
client.on('update', () => {
|
|
86
|
+
console.log('Client Updated', client.clientId);
|
|
87
|
+
|
|
88
|
+
console.log(`The avaialble incoming bitrate for the client ${client.clientId} is: ${client.availableIncomingBitrate}`)
|
|
89
|
+
});
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
```
|
|
61
93
|
|
|
62
94
|
## NPM package
|
|
63
95
|
|
|
@@ -69,10 +101,6 @@ https://www.npmjs.com/package/@observertc/observer-js
|
|
|
69
101
|
https://github.com/observertc/schemas
|
|
70
102
|
|
|
71
103
|
|
|
72
|
-
## Getting Involved
|
|
73
|
-
|
|
74
|
-
The repository is open for contributions.
|
|
75
|
-
|
|
76
104
|
## License
|
|
77
105
|
|
|
78
106
|
Apache-2.0
|
package/lib/ObservedClient.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ import { ObservedCall } from './ObservedCall';
|
|
|
4
4
|
import { EventEmitter } from 'events';
|
|
5
5
|
import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
6
6
|
import { ObservedSfu } from './ObservedSfu';
|
|
7
|
+
export interface ClientIssue {
|
|
8
|
+
severity: 'critical' | 'major' | 'minor';
|
|
9
|
+
timestamp: number;
|
|
10
|
+
description?: string;
|
|
11
|
+
peerConnectionId?: string;
|
|
12
|
+
trackId?: string;
|
|
13
|
+
}
|
|
7
14
|
export type ObservedClientModel = {
|
|
8
15
|
clientId: string;
|
|
9
16
|
mediaUnitId: string;
|
|
@@ -47,7 +54,9 @@ export type ObservedClientEvents = {
|
|
|
47
54
|
remoteCandidate: IceRemoteCandidate;
|
|
48
55
|
}
|
|
49
56
|
];
|
|
57
|
+
issue: [ClientIssue];
|
|
50
58
|
usingturn: [boolean];
|
|
59
|
+
usermediaerror: [string];
|
|
51
60
|
};
|
|
52
61
|
export declare interface ObservedClient<AppData extends Record<string, unknown> = Record<string, unknown>> {
|
|
53
62
|
on<U extends keyof ObservedClientEvents>(event: U, listener: (...args: ObservedClientEvents[U]) => void): this;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedClient.d.ts","sourceRoot":"","sources":["../src/ObservedClient.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAChJ,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAOlE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5C,MAAM,MAAM,mBAAmB,GAAE;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC,MAAM,EAAE;QAAC;YACR,eAAe,EAAE,MAAM,CAAC;SACxB;KAAC,CAAC;IACH,KAAK,EAAE,EAAE,CAAC;IACV,iBAAiB,EAAE,CAAC,sBAAsB,CAAC,CAAC;IAC5C,wBAAwB,EAAE;QAAC;YAC1B,cAAc,EAAE,sBAAsB,CAAC;YACvC,KAAK,EAAE,MAAM,CAAC;SACd;KAAC,CAAC;IACH,uBAAuB,EAAE;QAAC;YACzB,cAAc,EAAE,sBAAsB,CAAC;YACvC,KAAK,EAAE,MAAM,CAAC;SACd;KAAC,CAAC;IACH,qBAAqB,EAAE;QAAC;YACvB,cAAc,EAAE,sBAAsB,CAAC;YACvC,KAAK,EAAE,MAAM,CAAC;SACd;KAAC,CAAC;IACH,qBAAqB,EAAE;QAAC;YACvB,cAAc,EAAE,sBAAsB,CAAC;YACvC,cAAc,EAAE,iBAAiB,CAAC;YAClC,eAAe,EAAE,kBAAkB,CAAC;SACpC;KAAC,CAAC;IACH,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ObservedClient.d.ts","sourceRoot":"","sources":["../src/ObservedClient.ts"],"names":[],"mappings":"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"}
|
package/lib/ObservedClient.js
CHANGED
|
@@ -164,7 +164,7 @@ class ObservedClient extends events_1.EventEmitter {
|
|
|
164
164
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
|
|
165
165
|
type: callMetaReports_1.CallMetaType.OPERATION_SYSTEM,
|
|
166
166
|
payload: sample.os,
|
|
167
|
-
}, this.userId);
|
|
167
|
+
}, this.userId, undefined, sample.timestamp);
|
|
168
168
|
this.reports.addCallMetaReport(callMetaReport);
|
|
169
169
|
}
|
|
170
170
|
if (sample.engine && (((_d = this._model.engine) === null || _d === void 0 ? void 0 : _d.name) !== sample.engine.name ||
|
|
@@ -173,7 +173,7 @@ class ObservedClient extends events_1.EventEmitter {
|
|
|
173
173
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
|
|
174
174
|
type: callMetaReports_1.CallMetaType.ENGINE,
|
|
175
175
|
payload: sample.engine,
|
|
176
|
-
}, this.userId);
|
|
176
|
+
}, this.userId, undefined, sample.timestamp);
|
|
177
177
|
this.reports.addCallMetaReport(callMetaReport);
|
|
178
178
|
}
|
|
179
179
|
if (sample.platform && (((_f = this._model.platform) === null || _f === void 0 ? void 0 : _f.model) !== sample.platform.model ||
|
|
@@ -183,7 +183,7 @@ class ObservedClient extends events_1.EventEmitter {
|
|
|
183
183
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
|
|
184
184
|
type: callMetaReports_1.CallMetaType.PLATFORM,
|
|
185
185
|
payload: sample.platform,
|
|
186
|
-
}, this.userId);
|
|
186
|
+
}, this.userId, undefined, sample.timestamp);
|
|
187
187
|
this.reports.addCallMetaReport(callMetaReport);
|
|
188
188
|
}
|
|
189
189
|
if (sample.browser && (((_j = this._model.browser) === null || _j === void 0 ? void 0 : _j.name) !== sample.browser.name ||
|
|
@@ -192,21 +192,21 @@ class ObservedClient extends events_1.EventEmitter {
|
|
|
192
192
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
|
|
193
193
|
type: callMetaReports_1.CallMetaType.BROWSER,
|
|
194
194
|
payload: sample.browser,
|
|
195
|
-
}, this.userId);
|
|
195
|
+
}, this.userId, undefined, sample.timestamp);
|
|
196
196
|
this.reports.addCallMetaReport(callMetaReport);
|
|
197
197
|
}
|
|
198
198
|
for (const mediaConstraint of (_l = sample.mediaConstraints) !== null && _l !== void 0 ? _l : []) {
|
|
199
199
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
|
|
200
200
|
type: callMetaReports_1.CallMetaType.MEDIA_CONSTRAINT,
|
|
201
201
|
payload: mediaConstraint,
|
|
202
|
-
}, this.userId);
|
|
202
|
+
}, this.userId, undefined, sample.timestamp);
|
|
203
203
|
this.reports.addCallMetaReport(callMetaReport);
|
|
204
204
|
}
|
|
205
205
|
for (const localSDP of (_m = sample.localSDPs) !== null && _m !== void 0 ? _m : []) {
|
|
206
206
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
|
|
207
207
|
type: callMetaReports_1.CallMetaType.LOCAL_SDP,
|
|
208
208
|
payload: localSDP,
|
|
209
|
-
}, this.userId);
|
|
209
|
+
}, this.userId, undefined, sample.timestamp);
|
|
210
210
|
this.reports.addCallMetaReport(callMetaReport);
|
|
211
211
|
}
|
|
212
212
|
for (const extensionStats of (_o = sample.extensionStats) !== null && _o !== void 0 ? _o : []) {
|
|
@@ -229,6 +229,16 @@ class ObservedClient extends events_1.EventEmitter {
|
|
|
229
229
|
this._left = timestamp;
|
|
230
230
|
break;
|
|
231
231
|
}
|
|
232
|
+
case CallEventType_1.CallEventType.CLIENT_ISSUE: {
|
|
233
|
+
const severity = callEvent.value ? callEvent.value : 'minor';
|
|
234
|
+
this.emit('issue', {
|
|
235
|
+
severity,
|
|
236
|
+
timestamp: timestamp !== null && timestamp !== void 0 ? timestamp : Date.now(),
|
|
237
|
+
description: callEvent.message,
|
|
238
|
+
peerConnectionId: callEvent.peerConnectionId,
|
|
239
|
+
trackId: callEvent.mediaTrackId,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
232
242
|
}
|
|
233
243
|
this.reports.addCallEventReport(Object.assign({ serviceId: this.serviceId, mediaUnitId: this.mediaUnitId, roomId: this.roomId, callId: this.callId, clientId: this.clientId, userId: this.userId, timestamp: timestamp !== null && timestamp !== void 0 ? timestamp : Date.now() }, callEvent));
|
|
234
244
|
}
|
|
@@ -239,6 +249,7 @@ class ObservedClient extends events_1.EventEmitter {
|
|
|
239
249
|
}, this.userId);
|
|
240
250
|
this.reports.addCallMetaReport(callMetaReport);
|
|
241
251
|
this.userMediaErrors.push(userMediaError);
|
|
252
|
+
this.emit('usermediaerror', userMediaError);
|
|
242
253
|
}
|
|
243
254
|
for (const certificate of (_r = sample.certificates) !== null && _r !== void 0 ? _r : []) {
|
|
244
255
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
|
|
@@ -390,7 +401,7 @@ class ObservedClient extends events_1.EventEmitter {
|
|
|
390
401
|
logger.debug(`Peer connection ${iceLocalCandidate.peerConnectionId} not found for ice local candidate ${iceLocalCandidate.id}`);
|
|
391
402
|
continue;
|
|
392
403
|
}
|
|
393
|
-
peerConnection.ICE.addLocalCandidate(iceLocalCandidate);
|
|
404
|
+
peerConnection.ICE.addLocalCandidate(iceLocalCandidate, sample.timestamp);
|
|
394
405
|
}
|
|
395
406
|
for (const iceRemoteCandidate of (_13 = sample.iceRemoteCandidates) !== null && _13 !== void 0 ? _13 : []) {
|
|
396
407
|
if (!iceRemoteCandidate.peerConnectionId) {
|
|
@@ -402,7 +413,7 @@ class ObservedClient extends events_1.EventEmitter {
|
|
|
402
413
|
logger.debug(`Peer connection ${iceRemoteCandidate.peerConnectionId} not found for ice remote candidate ${iceRemoteCandidate.id}`);
|
|
403
414
|
continue;
|
|
404
415
|
}
|
|
405
|
-
peerConnection.ICE.addRemoteCandidate(iceRemoteCandidate);
|
|
416
|
+
peerConnection.ICE.addRemoteCandidate(iceRemoteCandidate, sample.timestamp);
|
|
406
417
|
}
|
|
407
418
|
for (const candidatePair of (_14 = sample.iceCandidatePairs) !== null && _14 !== void 0 ? _14 : []) {
|
|
408
419
|
const peerConnection = this._peerConnections.get(candidatePair.peerConnectionId);
|
package/lib/ObservedICE.d.ts
CHANGED
|
@@ -56,8 +56,8 @@ export declare class ObservedICE extends EventEmitter {
|
|
|
56
56
|
get updated(): number;
|
|
57
57
|
get closed(): boolean;
|
|
58
58
|
close(): void;
|
|
59
|
-
addLocalCandidate(candidate: IceLocalCandidate): void;
|
|
60
|
-
addRemoteCandidate(candidate: IceRemoteCandidate): void;
|
|
59
|
+
addLocalCandidate(candidate: IceLocalCandidate, sampleTimestamp?: number): void;
|
|
60
|
+
addRemoteCandidate(candidate: IceRemoteCandidate, sampleTimestamp?: number): void;
|
|
61
61
|
resetMetrics(): void;
|
|
62
62
|
update(candidatePair: IceCandidatePair, timestamp: number): void;
|
|
63
63
|
}
|
package/lib/ObservedICE.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedICE.d.ts","sourceRoot":"","sources":["../src/ObservedICE.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,MAAM,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE;QAAC;YACR,eAAe,EAAE,MAAM,CAAC;SACxB;KAAC,CAAC;IACH,qBAAqB,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAC3C,sBAAsB,EAAE,CAAC,kBAAkB,CAAC,CAAC;IAC7C,6BAA6B,EAAE;QAAC;YAC/B,cAAc,EAAE,iBAAiB,CAAC;YAClC,eAAe,EAAE,kBAAkB,CAAC;SACpC;KAAC,CAAC;IACH,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAC;IAC5B,KAAK,EAAE,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,WAAW;IACnC,EAAE,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACzG,GAAG,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CAC1F;AAED,qBAAa,WAAY,SAAQ,YAAY;aA+B3B,cAAc,EAAE,sBAAsB;WA9BzC,MAAM,CAAC,cAAc,EAAE,sBAAsB;IAIpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAwC;IAEnE,SAAS,UAAS;IAElB,kBAAkB,SAAK;IACvB,cAAc,SAAK;IACnB,oBAAoB,SAAK;IACzB,gBAAgB,SAAK;IAErB,kBAAkB,SAAK;IACvB,cAAc,SAAK;IACnB,oBAAoB,SAAK;IACzB,gBAAgB,SAAK;IAErB,cAAc,CAAC,EAAE,MAAM,CAAC;IAE/B,OAAO,CAAC,yBAAyB,CAAC,CAAS;IAC3C,OAAO,CAAC,0BAA0B,CAAC,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,MAAM,CAAC,CAAmB;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO;IAOP,IAAW,OAAO,kDAEjB;IAED,IAAW,eAAe,IAAI,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAEnE;IAED,IAAW,gBAAgB,IAAI,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAErE;IAED,IAAW,sBAAsB,kCAEhC;IAED,IAAW,uBAAuB,kCAEjC;IAED,IAAW,KAAK,iCAEf;IAED,IAAW,OAAO,WAEjB;IAED,IAAW,MAAM,YAEhB;IAEM,KAAK;IAML,iBAAiB,CAAC,SAAS,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"ObservedICE.d.ts","sourceRoot":"","sources":["../src/ObservedICE.ts"],"names":[],"mappings":"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"}
|
package/lib/ObservedICE.js
CHANGED
|
@@ -57,7 +57,7 @@ class ObservedICE extends events_1.EventEmitter {
|
|
|
57
57
|
this._closed = true;
|
|
58
58
|
this.emit('close');
|
|
59
59
|
}
|
|
60
|
-
addLocalCandidate(candidate) {
|
|
60
|
+
addLocalCandidate(candidate, sampleTimestamp) {
|
|
61
61
|
if (!candidate.id)
|
|
62
62
|
return;
|
|
63
63
|
const newCandidate = !this._localCandidates.has(candidate.id);
|
|
@@ -66,12 +66,12 @@ class ObservedICE extends events_1.EventEmitter {
|
|
|
66
66
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.peerConnection.client.serviceId, this.peerConnection.client.mediaUnitId, this.peerConnection.client.roomId, this.peerConnection.client.callId, this.peerConnection.client.clientId, {
|
|
67
67
|
type: callMetaReports_1.CallMetaType.ICE_LOCAL_CANDIDATE,
|
|
68
68
|
payload: candidate,
|
|
69
|
-
}, this.peerConnection.client.userId);
|
|
69
|
+
}, this.peerConnection.client.userId, this.peerConnection.peerConnectionId, sampleTimestamp);
|
|
70
70
|
this.reports.addCallMetaReport(callMetaReport);
|
|
71
71
|
this.emit('new-local-candidate', candidate);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
addRemoteCandidate(candidate) {
|
|
74
|
+
addRemoteCandidate(candidate, sampleTimestamp) {
|
|
75
75
|
if (!candidate.id)
|
|
76
76
|
return;
|
|
77
77
|
const newCandidate = !this._remoteCandidates.has(candidate.id);
|
|
@@ -80,7 +80,7 @@ class ObservedICE extends events_1.EventEmitter {
|
|
|
80
80
|
const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.peerConnection.client.serviceId, this.peerConnection.client.mediaUnitId, this.peerConnection.client.roomId, this.peerConnection.client.callId, this.peerConnection.client.clientId, {
|
|
81
81
|
type: callMetaReports_1.CallMetaType.ICE_REMOTE_CANDIDATE,
|
|
82
82
|
payload: candidate,
|
|
83
|
-
}, this.peerConnection.client.userId);
|
|
83
|
+
}, this.peerConnection.client.userId, this.peerConnection.peerConnectionId, sampleTimestamp);
|
|
84
84
|
this.reports.addCallMetaReport(callMetaReport);
|
|
85
85
|
this.emit('new-remote-candidate', candidate);
|
|
86
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedOutboundTrack.d.ts","sourceRoot":"","sources":["../src/ObservedOutboundTrack.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ObservedOutboundTrack.d.ts","sourceRoot":"","sources":["../src/ObservedOutboundTrack.ts"],"names":[],"mappings":"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"}
|
|
@@ -112,6 +112,13 @@ class ObservedOutboundTrack extends events_1.EventEmitter {
|
|
|
112
112
|
if ((videoSample === null || videoSample === void 0 ? void 0 : videoSample.framesSent) && (lastVideoStats === null || lastVideoStats === void 0 ? void 0 : lastVideoStats.framesSent) && lastVideoStats.framesSent < videoSample.framesSent) {
|
|
113
113
|
deltaSentFrames = videoSample.framesSent - lastVideoStats.framesSent;
|
|
114
114
|
}
|
|
115
|
+
if (videoSample.qualityLimitationReason && (lastVideoStats === null || lastVideoStats === void 0 ? void 0 : lastVideoStats.qualityLimitationReason) !== videoSample.qualityLimitationReason) {
|
|
116
|
+
this.emit('qualitylimitationchanged', videoSample.qualityLimitationReason);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (this.kind === 'audio') {
|
|
120
|
+
// const audioSample = sample as OutboundAudioTrack;
|
|
121
|
+
// const lastAudioStats = lastStat as OutboundAudioTrack | undefined;
|
|
115
122
|
}
|
|
116
123
|
const stats = Object.assign(Object.assign({}, sample), { rttInMs,
|
|
117
124
|
bitrate, ssrc: sample.ssrc, deltaLostPackets,
|
package/lib/ObservedSfu.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedSfu.d.ts","sourceRoot":"","sources":["../src/ObservedSfu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAA6B,MAAM,wBAAwB,CAAC;AAGzF,MAAM,MAAM,gBAAgB,GAAE;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE;QAAC;YACR,eAAe,EAAE,MAAM,CAAC;SACxB;KAAC,CAAC;IACH,KAAK,EAAE,EAAE,CAAC;IACV,YAAY,EAAE,CAAC,oBAAoB,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrG,EAAE,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACzG,GAAG,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAE1F,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;CAChC;AAED,qBAAa,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,YAAY;IAY9G,OAAO,CAAC,QAAQ,CAAC,MAAM;aACP,QAAQ,EAAE,QAAQ;aAClB,OAAO,EAAE,OAAO;IAbjC,SAAgB,OAAO,SAAc;IAErC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,sBAAsB,CAAC,CAAS;IACxC,OAAO,CAAC,KAAK,CAAC,CAAS;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2C;gBAGrD,MAAM,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO;IAMjC,IAAW,MAAM,uBAEhB;IAED,IAAW,OAAO,kDAEjB;IAED,IAAW,SAAS,WAGnB;IAED,IAAW,WAAW,WAErB;IAED,IAAW,KAAK,WAGf;IAED,IAAW,MAAM,WAGhB;IAED,IAAW,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAEjE;IAED,IAAW,OAAO,WAEjB;IAED,IAAW,MAAM,YAEhB;IAEM,KAAK;
|
|
1
|
+
{"version":3,"file":"ObservedSfu.d.ts","sourceRoot":"","sources":["../src/ObservedSfu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAA6B,MAAM,wBAAwB,CAAC;AAGzF,MAAM,MAAM,gBAAgB,GAAE;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE;QAAC;YACR,eAAe,EAAE,MAAM,CAAC;SACxB;KAAC,CAAC;IACH,KAAK,EAAE,EAAE,CAAC;IACV,YAAY,EAAE,CAAC,oBAAoB,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrG,EAAE,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACzG,GAAG,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAE1F,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;CAChC;AAED,qBAAa,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,YAAY;IAY9G,OAAO,CAAC,QAAQ,CAAC,MAAM;aACP,QAAQ,EAAE,QAAQ;aAClB,OAAO,EAAE,OAAO;IAbjC,SAAgB,OAAO,SAAc;IAErC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,sBAAsB,CAAC,CAAS;IACxC,OAAO,CAAC,KAAK,CAAC,CAAS;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2C;gBAGrD,MAAM,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO;IAMjC,IAAW,MAAM,uBAEhB;IAED,IAAW,OAAO,kDAEjB;IAED,IAAW,SAAS,WAGnB;IAED,IAAW,WAAW,WAErB;IAED,IAAW,KAAK,WAGf;IAED,IAAW,MAAM,WAGhB;IAED,IAAW,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAEjE;IAED,IAAW,OAAO,WAEjB;IAED,IAAW,MAAM,YAEhB;IAEM,KAAK;IAmGZ,OAAO,CAAC,gBAAgB;CAYxB"}
|
package/lib/ObservedSfu.js
CHANGED
|
@@ -61,6 +61,7 @@ class ObservedSfu extends events_1.EventEmitter {
|
|
|
61
61
|
if (!this._timeZoneOffsetInHours && sample.timeZoneOffsetInHours) {
|
|
62
62
|
this._timeZoneOffsetInHours = sample.timeZoneOffsetInHours;
|
|
63
63
|
}
|
|
64
|
+
this._marker = sample.marker;
|
|
64
65
|
const now = Date.now();
|
|
65
66
|
const elapsedTimeInMs = now - this._updated;
|
|
66
67
|
for (const customSfuEvents of (_a = sample.customSfuEvents) !== null && _a !== void 0 ? _a : []) {
|
package/lib/Observer.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ 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';
|
|
8
|
+
import { CallSummaryMonitor, CallSummaryMonitorConfig } from './monitors/CallSummaryMonitor';
|
|
9
9
|
import { TurnUsageMonitor } from './monitors/TurnUsageMonitor';
|
|
10
10
|
export type ObserverEvents = {
|
|
11
11
|
'newcall': [ObservedCall];
|
|
@@ -51,9 +51,11 @@ export declare class Observer extends EventEmitter {
|
|
|
51
51
|
createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(config: PartialBy<ObservedCallModel, 'serviceId'> & {
|
|
52
52
|
appData: T;
|
|
53
53
|
started?: number;
|
|
54
|
+
reportCallStarted?: boolean;
|
|
55
|
+
reportCallEnded?: boolean;
|
|
54
56
|
}): ObservedCall<T>;
|
|
55
57
|
createObservedSfu<AppData extends Record<string, unknown> = Record<string, unknown>>(model: ObservedSfuModel, appData: AppData): ObservedSfu<AppData>;
|
|
56
|
-
createCallSummaryMonitor(options?: {
|
|
58
|
+
createCallSummaryMonitor(options?: CallSummaryMonitorConfig & {
|
|
57
59
|
timeoutAfterCallClose?: number;
|
|
58
60
|
}): CallSummaryMonitor;
|
|
59
61
|
createTurnUsageMonitor(): TurnUsageMonitor;
|
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;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"Observer.d.ts","sourceRoot":"","sources":["../src/Observer.ts"],"names":[],"mappings":"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"}
|
package/lib/Observer.js
CHANGED
|
@@ -65,7 +65,7 @@ class Observer extends events_1.EventEmitter {
|
|
|
65
65
|
if (this._closed) {
|
|
66
66
|
throw new Error('Attempted to create a call source on a closed observer');
|
|
67
67
|
}
|
|
68
|
-
const { appData, started = Date.now() } = config, model = __rest(config, ["appData", "started"]);
|
|
68
|
+
const { appData, started = Date.now(), reportCallEnded = true, reportCallStarted = true } = config, model = __rest(config, ["appData", "started", "reportCallEnded", "reportCallStarted"]);
|
|
69
69
|
const call = new ObservedCall_1.ObservedCall(Object.assign(Object.assign({}, model), { serviceId: this.config.defaultServiceId }), this, appData);
|
|
70
70
|
if (this._closed)
|
|
71
71
|
throw new Error('Cannot create an observed call on a closed observer');
|
|
@@ -73,10 +73,10 @@ class Observer extends events_1.EventEmitter {
|
|
|
73
73
|
throw new Error(`Observed Call with id ${call.callId} already exists`);
|
|
74
74
|
call.once('close', () => {
|
|
75
75
|
this._observedCalls.delete(call.callId);
|
|
76
|
-
this.reports.addCallEventReport((0, callEventReports_1.createCallEndedEventReport)(call.serviceId, call.roomId, call.callId, Date.now()));
|
|
76
|
+
reportCallEnded && this.reports.addCallEventReport((0, callEventReports_1.createCallEndedEventReport)(call.serviceId, call.roomId, call.callId, Date.now()));
|
|
77
77
|
});
|
|
78
78
|
this._observedCalls.set(call.callId, call);
|
|
79
|
-
this.reports.addCallEventReport((0, callEventReports_1.createCallStartedEventReport)(call.serviceId, call.roomId, call.callId, started));
|
|
79
|
+
reportCallStarted && this.reports.addCallEventReport((0, callEventReports_1.createCallStartedEventReport)(call.serviceId, call.roomId, call.callId, started));
|
|
80
80
|
this.emit('newcall', call);
|
|
81
81
|
return call;
|
|
82
82
|
}
|
|
@@ -102,7 +102,7 @@ class Observer extends events_1.EventEmitter {
|
|
|
102
102
|
const existingMonitor = this._monitors.get(CallSummaryMonitor_1.CallSummaryMonitor.name);
|
|
103
103
|
if (existingMonitor)
|
|
104
104
|
return existingMonitor;
|
|
105
|
-
const monitor = new CallSummaryMonitor_1.CallSummaryMonitor();
|
|
105
|
+
const monitor = new CallSummaryMonitor_1.CallSummaryMonitor(options);
|
|
106
106
|
const onNewCall = (call) => {
|
|
107
107
|
monitor.addCall(call);
|
|
108
108
|
call.once('close', () => {
|
|
@@ -17,6 +17,7 @@ export declare enum CallEventType {
|
|
|
17
17
|
DATA_CHANNEL_CLOSED = "DATA_CHANNEL_CLOSED",
|
|
18
18
|
DATA_CHANNEL_ERROR = "DATA_CHANNEL_ERROR",
|
|
19
19
|
NEGOTIATION_NEEDED = "NEGOTIATION_NEEDED",
|
|
20
|
-
SIGNALING_STATE_CHANGE = "SIGNALING_STATE_CHANGE"
|
|
20
|
+
SIGNALING_STATE_CHANGE = "SIGNALING_STATE_CHANGE",
|
|
21
|
+
CLIENT_ISSUE = "CLIENT_ISSUE"
|
|
21
22
|
}
|
|
22
23
|
//# sourceMappingURL=CallEventType.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CallEventType.d.ts","sourceRoot":"","sources":["../../src/common/CallEventType.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CallEventType.d.ts","sourceRoot":"","sources":["../../src/common/CallEventType.ts"],"names":[],"mappings":"AACA,oBAAY,aAAa;IACxB,YAAY,iBAAiB;IAC7B,UAAU,eAAe;IACzB,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAC3B,sBAAsB,2BAA2B;IACjD,sBAAsB,2BAA2B;IACjD,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,2BAA2B,gCAAgC;IAC3D,6BAA6B,kCAAkC;IAC/D,4BAA4B,iCAAiC;IAC7D,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,kBAAkB,uBAAuB;IACzC,kBAAkB,uBAAuB;IACzC,sBAAsB,2BAA2B;IACjD,YAAY,iBAAiB;CAC7B"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// eslint-disable-next-line no-shadow
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.CallEventType = void 0;
|
|
4
|
+
// eslint-disable-next-line no-shadow
|
|
5
5
|
var CallEventType;
|
|
6
6
|
(function (CallEventType) {
|
|
7
7
|
CallEventType["CALL_STARTED"] = "CALL_STARTED";
|
|
@@ -23,4 +23,5 @@ var CallEventType;
|
|
|
23
23
|
CallEventType["DATA_CHANNEL_ERROR"] = "DATA_CHANNEL_ERROR";
|
|
24
24
|
CallEventType["NEGOTIATION_NEEDED"] = "NEGOTIATION_NEEDED";
|
|
25
25
|
CallEventType["SIGNALING_STATE_CHANGE"] = "SIGNALING_STATE_CHANGE";
|
|
26
|
+
CallEventType["CLIENT_ISSUE"] = "CLIENT_ISSUE";
|
|
26
27
|
})(CallEventType = exports.CallEventType || (exports.CallEventType = {}));
|
|
@@ -59,5 +59,5 @@ export type CallMetaReportType = {
|
|
|
59
59
|
type: CallMetaType.BROWSER;
|
|
60
60
|
payload: Browser;
|
|
61
61
|
};
|
|
62
|
-
export declare function createCallMetaReport(serviceId: string, mediaUnitId: string, roomId: string, callId: string, clientId: string, reportType: CallMetaReportType, userId?: string, timestamp?: number): CallMetaReport;
|
|
62
|
+
export declare function createCallMetaReport(serviceId: string, mediaUnitId: string, roomId: string, callId: string, clientId: string, reportType: CallMetaReportType, userId?: string, peerConnectionId?: string, timestamp?: number): CallMetaReport;
|
|
63
63
|
//# sourceMappingURL=callMetaReports.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callMetaReports.d.ts","sourceRoot":"","sources":["../../src/common/callMetaReports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EACN,OAAO,EACP,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,QAAQ,EACR,MAAM,+BAA+B,CAAC;AAGvC,oBAAY,YAAY;IACvB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;IACf,mBAAmB,wBAAwB;IAC3C,oBAAoB,yBAAyB;IAC7C,UAAU,eAAe;IACzB,gBAAgB,qBAAqB;IACrC,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,SAAS,cAAc;IAEvB,gBAAgB,qBAAqB;IACrC,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;CACnB;AAED,MAAM,MAAM,kBAAkB,GAC3B;IACD,IAAI,EAAE,YAAY,CAAC,WAAW,CAAC;IAC/B,OAAO,EAAE,WAAW,CAAC;CACrB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,mBAAmB,CAAC;IACvC,OAAO,EAAE,iBAAiB,CAAC;CAC3B,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,oBAAoB,CAAC;IACxC,OAAO,EAAE,kBAAkB,CAAC;CAC5B,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC;IAChC,OAAO,EAAE,WAAW,CAAC;CACrB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;IAC5B,OAAO,EAAE,QAAQ,CAAC;CAClB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CACjB,CAAC;AAEH,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,kBAAkB,EAC9B,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,kBAelB"}
|
|
1
|
+
{"version":3,"file":"callMetaReports.d.ts","sourceRoot":"","sources":["../../src/common/callMetaReports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EACN,OAAO,EACP,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,QAAQ,EACR,MAAM,+BAA+B,CAAC;AAGvC,oBAAY,YAAY;IACvB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;IACf,mBAAmB,wBAAwB;IAC3C,oBAAoB,yBAAyB;IAC7C,UAAU,eAAe;IACzB,gBAAgB,qBAAqB;IACrC,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,SAAS,cAAc;IAEvB,gBAAgB,qBAAqB;IACrC,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;CACnB;AAED,MAAM,MAAM,kBAAkB,GAC3B;IACD,IAAI,EAAE,YAAY,CAAC,WAAW,CAAC;IAC/B,OAAO,EAAE,WAAW,CAAC;CACrB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,mBAAmB,CAAC;IACvC,OAAO,EAAE,iBAAiB,CAAC;CAC3B,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,oBAAoB,CAAC;IACxC,OAAO,EAAE,kBAAkB,CAAC;CAC5B,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC;IAChC,OAAO,EAAE,WAAW,CAAC;CACrB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;IAC5B,OAAO,EAAE,QAAQ,CAAC;CAClB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CACjB,CAAC;AAEH,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,kBAAkB,EAC9B,MAAM,CAAC,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,MAAM,EACzB,SAAS,CAAC,EAAE,MAAM,kBAelB"}
|
|
@@ -19,7 +19,7 @@ var CallMetaType;
|
|
|
19
19
|
CallMetaType["PLATFORM"] = "PLATFORM";
|
|
20
20
|
CallMetaType["BROWSER"] = "BROWSER";
|
|
21
21
|
})(CallMetaType = exports.CallMetaType || (exports.CallMetaType = {}));
|
|
22
|
-
function createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, reportType, userId, timestamp) {
|
|
22
|
+
function createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, reportType, userId, peerConnectionId, timestamp) {
|
|
23
23
|
const report = {
|
|
24
24
|
type: reportType.type,
|
|
25
25
|
serviceId,
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
import { ClientIssue } from '../ObservedClient';
|
|
1
2
|
export interface ClientSummary {
|
|
2
3
|
clientId: string;
|
|
3
4
|
mediaUnitId: string;
|
|
4
5
|
userId?: string;
|
|
5
6
|
joined: number;
|
|
7
|
+
left?: number;
|
|
6
8
|
durationInMs: number;
|
|
7
9
|
avgOutboundAudioBitrate: number;
|
|
8
10
|
avgOutboundVideoBitrate: number;
|
|
9
11
|
avgInboundAudioBitrate: number;
|
|
10
12
|
avgInboundVideoBitrate: number;
|
|
11
13
|
ewmaRttInMs: number;
|
|
14
|
+
usedTurn: boolean;
|
|
15
|
+
issues: ClientIssue[];
|
|
12
16
|
}
|
|
13
17
|
export interface CallSummary {
|
|
14
18
|
serviceId: string;
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"CallSummary.d.ts","sourceRoot":"","sources":["../../src/monitors/CallSummary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,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,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,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;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,WAAW,EAAE,CAAC;CACtB;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"}
|
|
@@ -6,6 +6,10 @@ export type CallSummaryMonitorEvents = {
|
|
|
6
6
|
close: [];
|
|
7
7
|
summary: [CallSummary];
|
|
8
8
|
};
|
|
9
|
+
export type CallSummaryMonitorConfig = {
|
|
10
|
+
detectUserMediaIssues?: boolean;
|
|
11
|
+
detectMediaTrackQualityLimitationIssues?: boolean;
|
|
12
|
+
};
|
|
9
13
|
export declare interface CallSummaryMonitor {
|
|
10
14
|
on<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
|
|
11
15
|
off<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
|
|
@@ -13,11 +17,14 @@ export declare interface CallSummaryMonitor {
|
|
|
13
17
|
emit<U extends keyof CallSummaryMonitorEvents>(event: U, ...args: CallSummaryMonitorEvents[U]): boolean;
|
|
14
18
|
}
|
|
15
19
|
export declare class CallSummaryMonitor extends EventEmitter {
|
|
20
|
+
readonly config: CallSummaryMonitorConfig;
|
|
16
21
|
private readonly _summaries;
|
|
17
22
|
private _closed;
|
|
18
|
-
constructor();
|
|
23
|
+
constructor(config?: CallSummaryMonitorConfig);
|
|
19
24
|
addCall(call: ObservedCall): void;
|
|
20
25
|
private _addClient;
|
|
26
|
+
private _addPeerConnection;
|
|
27
|
+
private _addOutboundVideoTrack;
|
|
21
28
|
takeSummary(callId: string): CallSummary | undefined;
|
|
22
29
|
get closed(): boolean;
|
|
23
30
|
close(): void;
|
|
@@ -1 +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,
|
|
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,EAAiB,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/C,MAAM,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC;CACvB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACtC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC,CAAC,EAAE,OAAO,CAAC;CAClD,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;aAKlC,MAAM,EAAE,wBAAwB;IAJjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAE7D,OAAO,CAAC,OAAO,CAAS;gBAEP,MAAM,GAAE,wBAA6B;IAK/C,OAAO,CAAC,IAAI,EAAE,YAAY;IAyBjC,OAAO,CAAC,UAAU;IAuElB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,sBAAsB;IAmBvB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAU3D,IAAW,MAAM,YAEhB;IAEM,KAAK;CAMZ"}
|
|
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CallSummaryMonitor = void 0;
|
|
4
4
|
const events_1 = require("events");
|
|
5
5
|
class CallSummaryMonitor extends events_1.EventEmitter {
|
|
6
|
-
constructor() {
|
|
6
|
+
constructor(config = {}) {
|
|
7
7
|
super();
|
|
8
|
+
this.config = config;
|
|
8
9
|
this._summaries = new Map();
|
|
9
10
|
this._closed = false;
|
|
10
11
|
}
|
|
@@ -44,6 +45,8 @@ class CallSummaryMonitor extends events_1.EventEmitter {
|
|
|
44
45
|
ewmaRttInMs: 0,
|
|
45
46
|
joined: client.created,
|
|
46
47
|
userId: client.userId,
|
|
48
|
+
usedTurn: false,
|
|
49
|
+
issues: [],
|
|
47
50
|
};
|
|
48
51
|
callSummary.clients.push(clientSummary);
|
|
49
52
|
const updateClient = () => {
|
|
@@ -51,7 +54,29 @@ class CallSummaryMonitor extends events_1.EventEmitter {
|
|
|
51
54
|
clientSummary.ewmaRttInMs = (clientSummary.ewmaRttInMs * 0.9) + (client.avgRttInMs * 0.1);
|
|
52
55
|
}
|
|
53
56
|
};
|
|
57
|
+
const onUsingTurn = (usingTurn) => {
|
|
58
|
+
clientSummary.usedTurn || (clientSummary.usedTurn = usingTurn);
|
|
59
|
+
};
|
|
60
|
+
const onIssue = (issue) => {
|
|
61
|
+
clientSummary.issues.push(issue);
|
|
62
|
+
};
|
|
63
|
+
const onUserMediaError = (error) => {
|
|
64
|
+
if (!this.config.detectUserMediaIssues)
|
|
65
|
+
return;
|
|
66
|
+
// maybe the client also sned this issue, in which case the timestamp can be more accurate
|
|
67
|
+
const alreadyDetected = clientSummary.issues.find((issue) => issue.severity === 'critical' && issue.description === error);
|
|
68
|
+
!alreadyDetected && clientSummary.issues.push({
|
|
69
|
+
severity: 'critical',
|
|
70
|
+
timestamp: Date.now(),
|
|
71
|
+
description: error,
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
const onNewPeerConnection = (peerConnection) => this._addPeerConnection(clientSummary, peerConnection);
|
|
54
75
|
client.on('update', updateClient);
|
|
76
|
+
client.on('usingturn', onUsingTurn);
|
|
77
|
+
client.on('issue', onIssue);
|
|
78
|
+
client.on('usermediaerror', onUserMediaError);
|
|
79
|
+
client.on('newpeerconnection', onNewPeerConnection);
|
|
55
80
|
client.once('close', () => {
|
|
56
81
|
const elapsedTimeInS = (Date.now() - client.created) / 1000;
|
|
57
82
|
clientSummary.avgInboundAudioBitrate = (client.totalReceivedBytes * 8) / elapsedTimeInS;
|
|
@@ -60,7 +85,36 @@ class CallSummaryMonitor extends events_1.EventEmitter {
|
|
|
60
85
|
clientSummary.avgOutboundVideoBitrate = (client.totalSentBytes * 8) / elapsedTimeInS;
|
|
61
86
|
clientSummary.durationInMs = elapsedTimeInS * 1000;
|
|
62
87
|
client.off('update', updateClient);
|
|
88
|
+
client.off('usingturn', onUsingTurn);
|
|
89
|
+
client.off('issue', onIssue);
|
|
90
|
+
client.off('usermediaerror', onUserMediaError);
|
|
91
|
+
client.off('newpeerconnection', onNewPeerConnection);
|
|
92
|
+
callSummary.durationInMs += clientSummary.durationInMs;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
_addPeerConnection(clientSummary, peerConnection) {
|
|
96
|
+
const onOutboundVideoTrack = (track) => this._addOutboundVideoTrack(clientSummary, track);
|
|
97
|
+
peerConnection.on('newoutboundvideotrack', onOutboundVideoTrack);
|
|
98
|
+
peerConnection.once('close', () => {
|
|
99
|
+
peerConnection.off('newoutboundvideotrack', onOutboundVideoTrack);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
_addOutboundVideoTrack(clientSummary, track) {
|
|
103
|
+
const onQualityLimitationChanged = (reason) => {
|
|
104
|
+
if (!this.config.detectMediaTrackQualityLimitationIssues)
|
|
105
|
+
return;
|
|
106
|
+
clientSummary.issues.push({
|
|
107
|
+
severity: 'minor',
|
|
108
|
+
timestamp: Date.now(),
|
|
109
|
+
description: reason,
|
|
110
|
+
peerConnectionId: track.peerConnectionId,
|
|
111
|
+
trackId: track.trackId,
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
track.once('close', () => {
|
|
115
|
+
track.off('qualitylimitationchanged', onQualityLimitationChanged);
|
|
63
116
|
});
|
|
117
|
+
track.on('qualitylimitationchanged', onQualityLimitationChanged);
|
|
64
118
|
}
|
|
65
119
|
takeSummary(callId) {
|
|
66
120
|
if (this.closed)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import { ObservedPeerConnection } from '../ObservedPeerConnection';
|
|
4
|
+
import { ObservedClient } from '../ObservedClient';
|
|
4
5
|
export type TurnUsageMonitorEvents = {
|
|
5
6
|
close: [];
|
|
6
7
|
'newturnip': [string];
|
|
@@ -31,6 +32,7 @@ export declare class TurnUsageMonitor extends EventEmitter {
|
|
|
31
32
|
get turnIps(): string[];
|
|
32
33
|
get peerConnections(): ObservedPeerConnection[];
|
|
33
34
|
getUsage(turnIp: string): TurnUsage | undefined;
|
|
35
|
+
get clients(): ReadonlyMap<string, ObservedClient>;
|
|
34
36
|
get closed(): boolean;
|
|
35
37
|
close(): void;
|
|
36
38
|
}
|
|
@@ -1 +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;
|
|
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;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,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,OAAO,IAAI,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAUxD;IAED,IAAW,MAAM,YAEhB;IAEM,KAAK;CAMZ"}
|
|
@@ -67,6 +67,15 @@ class TurnUsageMonitor extends events_1.EventEmitter {
|
|
|
67
67
|
getUsage(turnIp) {
|
|
68
68
|
return this._turnUsage.get(turnIp);
|
|
69
69
|
}
|
|
70
|
+
get clients() {
|
|
71
|
+
const result = new Map();
|
|
72
|
+
for (const pc of this.peerConnections) {
|
|
73
|
+
if (result.has(pc.clientId))
|
|
74
|
+
continue;
|
|
75
|
+
result.set(pc.clientId, pc.client);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
70
79
|
get closed() {
|
|
71
80
|
return this._closed;
|
|
72
81
|
}
|
package/package.json
CHANGED
package/src/ObservedClient.ts
CHANGED
|
@@ -12,6 +12,14 @@ import { ObservedSfu } from './ObservedSfu';
|
|
|
12
12
|
|
|
13
13
|
const logger = createLogger('ObservedClient');
|
|
14
14
|
|
|
15
|
+
export interface ClientIssue {
|
|
16
|
+
severity: 'critical' | 'major' | 'minor';
|
|
17
|
+
timestamp: number;
|
|
18
|
+
description?: string;
|
|
19
|
+
peerConnectionId?: string,
|
|
20
|
+
trackId?: string,
|
|
21
|
+
}
|
|
22
|
+
|
|
15
23
|
export type ObservedClientModel= {
|
|
16
24
|
clientId: string;
|
|
17
25
|
mediaUnitId: string;
|
|
@@ -46,7 +54,9 @@ export type ObservedClientEvents = {
|
|
|
46
54
|
localCandidate: IceLocalCandidate,
|
|
47
55
|
remoteCandidate: IceRemoteCandidate,
|
|
48
56
|
}],
|
|
57
|
+
issue: [ClientIssue],
|
|
49
58
|
usingturn: [boolean],
|
|
59
|
+
usermediaerror: [string],
|
|
50
60
|
};
|
|
51
61
|
|
|
52
62
|
export declare interface ObservedClient<AppData extends Record<string, unknown> = Record<string, unknown>> {
|
|
@@ -252,7 +262,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
252
262
|
{
|
|
253
263
|
type: CallMetaType.OPERATION_SYSTEM,
|
|
254
264
|
payload: sample.os,
|
|
255
|
-
},
|
|
265
|
+
},
|
|
266
|
+
this.userId,
|
|
267
|
+
undefined,
|
|
268
|
+
sample.timestamp
|
|
269
|
+
);
|
|
256
270
|
|
|
257
271
|
this.reports.addCallMetaReport(callMetaReport);
|
|
258
272
|
}
|
|
@@ -272,7 +286,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
272
286
|
{
|
|
273
287
|
type: CallMetaType.ENGINE,
|
|
274
288
|
payload: sample.engine,
|
|
275
|
-
},
|
|
289
|
+
},
|
|
290
|
+
this.userId,
|
|
291
|
+
undefined,
|
|
292
|
+
sample.timestamp
|
|
293
|
+
);
|
|
276
294
|
|
|
277
295
|
this.reports.addCallMetaReport(callMetaReport);
|
|
278
296
|
}
|
|
@@ -293,7 +311,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
293
311
|
{
|
|
294
312
|
type: CallMetaType.PLATFORM,
|
|
295
313
|
payload: sample.platform,
|
|
296
|
-
},
|
|
314
|
+
},
|
|
315
|
+
this.userId,
|
|
316
|
+
undefined,
|
|
317
|
+
sample.timestamp
|
|
318
|
+
);
|
|
297
319
|
|
|
298
320
|
this.reports.addCallMetaReport(callMetaReport);
|
|
299
321
|
}
|
|
@@ -313,7 +335,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
313
335
|
{
|
|
314
336
|
type: CallMetaType.BROWSER,
|
|
315
337
|
payload: sample.browser,
|
|
316
|
-
},
|
|
338
|
+
},
|
|
339
|
+
this.userId,
|
|
340
|
+
undefined,
|
|
341
|
+
sample.timestamp
|
|
342
|
+
);
|
|
317
343
|
|
|
318
344
|
this.reports.addCallMetaReport(callMetaReport);
|
|
319
345
|
}
|
|
@@ -328,7 +354,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
328
354
|
{
|
|
329
355
|
type: CallMetaType.MEDIA_CONSTRAINT,
|
|
330
356
|
payload: mediaConstraint,
|
|
331
|
-
},
|
|
357
|
+
},
|
|
358
|
+
this.userId,
|
|
359
|
+
undefined,
|
|
360
|
+
sample.timestamp
|
|
361
|
+
);
|
|
332
362
|
|
|
333
363
|
this.reports.addCallMetaReport(callMetaReport);
|
|
334
364
|
}
|
|
@@ -343,7 +373,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
343
373
|
{
|
|
344
374
|
type: CallMetaType.LOCAL_SDP,
|
|
345
375
|
payload: localSDP,
|
|
346
|
-
},
|
|
376
|
+
},
|
|
377
|
+
this.userId,
|
|
378
|
+
undefined,
|
|
379
|
+
sample.timestamp
|
|
380
|
+
);
|
|
347
381
|
|
|
348
382
|
this.reports.addCallMetaReport(callMetaReport);
|
|
349
383
|
}
|
|
@@ -368,6 +402,17 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
368
402
|
this._left = timestamp;
|
|
369
403
|
break;
|
|
370
404
|
}
|
|
405
|
+
case CallEventType.CLIENT_ISSUE: {
|
|
406
|
+
const severity = callEvent.value ? callEvent.value as ClientIssue['severity'] : 'minor';
|
|
407
|
+
|
|
408
|
+
this.emit('issue', {
|
|
409
|
+
severity,
|
|
410
|
+
timestamp: timestamp ?? Date.now(),
|
|
411
|
+
description: callEvent.message,
|
|
412
|
+
peerConnectionId: callEvent.peerConnectionId,
|
|
413
|
+
trackId: callEvent.mediaTrackId,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
371
416
|
}
|
|
372
417
|
this.reports.addCallEventReport({
|
|
373
418
|
serviceId: this.serviceId,
|
|
@@ -390,10 +435,13 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
390
435
|
this.clientId, {
|
|
391
436
|
type: CallMetaType.USER_MEDIA_ERROR,
|
|
392
437
|
payload: userMediaError,
|
|
393
|
-
},
|
|
438
|
+
},
|
|
439
|
+
this.userId,
|
|
440
|
+
);
|
|
394
441
|
|
|
395
442
|
this.reports.addCallMetaReport(callMetaReport);
|
|
396
443
|
this.userMediaErrors.push(userMediaError);
|
|
444
|
+
this.emit('usermediaerror', userMediaError);
|
|
397
445
|
}
|
|
398
446
|
|
|
399
447
|
for (const certificate of sample.certificates ?? []) {
|
|
@@ -405,7 +453,9 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
405
453
|
this.clientId, {
|
|
406
454
|
type: CallMetaType.CERTIFICATE,
|
|
407
455
|
payload: certificate,
|
|
408
|
-
},
|
|
456
|
+
},
|
|
457
|
+
this.userId
|
|
458
|
+
);
|
|
409
459
|
|
|
410
460
|
this.reports.addCallMetaReport(callMetaReport);
|
|
411
461
|
}
|
|
@@ -606,7 +656,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
606
656
|
continue;
|
|
607
657
|
}
|
|
608
658
|
|
|
609
|
-
peerConnection.ICE.addLocalCandidate(iceLocalCandidate);
|
|
659
|
+
peerConnection.ICE.addLocalCandidate(iceLocalCandidate, sample.timestamp);
|
|
610
660
|
}
|
|
611
661
|
|
|
612
662
|
for (const iceRemoteCandidate of sample.iceRemoteCandidates ?? []) {
|
|
@@ -621,7 +671,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
621
671
|
continue;
|
|
622
672
|
}
|
|
623
673
|
|
|
624
|
-
peerConnection.ICE.addRemoteCandidate(iceRemoteCandidate);
|
|
674
|
+
peerConnection.ICE.addRemoteCandidate(iceRemoteCandidate, sample.timestamp);
|
|
625
675
|
}
|
|
626
676
|
|
|
627
677
|
for (const candidatePair of sample.iceCandidatePairs ?? []) {
|
package/src/ObservedICE.ts
CHANGED
|
@@ -100,7 +100,7 @@ export class ObservedICE extends EventEmitter {
|
|
|
100
100
|
this.emit('close');
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
public addLocalCandidate(candidate: IceLocalCandidate) {
|
|
103
|
+
public addLocalCandidate(candidate: IceLocalCandidate, sampleTimestamp?: number) {
|
|
104
104
|
if (!candidate.id) return;
|
|
105
105
|
|
|
106
106
|
const newCandidate = !this._localCandidates.has(candidate.id);
|
|
@@ -116,7 +116,11 @@ export class ObservedICE extends EventEmitter {
|
|
|
116
116
|
this.peerConnection.client.clientId, {
|
|
117
117
|
type: CallMetaType.ICE_LOCAL_CANDIDATE,
|
|
118
118
|
payload: candidate,
|
|
119
|
-
},
|
|
119
|
+
},
|
|
120
|
+
this.peerConnection.client.userId,
|
|
121
|
+
this.peerConnection.peerConnectionId,
|
|
122
|
+
sampleTimestamp,
|
|
123
|
+
);
|
|
120
124
|
|
|
121
125
|
this.reports.addCallMetaReport(callMetaReport);
|
|
122
126
|
|
|
@@ -124,7 +128,7 @@ export class ObservedICE extends EventEmitter {
|
|
|
124
128
|
}
|
|
125
129
|
}
|
|
126
130
|
|
|
127
|
-
public addRemoteCandidate(candidate: IceRemoteCandidate) {
|
|
131
|
+
public addRemoteCandidate(candidate: IceRemoteCandidate, sampleTimestamp?: number) {
|
|
128
132
|
if (!candidate.id) return;
|
|
129
133
|
|
|
130
134
|
const newCandidate = !this._remoteCandidates.has(candidate.id);
|
|
@@ -140,7 +144,11 @@ export class ObservedICE extends EventEmitter {
|
|
|
140
144
|
this.peerConnection.client.clientId, {
|
|
141
145
|
type: CallMetaType.ICE_REMOTE_CANDIDATE,
|
|
142
146
|
payload: candidate,
|
|
143
|
-
},
|
|
147
|
+
},
|
|
148
|
+
this.peerConnection.client.userId,
|
|
149
|
+
this.peerConnection.peerConnectionId,
|
|
150
|
+
sampleTimestamp
|
|
151
|
+
);
|
|
144
152
|
|
|
145
153
|
this.reports.addCallMetaReport(callMetaReport);
|
|
146
154
|
|
|
@@ -12,6 +12,7 @@ export type ObservedOutboundTrackModel<K extends MediaKind> = {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export type ObservedOutboundTrackEvents = {
|
|
15
|
+
qualitylimitationchanged: [string];
|
|
15
16
|
update: [{
|
|
16
17
|
elapsedTimeInMs: number;
|
|
17
18
|
}],
|
|
@@ -197,6 +198,14 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
197
198
|
if (videoSample?.framesSent && lastVideoStats?.framesSent && lastVideoStats.framesSent < videoSample.framesSent) {
|
|
198
199
|
deltaSentFrames = videoSample.framesSent - lastVideoStats.framesSent;
|
|
199
200
|
}
|
|
201
|
+
|
|
202
|
+
if (videoSample.qualityLimitationReason && lastVideoStats?.qualityLimitationReason !== videoSample.qualityLimitationReason) {
|
|
203
|
+
this.emit('qualitylimitationchanged', videoSample.qualityLimitationReason);
|
|
204
|
+
}
|
|
205
|
+
} else if (this.kind === 'audio') {
|
|
206
|
+
// const audioSample = sample as OutboundAudioTrack;
|
|
207
|
+
// const lastAudioStats = lastStat as OutboundAudioTrack | undefined;
|
|
208
|
+
|
|
200
209
|
}
|
|
201
210
|
const stats: ObservedOutboundTrackStats<Kind> = {
|
|
202
211
|
...sample,
|
package/src/ObservedSfu.ts
CHANGED
|
@@ -105,6 +105,8 @@ export class ObservedSfu<AppData extends Record<string, unknown> = Record<string
|
|
|
105
105
|
this._timeZoneOffsetInHours = sample.timeZoneOffsetInHours;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
this._marker = sample.marker;
|
|
109
|
+
|
|
108
110
|
const now = Date.now();
|
|
109
111
|
const elapsedTimeInMs = now - this._updated;
|
|
110
112
|
|
package/src/Observer.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { PartialBy } from './common/utils';
|
|
|
6
6
|
import { createCallEndedEventReport, createCallStartedEventReport } from './common/callEventReports';
|
|
7
7
|
import { ObserverSinkContext } from './common/types';
|
|
8
8
|
import { ObservedSfu, ObservedSfuModel } from './ObservedSfu';
|
|
9
|
-
import { CallSummaryMonitor } from './monitors/CallSummaryMonitor';
|
|
9
|
+
import { CallSummaryMonitor, CallSummaryMonitorConfig } from './monitors/CallSummaryMonitor';
|
|
10
10
|
import { TurnUsageMonitor } from './monitors/TurnUsageMonitor';
|
|
11
11
|
import { ObservedClient } from './ObservedClient';
|
|
12
12
|
import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
@@ -104,13 +104,19 @@ export class Observer extends EventEmitter {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
public createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(
|
|
107
|
-
config: PartialBy<ObservedCallModel, 'serviceId'> & { appData: T, started?: number }
|
|
107
|
+
config: PartialBy<ObservedCallModel, 'serviceId'> & { appData: T, started?: number, reportCallStarted?: boolean, reportCallEnded?: boolean }
|
|
108
108
|
): ObservedCall<T> {
|
|
109
109
|
if (this._closed) {
|
|
110
110
|
throw new Error('Attempted to create a call source on a closed observer');
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
const {
|
|
113
|
+
const {
|
|
114
|
+
appData,
|
|
115
|
+
started = Date.now(),
|
|
116
|
+
reportCallEnded = true,
|
|
117
|
+
reportCallStarted = true,
|
|
118
|
+
...model
|
|
119
|
+
} = config;
|
|
114
120
|
const call = new ObservedCall({
|
|
115
121
|
...model,
|
|
116
122
|
serviceId: this.config.defaultServiceId,
|
|
@@ -121,7 +127,7 @@ export class Observer extends EventEmitter {
|
|
|
121
127
|
|
|
122
128
|
call.once('close', () => {
|
|
123
129
|
this._observedCalls.delete(call.callId);
|
|
124
|
-
this.reports.addCallEventReport(createCallEndedEventReport(
|
|
130
|
+
reportCallEnded && this.reports.addCallEventReport(createCallEndedEventReport(
|
|
125
131
|
call.serviceId,
|
|
126
132
|
call.roomId,
|
|
127
133
|
call.callId,
|
|
@@ -130,7 +136,7 @@ export class Observer extends EventEmitter {
|
|
|
130
136
|
});
|
|
131
137
|
|
|
132
138
|
this._observedCalls.set(call.callId, call);
|
|
133
|
-
this.reports.addCallEventReport(createCallStartedEventReport(
|
|
139
|
+
reportCallStarted && this.reports.addCallEventReport(createCallStartedEventReport(
|
|
134
140
|
call.serviceId,
|
|
135
141
|
call.roomId,
|
|
136
142
|
call.callId,
|
|
@@ -165,14 +171,14 @@ export class Observer extends EventEmitter {
|
|
|
165
171
|
return sfu;
|
|
166
172
|
}
|
|
167
173
|
|
|
168
|
-
public createCallSummaryMonitor(options?: { timeoutAfterCallClose?: number }): CallSummaryMonitor {
|
|
174
|
+
public createCallSummaryMonitor(options?: CallSummaryMonitorConfig & { timeoutAfterCallClose?: number }): CallSummaryMonitor {
|
|
169
175
|
if (this._closed) throw new Error('Cannot create a call summary monitor on a closed observer');
|
|
170
176
|
|
|
171
177
|
const existingMonitor = this._monitors.get(CallSummaryMonitor.name);
|
|
172
178
|
|
|
173
179
|
if (existingMonitor) return existingMonitor as CallSummaryMonitor;
|
|
174
180
|
|
|
175
|
-
const monitor = new CallSummaryMonitor();
|
|
181
|
+
const monitor = new CallSummaryMonitor(options);
|
|
176
182
|
const onNewCall = (call: ObservedCall) => {
|
|
177
183
|
monitor.addCall(call);
|
|
178
184
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// eslint-disable-next-line no-shadow
|
|
2
|
-
|
|
3
2
|
export enum CallEventType {
|
|
4
3
|
CALL_STARTED = 'CALL_STARTED',
|
|
5
4
|
CALL_ENDED = 'CALL_ENDED',
|
|
@@ -20,4 +19,5 @@ export enum CallEventType {
|
|
|
20
19
|
DATA_CHANNEL_ERROR = 'DATA_CHANNEL_ERROR',
|
|
21
20
|
NEGOTIATION_NEEDED = 'NEGOTIATION_NEEDED',
|
|
22
21
|
SIGNALING_STATE_CHANGE = 'SIGNALING_STATE_CHANGE',
|
|
22
|
+
CLIENT_ISSUE = 'CLIENT_ISSUE',
|
|
23
23
|
}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
import { ClientIssue } from '../ObservedClient';
|
|
2
|
+
|
|
1
3
|
export interface ClientSummary {
|
|
2
4
|
clientId: string;
|
|
3
5
|
mediaUnitId: string;
|
|
4
6
|
userId?: string;
|
|
5
7
|
joined: number;
|
|
8
|
+
left?: number;
|
|
6
9
|
durationInMs: number;
|
|
7
10
|
avgOutboundAudioBitrate: number,
|
|
8
11
|
avgOutboundVideoBitrate: number,
|
|
9
12
|
avgInboundAudioBitrate: number,
|
|
10
13
|
avgInboundVideoBitrate: number,
|
|
11
14
|
ewmaRttInMs: number,
|
|
15
|
+
usedTurn: boolean;
|
|
16
|
+
issues: ClientIssue[];
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
export interface CallSummary {
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import { CallSummary } from './CallSummary';
|
|
2
|
+
import { CallSummary, ClientSummary } from './CallSummary';
|
|
3
3
|
import { ObservedCall } from '../ObservedCall';
|
|
4
|
-
import { ObservedClient } from '../ObservedClient';
|
|
4
|
+
import { ClientIssue, ObservedClient } from '../ObservedClient';
|
|
5
|
+
import { ObservedOutboundTrack } from '../ObservedOutboundTrack';
|
|
6
|
+
import { ObservedPeerConnection } from '../ObservedPeerConnection';
|
|
5
7
|
|
|
6
8
|
export type CallSummaryMonitorEvents = {
|
|
7
9
|
close: [],
|
|
8
10
|
summary: [CallSummary],
|
|
9
11
|
}
|
|
10
12
|
|
|
13
|
+
export type CallSummaryMonitorConfig = {
|
|
14
|
+
detectUserMediaIssues?: boolean;
|
|
15
|
+
detectMediaTrackQualityLimitationIssues?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
11
18
|
export declare interface CallSummaryMonitor {
|
|
12
19
|
on<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
|
|
13
20
|
off<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
|
|
@@ -19,7 +26,9 @@ export class CallSummaryMonitor extends EventEmitter {
|
|
|
19
26
|
private readonly _summaries = new Map<string, CallSummary>();
|
|
20
27
|
|
|
21
28
|
private _closed = false;
|
|
22
|
-
public constructor(
|
|
29
|
+
public constructor(
|
|
30
|
+
public readonly config: CallSummaryMonitorConfig = {},
|
|
31
|
+
) {
|
|
23
32
|
super();
|
|
24
33
|
}
|
|
25
34
|
|
|
@@ -50,7 +59,7 @@ export class CallSummaryMonitor extends EventEmitter {
|
|
|
50
59
|
|
|
51
60
|
private _addClient(callSummary: CallSummary, client: ObservedClient) {
|
|
52
61
|
if (this.closed) return;
|
|
53
|
-
const clientSummary = {
|
|
62
|
+
const clientSummary: ClientSummary = {
|
|
54
63
|
clientId: client.clientId,
|
|
55
64
|
mediaUnitId: client.mediaUnitId,
|
|
56
65
|
durationInMs: 0,
|
|
@@ -61,6 +70,8 @@ export class CallSummaryMonitor extends EventEmitter {
|
|
|
61
70
|
ewmaRttInMs: 0,
|
|
62
71
|
joined: client.created,
|
|
63
72
|
userId: client.userId,
|
|
73
|
+
usedTurn: false,
|
|
74
|
+
issues: [],
|
|
64
75
|
};
|
|
65
76
|
|
|
66
77
|
callSummary.clients.push(clientSummary);
|
|
@@ -71,7 +82,34 @@ export class CallSummaryMonitor extends EventEmitter {
|
|
|
71
82
|
}
|
|
72
83
|
};
|
|
73
84
|
|
|
85
|
+
const onUsingTurn = (usingTurn: boolean) => {
|
|
86
|
+
clientSummary.usedTurn ||= usingTurn;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const onIssue = (issue: ClientIssue) => {
|
|
90
|
+
clientSummary.issues.push(issue);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const onUserMediaError = (error: string) => {
|
|
94
|
+
if (!this.config.detectUserMediaIssues) return;
|
|
95
|
+
|
|
96
|
+
// maybe the client also sned this issue, in which case the timestamp can be more accurate
|
|
97
|
+
const alreadyDetected = clientSummary.issues.find((issue) => issue.severity === 'critical' && issue.description === error);
|
|
98
|
+
|
|
99
|
+
!alreadyDetected && clientSummary.issues.push({
|
|
100
|
+
severity: 'critical',
|
|
101
|
+
timestamp: Date.now(),
|
|
102
|
+
description: error,
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const onNewPeerConnection = (peerConnection: ObservedPeerConnection) => this._addPeerConnection(clientSummary, peerConnection);
|
|
107
|
+
|
|
74
108
|
client.on('update', updateClient);
|
|
109
|
+
client.on('usingturn', onUsingTurn);
|
|
110
|
+
client.on('issue', onIssue);
|
|
111
|
+
client.on('usermediaerror', onUserMediaError);
|
|
112
|
+
client.on('newpeerconnection', onNewPeerConnection);
|
|
75
113
|
client.once('close', () => {
|
|
76
114
|
const elapsedTimeInS = (Date.now() - client.created) / 1000;
|
|
77
115
|
|
|
@@ -81,7 +119,41 @@ export class CallSummaryMonitor extends EventEmitter {
|
|
|
81
119
|
clientSummary.avgOutboundVideoBitrate = (client.totalSentBytes * 8) / elapsedTimeInS;
|
|
82
120
|
clientSummary.durationInMs = elapsedTimeInS * 1000;
|
|
83
121
|
client.off('update', updateClient);
|
|
122
|
+
client.off('usingturn', onUsingTurn);
|
|
123
|
+
client.off('issue', onIssue);
|
|
124
|
+
client.off('usermediaerror', onUserMediaError);
|
|
125
|
+
client.off('newpeerconnection', onNewPeerConnection);
|
|
126
|
+
|
|
127
|
+
callSummary.durationInMs += clientSummary.durationInMs;
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private _addPeerConnection(clientSummary: ClientSummary, peerConnection: ObservedPeerConnection) {
|
|
132
|
+
const onOutboundVideoTrack = (track: ObservedOutboundTrack<'video'>) => this._addOutboundVideoTrack(clientSummary, track);
|
|
133
|
+
|
|
134
|
+
peerConnection.on('newoutboundvideotrack', onOutboundVideoTrack);
|
|
135
|
+
peerConnection.once('close', () => {
|
|
136
|
+
peerConnection.off('newoutboundvideotrack', onOutboundVideoTrack);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private _addOutboundVideoTrack(clientSummary: ClientSummary, track: ObservedOutboundTrack<'video'>) {
|
|
141
|
+
const onQualityLimitationChanged = (reason: string) => {
|
|
142
|
+
if (!this.config.detectMediaTrackQualityLimitationIssues) return;
|
|
143
|
+
|
|
144
|
+
clientSummary.issues.push({
|
|
145
|
+
severity: 'minor',
|
|
146
|
+
timestamp: Date.now(),
|
|
147
|
+
description: reason,
|
|
148
|
+
peerConnectionId: track.peerConnectionId,
|
|
149
|
+
trackId: track.trackId,
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
track.once('close', () => {
|
|
154
|
+
track.off('qualitylimitationchanged', onQualityLimitationChanged);
|
|
84
155
|
});
|
|
156
|
+
track.on('qualitylimitationchanged', onQualityLimitationChanged);
|
|
85
157
|
}
|
|
86
158
|
|
|
87
159
|
public takeSummary(callId: string): CallSummary | undefined {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
import { ObservedPeerConnection } from '../ObservedPeerConnection';
|
|
3
3
|
import { ObservedICEEvents } from '../ObservedICE';
|
|
4
|
+
import { ObservedClient } from '../ObservedClient';
|
|
4
5
|
|
|
5
6
|
export type TurnUsageMonitorEvents = {
|
|
6
7
|
close: [],
|
|
@@ -111,6 +112,18 @@ export class TurnUsageMonitor extends EventEmitter {
|
|
|
111
112
|
return this._turnUsage.get(turnIp);
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
public get clients(): ReadonlyMap<string, ObservedClient> {
|
|
116
|
+
const result = new Map<string, ObservedClient>();
|
|
117
|
+
|
|
118
|
+
for (const pc of this.peerConnections) {
|
|
119
|
+
if (result.has(pc.clientId)) continue;
|
|
120
|
+
|
|
121
|
+
result.set(pc.clientId, pc.client);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
114
127
|
public get closed() {
|
|
115
128
|
return this._closed;
|
|
116
129
|
}
|