@observertc/observer-js 0.42.0 → 0.42.2
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/ObservedCall.d.ts +5 -10
- package/lib/ObservedCall.d.ts.map +1 -1
- package/lib/ObservedCall.js +17 -22
- package/lib/ObservedClient.d.ts +20 -8
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +96 -27
- package/lib/ObservedInboundAudioTrack.d.ts +2 -0
- package/lib/ObservedInboundAudioTrack.d.ts.map +1 -1
- package/lib/ObservedInboundAudioTrack.js +2 -0
- package/lib/ObservedInboundVideoTrack.d.ts +4 -1
- package/lib/ObservedInboundVideoTrack.d.ts.map +1 -1
- package/lib/ObservedInboundVideoTrack.js +2 -1
- package/lib/ObservedOutboundAudioTrack.d.ts +2 -0
- package/lib/ObservedOutboundAudioTrack.d.ts.map +1 -1
- package/lib/ObservedOutboundAudioTrack.js +2 -12
- package/lib/ObservedOutboundVideoTrack.d.ts +4 -1
- package/lib/ObservedOutboundVideoTrack.d.ts.map +1 -1
- package/lib/ObservedOutboundVideoTrack.js +2 -1
- package/lib/ObservedPeerConnection.d.ts +2 -0
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/Observer.d.ts +0 -1
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +5 -3
- package/lib/common/CalculatedScore.js +3 -3
- package/lib/common/types.d.ts +1 -0
- package/lib/common/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ObservedCall.ts +35 -41
- package/src/ObservedClient.ts +117 -35
- package/src/ObservedInboundAudioTrack.ts +8 -0
- package/src/ObservedInboundVideoTrack.ts +10 -1
- package/src/ObservedOutboundAudioTrack.ts +8 -16
- package/src/ObservedOutboundVideoTrack.ts +10 -1
- package/src/ObservedPeerConnection.ts +6 -1
- package/src/Observer.ts +3 -4
- package/src/common/CalculatedScore.ts +1 -1
- package/src/common/types.ts +1 -0
- package/lib/monitors/ClientQualityMonitor.d.ts +0 -1
- package/lib/monitors/ClientQualityMonitor.d.ts.map +0 -1
- package/lib/monitors/ClientQualityMonitor.js +0 -1
- package/src/monitors/ClientQualityMonitor.ts +0 -0
|
@@ -11,7 +11,6 @@ class ObservedOutboundVideoTrack extends events_1.EventEmitter {
|
|
|
11
11
|
this.created = Date.now();
|
|
12
12
|
this.visited = false;
|
|
13
13
|
this.contentType = 'standard';
|
|
14
|
-
this.codec = 'vp8';
|
|
15
14
|
this.bitrate = 0;
|
|
16
15
|
this.totalLostPackets = 0;
|
|
17
16
|
this.totalSentPackets = 0;
|
|
@@ -135,6 +134,8 @@ class ObservedOutboundVideoTrack extends events_1.EventEmitter {
|
|
|
135
134
|
// this.deltaSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentBytes, 0);
|
|
136
135
|
// setting up sfu connection as it is not always available at the first sample
|
|
137
136
|
this.visited = true;
|
|
137
|
+
// a peer connection is active if it has at least one active track
|
|
138
|
+
this.peerConnection.visited = true;
|
|
138
139
|
this._updated = now;
|
|
139
140
|
this.emit('update', {
|
|
140
141
|
elapsedTimeInMs,
|
|
@@ -42,6 +42,8 @@ export declare class ObservedPeerConnection extends EventEmitter {
|
|
|
42
42
|
readonly client: ObservedClient;
|
|
43
43
|
readonly created: number;
|
|
44
44
|
visited: boolean;
|
|
45
|
+
opened?: number;
|
|
46
|
+
closedTimestamp?: number;
|
|
45
47
|
private _elapsedTimeSinceLastUpdate?;
|
|
46
48
|
private _statsTimestamp?;
|
|
47
49
|
ωpendingIssuesForScores: ClientIssue[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedPeerConnection.d.ts","sourceRoot":"","sources":["../src/ObservedPeerConnection.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAiC,MAAM,+BAA+B,CAAC;AAC/F,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AACxG,OAAO,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AACxG,OAAO,EAAE,0BAA0B,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAC3G,OAAO,EAAE,0BAA0B,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAC3G,OAAO,EAAE,eAAe,EAAuB,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,MAAM,4BAA4B,GAAG;IAC1C,MAAM,EAAE;QAAC;YACR,eAAe,EAAE,MAAM,CAAC;SACxB;KAAC,CAAC;IACH,KAAK,EAAE,EAAE,CAAC;IACV,KAAK,EAAE,CAAC,eAAe,CAAC,CAAC;IACzB,mBAAmB,EAAE,CAAC,yBAAyB,CAAC,CAAC;IACjD,mBAAmB,EAAE,CAAC,yBAAyB,CAAC,CAAC;IACjD,qBAAqB,EAAE,CAAC,0BAA0B,CAAC,CAAC;IACpD,qBAAqB,EAAE,CAAC,0BAA0B,CAAC,CAAC;IACpD,cAAc,EAAE,CAAC,mBAAmB,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC;AAEjG,MAAM,CAAC,OAAO,WAAW,sBAAsB;IAC9C,EAAE,CAAC,CAAC,SAAS,MAAM,4BAA4B,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/H,GAAG,CAAC,CAAC,SAAS,MAAM,4BAA4B,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAChI,IAAI,CAAC,CAAC,SAAS,MAAM,4BAA4B,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACjI,IAAI,CAAC,CAAC,SAAS,MAAM,4BAA4B,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CAChH;AAED,qBAAa,sBAAuB,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"ObservedPeerConnection.d.ts","sourceRoot":"","sources":["../src/ObservedPeerConnection.ts"],"names":[],"mappings":"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"}
|
package/lib/Observer.d.ts
CHANGED
|
@@ -51,7 +51,6 @@ export declare class Observer extends EventEmitter {
|
|
|
51
51
|
constructor(config: ObserverConfig);
|
|
52
52
|
createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(config: PartialBy<ObservedCallModel, 'serviceId'> & {
|
|
53
53
|
appData: T;
|
|
54
|
-
started?: number;
|
|
55
54
|
reportCallStarted?: boolean;
|
|
56
55
|
reportCallEnded?: boolean;
|
|
57
56
|
}): ObservedCall<T>;
|
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,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAI/D,MAAM,MAAM,cAAc,GAAG;IAC5B,SAAS,EAAE,CAAC,YAAY,CAAC,CAAC;IAC1B,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC;IACxB,SAAS,EAAE,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,EAAE,EAAE,CAAC;CACZ,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAE5B;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,QAAQ;IAChC,EAAE,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACnG,GAAG,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACpG,IAAI,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACrG,IAAI,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACpF;AAED,qBAAa,QAAS,SAAQ,YAAY;aA2BxB,MAAM,EAAE,cAAc;WA1BzB,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,QAAQ;IAkBvE,SAAgB,OAAO,mBAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmC;IAClE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsF;IAEhH,OAAO,CAAC,YAAY,CAAC,CAAgC;IACrD,OAAO,CAAC,OAAO,CAAS;gBAEP,MAAM,EAAE,cAAc;IAyBhC,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpF,MAAM,EAAE,SAAS,CAAC,iBAAiB,EAAE,WAAW,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC,CAAC;QAAC,
|
|
1
|
+
{"version":3,"file":"Observer.d.ts","sourceRoot":"","sources":["../src/Observer.ts"],"names":[],"mappings":"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"}
|
package/lib/Observer.js
CHANGED
|
@@ -64,21 +64,23 @@ class Observer extends events_1.EventEmitter {
|
|
|
64
64
|
this.reports.on('reports', onReports);
|
|
65
65
|
}
|
|
66
66
|
createObservedCall(config) {
|
|
67
|
+
var _a;
|
|
67
68
|
if (this._closed) {
|
|
68
69
|
throw new Error('Attempted to create a call source on a closed observer');
|
|
69
70
|
}
|
|
70
|
-
const { appData,
|
|
71
|
+
const { appData, reportCallEnded = true, reportCallStarted = true } = config, model = __rest(config, ["appData", "reportCallEnded", "reportCallStarted"]);
|
|
71
72
|
const call = new ObservedCall_1.ObservedCall(Object.assign(Object.assign({}, model), { serviceId: this.config.defaultServiceId }), this, appData);
|
|
72
73
|
if (this._closed)
|
|
73
74
|
throw new Error('Cannot create an observed call on a closed observer');
|
|
74
75
|
if (this._observedCalls.has(call.callId))
|
|
75
76
|
throw new Error(`Observed Call with id ${call.callId} already exists`);
|
|
76
77
|
call.once('close', () => {
|
|
78
|
+
var _a;
|
|
77
79
|
this._observedCalls.delete(call.callId);
|
|
78
|
-
reportCallEnded && this.reports.addCallEventReport((0, callEventReports_1.createCallEndedEventReport)(call.serviceId, call.roomId, call.callId, Date.now()));
|
|
80
|
+
reportCallEnded && this.reports.addCallEventReport((0, callEventReports_1.createCallEndedEventReport)(call.serviceId, call.roomId, call.callId, (_a = call.ended) !== null && _a !== void 0 ? _a : Date.now()));
|
|
79
81
|
});
|
|
80
82
|
this._observedCalls.set(call.callId, call);
|
|
81
|
-
reportCallStarted && this.reports.addCallEventReport((0, callEventReports_1.createCallStartedEventReport)(call.serviceId, call.roomId, call.callId, started));
|
|
83
|
+
reportCallStarted && this.reports.addCallEventReport((0, callEventReports_1.createCallStartedEventReport)(call.serviceId, call.roomId, call.callId, (_a = call.started) !== null && _a !== void 0 ? _a : Date.now()));
|
|
82
84
|
this.emit('newcall', call);
|
|
83
85
|
return call;
|
|
84
86
|
}
|
|
@@ -38,7 +38,7 @@ exports.BPP_RANGES = {
|
|
|
38
38
|
},
|
|
39
39
|
};
|
|
40
40
|
function calculateBaseVideoScore(track, newIssues) {
|
|
41
|
-
var _a;
|
|
41
|
+
var _a, _b;
|
|
42
42
|
if (!track.highestLayer) {
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
@@ -58,7 +58,7 @@ function calculateBaseVideoScore(track, newIssues) {
|
|
|
58
58
|
}
|
|
59
59
|
const bpp = bitrate / (frameHeight * frameWidth * framesPerSecond);
|
|
60
60
|
// let's assume vp8 for now
|
|
61
|
-
const bppRange = exports.BPP_RANGES[track.contentType][track.codec];
|
|
61
|
+
const bppRange = exports.BPP_RANGES[track.contentType][(_a = track.codec) !== null && _a !== void 0 ? _a : 'vp8'];
|
|
62
62
|
if (bpp / 2 < bppRange.low) {
|
|
63
63
|
score.score = 1.0;
|
|
64
64
|
score.remarks.push({
|
|
@@ -92,7 +92,7 @@ function calculateBaseVideoScore(track, newIssues) {
|
|
|
92
92
|
}
|
|
93
93
|
score.remarks.push({
|
|
94
94
|
severity: issue.severity,
|
|
95
|
-
text: (
|
|
95
|
+
text: (_b = issue.description) !== null && _b !== void 0 ? _b : 'Issue occurred',
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
return score;
|
package/lib/common/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CallEventReport, CallMetaReport, ClientDataChannelReport, ClientExtensionReport, IceCandidatePairReport, InboundAudioTrackReport, InboundVideoTrackReport, ObserverEventReport, OutboundAudioTrackReport, OutboundVideoTrackReport, PeerConnectionTransportReport, SfuEventReport, SfuExtensionReport, SfuInboundRtpPadReport, SfuMetaReport, SfuOutboundRtpPadReport, SfuSctpStreamReport, SFUTransportReport } from '@observertc/report-schemas-js';
|
|
2
2
|
export type MediaKind = 'audio' | 'video';
|
|
3
|
+
export type SupportedVideoCodecType = 'vp8' | 'vp9' | 'h264' | 'h265';
|
|
3
4
|
export interface ObserverSinkContext {
|
|
4
5
|
readonly callEventReports: CallEventReport[];
|
|
5
6
|
readonly callMetaReports: CallMetaReport[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,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,EAClB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,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,EAClB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1C,MAAM,MAAM,uBAAuB,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAItE,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IAC7C,QAAQ,CAAC,eAAe,EAAE,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;IAC7D,QAAQ,CAAC,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;IACzD,QAAQ,CAAC,uBAAuB,EAAE,sBAAsB,EAAE,CAAC;IAC3D,QAAQ,CAAC,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;IAC7D,QAAQ,CAAC,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;IAC7D,QAAQ,CAAC,8BAA8B,EAAE,6BAA6B,EAAE,CAAC;IACzE,QAAQ,CAAC,oBAAoB,EAAE,mBAAmB,EAAE,CAAC;IACrD,QAAQ,CAAC,yBAAyB,EAAE,wBAAwB,EAAE,CAAC;IAC/D,QAAQ,CAAC,yBAAyB,EAAE,wBAAwB,EAAE,CAAC;IAC/D,QAAQ,CAAC,eAAe,EAAE,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IACnD,QAAQ,CAAC,uBAAuB,EAAE,sBAAsB,EAAE,CAAC;IAC3D,QAAQ,CAAC,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;IAC7D,QAAQ,CAAC,oBAAoB,EAAE,mBAAmB,EAAE,CAAC;IACrD,QAAQ,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IACnD,QAAQ,CAAC,cAAc,EAAE,aAAa,EAAE,CAAC;CACzC"}
|
package/package.json
CHANGED
package/src/ObservedCall.ts
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import { ObservedClient,
|
|
2
|
+
import { ObservedClient, ObservedClientModel } from './ObservedClient';
|
|
3
3
|
import { Observer } from './Observer';
|
|
4
|
-
import { createClientJoinedEventReport } from './common/callEventReports';
|
|
4
|
+
import { createClientJoinedEventReport, createClientLeftEventReport } from './common/callEventReports';
|
|
5
5
|
import { getMedian, PartialBy } from './common/utils';
|
|
6
6
|
import { CallEventReport } from '@observertc/report-schemas-js';
|
|
7
7
|
import { createProcessor } from './common/Middleware';
|
|
8
8
|
import { ClientSample } from '@observertc/sample-schemas-js';
|
|
9
|
-
import { ClientIssue } from './monitors/CallSummary';
|
|
10
9
|
import { ObservedOutboundAudioTrack } from './ObservedOutboundAudioTrack';
|
|
11
10
|
import { ObservedOutboundVideoTrack } from './ObservedOutboundVideoTrack';
|
|
12
11
|
import { CalculatedScore } from './common/CalculatedScore';
|
|
13
12
|
|
|
14
|
-
type ClientIssueDetectionConfig = Pick<ClientIssue, 'severity'>;
|
|
15
|
-
|
|
16
13
|
export type ObservedCallModel = {
|
|
17
14
|
serviceId: string;
|
|
18
15
|
roomId: string;
|
|
@@ -49,7 +46,8 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
49
46
|
public readonly sfuStreamIdToOutboundVideoTrack = new Map<string | number, ObservedOutboundVideoTrack>();
|
|
50
47
|
private _closed = false;
|
|
51
48
|
private _updated = Date.now();
|
|
52
|
-
|
|
49
|
+
public ended?: number;
|
|
50
|
+
public started?: number = Date.now();
|
|
53
51
|
|
|
54
52
|
public constructor(
|
|
55
53
|
private readonly _model: ObservedCallModel,
|
|
@@ -83,10 +81,6 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
83
81
|
return this._updated;
|
|
84
82
|
}
|
|
85
83
|
|
|
86
|
-
public get ended() {
|
|
87
|
-
return this._ended;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
84
|
public get clients(): ReadonlyMap<string, ObservedClient> {
|
|
91
85
|
return this._clients;
|
|
92
86
|
}
|
|
@@ -127,7 +121,12 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
127
121
|
public close(timestamp?: number) {
|
|
128
122
|
if (this._closed) return;
|
|
129
123
|
this._closed = true;
|
|
130
|
-
|
|
124
|
+
|
|
125
|
+
if (timestamp) {
|
|
126
|
+
this.ended = timestamp;
|
|
127
|
+
} else if (!this.ended) {
|
|
128
|
+
this.ended = Date.now();
|
|
129
|
+
}
|
|
131
130
|
|
|
132
131
|
Array.from(this._clients.values()).forEach((client) => client.close());
|
|
133
132
|
|
|
@@ -146,21 +145,20 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
146
145
|
|
|
147
146
|
public createClient<ClientAppData extends Record<string, unknown> = Record<string, unknown>>(config: ObservedClientModel & {
|
|
148
147
|
appData: ClientAppData,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
148
|
+
// in case we generate the CLIENT_JOINED report we can set the timestamp of the event
|
|
149
|
+
// in that case we should set the client.left to the timestamp of the leaving.
|
|
150
|
+
// by default the timestamp is set to the current time
|
|
151
|
+
joinedTimestamp?: number,
|
|
152
|
+
createClientJoinedReport?: boolean,
|
|
153
|
+
createClientLeftReport?: boolean,
|
|
154
154
|
}) {
|
|
155
155
|
if (this._closed) throw new Error(`Call ${this.callId} is closed`);
|
|
156
156
|
|
|
157
157
|
const {
|
|
158
158
|
appData,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
rejoin: 'minor'
|
|
163
|
-
},
|
|
159
|
+
createClientJoinedReport,
|
|
160
|
+
createClientLeftReport,
|
|
161
|
+
joinedTimestamp = Date.now(),
|
|
164
162
|
...model
|
|
165
163
|
} = config;
|
|
166
164
|
|
|
@@ -180,37 +178,33 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
180
178
|
result.on('update', onUpdate);
|
|
181
179
|
this._clients.set(result.clientId, result);
|
|
182
180
|
|
|
183
|
-
if (
|
|
181
|
+
if (createClientJoinedReport) {
|
|
184
182
|
this.reports.addCallEventReport(createClientJoinedEventReport(
|
|
185
183
|
this.serviceId,
|
|
186
184
|
result.mediaUnitId,
|
|
187
185
|
this.roomId,
|
|
188
186
|
this.callId,
|
|
189
187
|
result.clientId,
|
|
190
|
-
joined,
|
|
188
|
+
result.joined ?? joinedTimestamp,
|
|
191
189
|
result.userId,
|
|
192
190
|
result.marker,
|
|
193
191
|
));
|
|
194
192
|
}
|
|
195
193
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
result.off('rejoined', rejoinedClientIssueListener);
|
|
211
|
-
});
|
|
212
|
-
result.on('rejoined', rejoinedClientIssueListener);
|
|
213
|
-
}
|
|
194
|
+
result.once('close', () => {
|
|
195
|
+
if (createClientLeftReport) {
|
|
196
|
+
this.reports.addCallEventReport(createClientLeftEventReport(
|
|
197
|
+
this.serviceId,
|
|
198
|
+
result.mediaUnitId,
|
|
199
|
+
this.roomId,
|
|
200
|
+
this.callId,
|
|
201
|
+
result.clientId,
|
|
202
|
+
result.left ?? Date.now(),
|
|
203
|
+
result.userId,
|
|
204
|
+
result.marker,
|
|
205
|
+
));
|
|
206
|
+
}
|
|
207
|
+
});
|
|
214
208
|
|
|
215
209
|
this.emit('newclient', result);
|
|
216
210
|
|
package/src/ObservedClient.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Browser, ClientSample, Engine, IceLocalCandidate, IceRemoteCandidate, OperationSystem, Platform } from '@observertc/sample-schemas-js';
|
|
1
|
+
import { Browser, ClientSample, Engine, IceLocalCandidate, IceRemoteCandidate, MediaCodecStats, MediaDevice, OperationSystem, Platform } from '@observertc/sample-schemas-js';
|
|
2
2
|
import { ObservedCall } from './ObservedCall';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
4
|
import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
@@ -6,7 +6,6 @@ import { createLogger } from './common/logger';
|
|
|
6
6
|
import { CallMetaType, createCallMetaReport } from './common/CallMetaReports';
|
|
7
7
|
// eslint-disable-next-line camelcase
|
|
8
8
|
import { PartialBy, isValidUuid } from './common/utils';
|
|
9
|
-
import { createClientLeftEventReport } from './common/callEventReports';
|
|
10
9
|
import { CallEventType } from './common/CallEventType';
|
|
11
10
|
import { ObservedSfu } from './ObservedSfu';
|
|
12
11
|
import { ClientIssue } from './monitors/CallSummary';
|
|
@@ -71,6 +70,19 @@ export declare interface ObservedClient<AppData extends Record<string, unknown>
|
|
|
71
70
|
readonly appData: AppData;
|
|
72
71
|
}
|
|
73
72
|
|
|
73
|
+
type PendingPeerConnectionTimestamp = {
|
|
74
|
+
type: 'opened' | 'closed'
|
|
75
|
+
peerConnectionId: string;
|
|
76
|
+
timestamp: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
type PendingMediaTrackTimestamp = {
|
|
80
|
+
type: 'added' | 'removed'
|
|
81
|
+
peerConnectionId: string;
|
|
82
|
+
mediaTrackId: string;
|
|
83
|
+
timestamp: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
74
86
|
export class ObservedClient<AppData extends Record<string, unknown> = Record<string, unknown>> extends EventEmitter {
|
|
75
87
|
|
|
76
88
|
public readonly created = Date.now();
|
|
@@ -81,10 +93,12 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
81
93
|
|
|
82
94
|
private _closed = false;
|
|
83
95
|
|
|
84
|
-
private _joinedEventAt?: number;
|
|
85
96
|
private _acceptedSamples = 0;
|
|
86
97
|
private _timeZoneOffsetInHours?: number;
|
|
87
|
-
|
|
98
|
+
|
|
99
|
+
// the timestamp of the CLIENT_JOINED event
|
|
100
|
+
public joined?: number;
|
|
101
|
+
public left?: number;
|
|
88
102
|
|
|
89
103
|
public score?: CalculatedScore;
|
|
90
104
|
public usingTURN = false;
|
|
@@ -117,14 +131,15 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
117
131
|
public outboundVideoBitrate?: number;
|
|
118
132
|
public inboundAudioBitrate?: number;
|
|
119
133
|
public inboundVideoBitrate?: number;
|
|
134
|
+
public mediaConstraints: string[] = [];
|
|
120
135
|
|
|
121
|
-
public readonly mediaDevices:
|
|
122
|
-
public readonly
|
|
136
|
+
public readonly mediaDevices: MediaDevice[] = [];
|
|
137
|
+
public readonly mediaCodecs: MediaCodecStats[] = [];
|
|
123
138
|
public readonly userMediaErrors: string[] = [];
|
|
124
139
|
public readonly issues: ClientIssue[] = [];
|
|
125
140
|
|
|
126
|
-
public
|
|
127
|
-
public
|
|
141
|
+
public ωpendingPeerConnectionTimestamps: PendingPeerConnectionTimestamp[] = [];
|
|
142
|
+
public ωpendingMediaTrackTimestamps: PendingMediaTrackTimestamp[] = [];
|
|
128
143
|
|
|
129
144
|
public constructor(
|
|
130
145
|
private readonly _model: ObservedClientModel,
|
|
@@ -238,9 +253,6 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
238
253
|
if (this._closed) return;
|
|
239
254
|
this._closed = true;
|
|
240
255
|
|
|
241
|
-
if (!this._left) {
|
|
242
|
-
this._addClientLeftReport();
|
|
243
|
-
}
|
|
244
256
|
Array.from(this._peerConnections.values()).forEach((peerConnection) => peerConnection.close());
|
|
245
257
|
|
|
246
258
|
this.emit('close');
|
|
@@ -453,6 +465,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
453
465
|
);
|
|
454
466
|
|
|
455
467
|
this.reports.addCallMetaReport(callMetaReport);
|
|
468
|
+
this.mediaConstraints.push(mediaConstraint);
|
|
456
469
|
}
|
|
457
470
|
|
|
458
471
|
for (const localSDP of sample.localSDPs ?? []) {
|
|
@@ -491,17 +504,56 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
491
504
|
for (const { timestamp, ...callEvent } of sample.customCallEvents ?? []) {
|
|
492
505
|
switch (callEvent.name) {
|
|
493
506
|
case CallEventType.CLIENT_JOINED: {
|
|
494
|
-
const lastJoined = this.
|
|
507
|
+
const lastJoined = this.joined;
|
|
495
508
|
|
|
496
|
-
this.
|
|
509
|
+
this.joined = timestamp;
|
|
497
510
|
|
|
498
|
-
if
|
|
511
|
+
// if it is joined before and it is joined again
|
|
512
|
+
if (lastJoined && this.joined && lastJoined !== this.joined) {
|
|
499
513
|
this.emit('rejoined', { lastJoined });
|
|
500
514
|
}
|
|
515
|
+
// in case we have a left event before the joined event
|
|
516
|
+
if (this.left && this.joined && this.left < this.joined) {
|
|
517
|
+
this.left = undefined;
|
|
518
|
+
}
|
|
501
519
|
break;
|
|
502
520
|
}
|
|
503
521
|
case CallEventType.CLIENT_LEFT: {
|
|
504
|
-
this.
|
|
522
|
+
this.left = timestamp;
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
case CallEventType.PEER_CONNECTION_OPENED: {
|
|
526
|
+
callEvent.peerConnectionId && this.ωpendingPeerConnectionTimestamps.push({
|
|
527
|
+
type: 'opened',
|
|
528
|
+
peerConnectionId: callEvent.peerConnectionId,
|
|
529
|
+
timestamp: timestamp ?? sample.timestamp,
|
|
530
|
+
});
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
case CallEventType.PEER_CONNECTION_CLOSED: {
|
|
534
|
+
callEvent.peerConnectionId && this.ωpendingPeerConnectionTimestamps.push({
|
|
535
|
+
type: 'closed',
|
|
536
|
+
peerConnectionId: callEvent.peerConnectionId,
|
|
537
|
+
timestamp: timestamp ?? sample.timestamp,
|
|
538
|
+
});
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
case CallEventType.MEDIA_TRACK_ADDED: {
|
|
542
|
+
callEvent.peerConnectionId && callEvent.mediaTrackId && this.ωpendingMediaTrackTimestamps.push({
|
|
543
|
+
type: 'added',
|
|
544
|
+
peerConnectionId: callEvent.peerConnectionId,
|
|
545
|
+
mediaTrackId: callEvent.mediaTrackId,
|
|
546
|
+
timestamp: timestamp ?? sample.timestamp,
|
|
547
|
+
});
|
|
548
|
+
break;
|
|
549
|
+
}
|
|
550
|
+
case CallEventType.MEDIA_TRACK_REMOVED: {
|
|
551
|
+
callEvent.peerConnectionId && callEvent.mediaTrackId && this.ωpendingMediaTrackTimestamps.push({
|
|
552
|
+
type: 'removed',
|
|
553
|
+
peerConnectionId: callEvent.peerConnectionId,
|
|
554
|
+
mediaTrackId: callEvent.mediaTrackId,
|
|
555
|
+
timestamp: timestamp ?? sample.timestamp,
|
|
556
|
+
});
|
|
505
557
|
break;
|
|
506
558
|
}
|
|
507
559
|
case CallEventType.CLIENT_ISSUE: {
|
|
@@ -592,7 +644,9 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
592
644
|
}, this.userId);
|
|
593
645
|
|
|
594
646
|
this.reports.addCallMetaReport(callMetaReport);
|
|
595
|
-
codec.mimeType && this.
|
|
647
|
+
if (codec.mimeType && !this.mediaCodecs.find((c) => c.mimeType === codec.mimeType)) {
|
|
648
|
+
this.mediaCodecs.push(codec);
|
|
649
|
+
}
|
|
596
650
|
}
|
|
597
651
|
|
|
598
652
|
for (const iceServer of sample.iceServers ?? []) {
|
|
@@ -619,9 +673,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
619
673
|
type: CallMetaType.MEDIA_DEVICE,
|
|
620
674
|
payload: mediaDevice,
|
|
621
675
|
}, this.userId);
|
|
622
|
-
|
|
676
|
+
|
|
623
677
|
this.reports.addCallMetaReport(callMetaReport);
|
|
624
|
-
mediaDevice.
|
|
678
|
+
if (mediaDevice.id && !this.mediaDevices.find((d) => d.id === mediaDevice.id)) {
|
|
679
|
+
this.mediaDevices.push(mediaDevice);
|
|
680
|
+
}
|
|
625
681
|
}
|
|
626
682
|
|
|
627
683
|
for (const mediaSource of sample.mediaSources ?? []) {
|
|
@@ -849,6 +905,48 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
849
905
|
}
|
|
850
906
|
}
|
|
851
907
|
|
|
908
|
+
// try to set the timestamps of the peer connections
|
|
909
|
+
if (0 < this.ωpendingPeerConnectionTimestamps.length) {
|
|
910
|
+
const newPendingTimestamps: PendingPeerConnectionTimestamp[] = [];
|
|
911
|
+
|
|
912
|
+
for (const pendingTimestamp of this.ωpendingPeerConnectionTimestamps) {
|
|
913
|
+
const peerConnection = this._peerConnections.get(pendingTimestamp.peerConnectionId);
|
|
914
|
+
|
|
915
|
+
if (!peerConnection) {
|
|
916
|
+
newPendingTimestamps.push(pendingTimestamp);
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
919
|
+
if (pendingTimestamp.type === 'opened') peerConnection.opened = pendingTimestamp.timestamp;
|
|
920
|
+
else if (pendingTimestamp.type === 'closed') peerConnection.closedTimestamp = pendingTimestamp.timestamp;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
this.ωpendingPeerConnectionTimestamps = newPendingTimestamps;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// try to set the timestamps of the media tracks
|
|
927
|
+
if (0 < this.ωpendingMediaTrackTimestamps.length) {
|
|
928
|
+
const newPendingTimestamps: PendingMediaTrackTimestamp[] = [];
|
|
929
|
+
|
|
930
|
+
for (const pendingTimestamp of this.ωpendingMediaTrackTimestamps) {
|
|
931
|
+
const peerConnection = this._peerConnections.get(pendingTimestamp.peerConnectionId);
|
|
932
|
+
const mediaTrack = peerConnection?.inboundAudioTracks.get(pendingTimestamp.mediaTrackId) ??
|
|
933
|
+
peerConnection?.inboundVideoTracks.get(pendingTimestamp.mediaTrackId) ??
|
|
934
|
+
peerConnection?.outboundAudioTracks.get(pendingTimestamp.mediaTrackId) ??
|
|
935
|
+
peerConnection?.outboundVideoTracks.get(pendingTimestamp.mediaTrackId);
|
|
936
|
+
|
|
937
|
+
if (!mediaTrack) {
|
|
938
|
+
newPendingTimestamps.push(pendingTimestamp);
|
|
939
|
+
continue;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
if (pendingTimestamp.type === 'added') mediaTrack.added = pendingTimestamp.timestamp;
|
|
943
|
+
else if (pendingTimestamp.type === 'removed') mediaTrack.removed = pendingTimestamp.timestamp;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
this.ωpendingMediaTrackTimestamps = newPendingTimestamps;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// close resources that are not visited
|
|
852
950
|
for (const peerConnection of this._peerConnections.values()) {
|
|
853
951
|
if (!peerConnection.visited) {
|
|
854
952
|
peerConnection.close();
|
|
@@ -1007,7 +1105,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
1007
1105
|
}
|
|
1008
1106
|
}
|
|
1009
1107
|
}
|
|
1010
|
-
|
|
1108
|
+
|
|
1011
1109
|
this.emit('issue', issue);
|
|
1012
1110
|
}
|
|
1013
1111
|
|
|
@@ -1036,20 +1134,4 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
1036
1134
|
|
|
1037
1135
|
return result;
|
|
1038
1136
|
}
|
|
1039
|
-
|
|
1040
|
-
private _addClientLeftReport() {
|
|
1041
|
-
if (this._left) return;
|
|
1042
|
-
this._left = Date.now();
|
|
1043
|
-
|
|
1044
|
-
this.reports.addCallEventReport(createClientLeftEventReport(
|
|
1045
|
-
this.serviceId,
|
|
1046
|
-
this.mediaUnitId,
|
|
1047
|
-
this.roomId,
|
|
1048
|
-
this.callId,
|
|
1049
|
-
this.clientId,
|
|
1050
|
-
this._left,
|
|
1051
|
-
this.userId,
|
|
1052
|
-
this.marker,
|
|
1053
|
-
));
|
|
1054
|
-
}
|
|
1055
1137
|
}
|
|
@@ -54,6 +54,11 @@ export class ObservedInboundAudioTrack extends EventEmitter {
|
|
|
54
54
|
public readonly created = Date.now();
|
|
55
55
|
public visited = false;
|
|
56
56
|
|
|
57
|
+
// timestamp of the MEDIA_TRACK_ADDED event
|
|
58
|
+
public added?: number;
|
|
59
|
+
// timestamp of the MEDIA_TRACK_REMOVED event
|
|
60
|
+
public removed?: number;
|
|
61
|
+
|
|
57
62
|
private readonly _stats = new Map<number, ObservedInboundAudioTrackStats>();
|
|
58
63
|
|
|
59
64
|
private _closed = false;
|
|
@@ -257,6 +262,9 @@ export class ObservedInboundAudioTrack extends EventEmitter {
|
|
|
257
262
|
this._stats.set(sample.ssrc, stats);
|
|
258
263
|
|
|
259
264
|
this.visited = true;
|
|
265
|
+
// a peer connection is active if it has at least one active track
|
|
266
|
+
this.peerConnection.visited = true;
|
|
267
|
+
|
|
260
268
|
this._updated = now;
|
|
261
269
|
|
|
262
270
|
this.emit('update', {
|
|
@@ -5,6 +5,7 @@ import { InboundAudioTrackReport, InboundVideoTrackReport } from '@observertc/re
|
|
|
5
5
|
import { CalculatedScore, calculateBaseVideoScore } from './common/CalculatedScore';
|
|
6
6
|
import { ClientIssue } from './monitors/CallSummary';
|
|
7
7
|
import { ObservedOutboundVideoTrack } from './ObservedOutboundVideoTrack';
|
|
8
|
+
import { SupportedVideoCodecType } from './common/types';
|
|
8
9
|
|
|
9
10
|
export type ObservedInboundVideoTrackModel = {
|
|
10
11
|
trackId: string;
|
|
@@ -54,8 +55,13 @@ export class ObservedInboundVideoTrack extends EventEmitter {
|
|
|
54
55
|
public readonly created = Date.now();
|
|
55
56
|
public visited = false;
|
|
56
57
|
|
|
58
|
+
// timestamp of the MEDIA_TRACK_ADDED event
|
|
59
|
+
public added?: number;
|
|
60
|
+
// timestamp of the MEDIA_TRACK_REMOVED event
|
|
61
|
+
public removed?: number;
|
|
62
|
+
|
|
57
63
|
public contentType: 'lowmotion' | 'standard' | 'highmotion' = 'standard';
|
|
58
|
-
public codec
|
|
64
|
+
public codec?: SupportedVideoCodecType;
|
|
59
65
|
|
|
60
66
|
private readonly _stats = new Map<number, ObservedInboundVideoTrackStats>();
|
|
61
67
|
|
|
@@ -267,6 +273,9 @@ export class ObservedInboundVideoTrack extends EventEmitter {
|
|
|
267
273
|
this._stats.set(sample.ssrc, stats);
|
|
268
274
|
|
|
269
275
|
this.visited = true;
|
|
276
|
+
// a peer connection is active if it has at least one active track
|
|
277
|
+
this.peerConnection.visited = true;
|
|
278
|
+
|
|
270
279
|
this._updated = now;
|
|
271
280
|
this.emit('update', {
|
|
272
281
|
elapsedTimeInMs,
|
|
@@ -50,6 +50,11 @@ export class ObservedOutboundAudioTrack extends EventEmitter {
|
|
|
50
50
|
public readonly created = Date.now();
|
|
51
51
|
public visited = false;
|
|
52
52
|
|
|
53
|
+
// timestamp of the MEDIA_TRACK_ADDED event
|
|
54
|
+
public added?: number;
|
|
55
|
+
// timestamp of the MEDIA_TRACK_REMOVED event
|
|
56
|
+
public removed?: number;
|
|
57
|
+
|
|
53
58
|
public bitrate = 0;
|
|
54
59
|
public rttInMs?: number;
|
|
55
60
|
public jitter?: number;
|
|
@@ -222,23 +227,10 @@ export class ObservedOutboundAudioTrack extends EventEmitter {
|
|
|
222
227
|
|
|
223
228
|
this._stats.set(sample.ssrc, stats);
|
|
224
229
|
|
|
225
|
-
// this.bitrate = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.bitrate, 0);
|
|
226
|
-
// this.rttInMs = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.rttInMs ?? 0), 0) / (this._stats.size || 1);
|
|
227
|
-
|
|
228
|
-
// this.totalLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.packetsLost ?? 0), 0);
|
|
229
|
-
// this.totalSentPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.packetsSent ?? 0), 0);
|
|
230
|
-
// this.totalSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.bytesSent ?? 0), 0);
|
|
231
|
-
// this.totalSentFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaSentPackets ?? 0), 0);
|
|
232
|
-
|
|
233
|
-
// this.deltaEncodedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaEncodedFrames ?? 0), 0);
|
|
234
|
-
// this.deltaSentFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaSentFrames ?? 0), 0);
|
|
235
|
-
// this.deltaLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaLostPackets, 0);
|
|
236
|
-
// this.deltaSentPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentPackets, 0);
|
|
237
|
-
// this.deltaSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentBytes, 0);
|
|
238
|
-
|
|
239
|
-
// setting up sfu connection as it is not always available at the first sample
|
|
240
|
-
|
|
241
230
|
this.visited = true;
|
|
231
|
+
// a peer connection is active if it has at least one active track
|
|
232
|
+
this.peerConnection.visited = true;
|
|
233
|
+
|
|
242
234
|
this._updated = now;
|
|
243
235
|
this.emit('update', {
|
|
244
236
|
elapsedTimeInMs,
|