@observertc/observer-js 0.42.1 → 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 +19 -8
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +94 -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 -2
- 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 +114 -34
- 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 -5
- 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
|
@@ -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,10 +51,8 @@ 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
|
-
ended?: number;
|
|
58
56
|
}): ObservedCall<T>;
|
|
59
57
|
createObservedSfu<AppData extends Record<string, unknown> = Record<string, unknown>>(model: ObservedSfuModel, appData: AppData): ObservedSfu<AppData>;
|
|
60
58
|
createCallSummaryMonitor(options?: CallSummaryMonitorConfig & {
|
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, ended !== null &&
|
|
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;
|
|
@@ -119,13 +133,13 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
119
133
|
public inboundVideoBitrate?: number;
|
|
120
134
|
public mediaConstraints: string[] = [];
|
|
121
135
|
|
|
122
|
-
public readonly mediaDevices:
|
|
123
|
-
public readonly
|
|
136
|
+
public readonly mediaDevices: MediaDevice[] = [];
|
|
137
|
+
public readonly mediaCodecs: MediaCodecStats[] = [];
|
|
124
138
|
public readonly userMediaErrors: string[] = [];
|
|
125
139
|
public readonly issues: ClientIssue[] = [];
|
|
126
140
|
|
|
127
|
-
public
|
|
128
|
-
public
|
|
141
|
+
public ωpendingPeerConnectionTimestamps: PendingPeerConnectionTimestamp[] = [];
|
|
142
|
+
public ωpendingMediaTrackTimestamps: PendingMediaTrackTimestamp[] = [];
|
|
129
143
|
|
|
130
144
|
public constructor(
|
|
131
145
|
private readonly _model: ObservedClientModel,
|
|
@@ -239,9 +253,6 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
239
253
|
if (this._closed) return;
|
|
240
254
|
this._closed = true;
|
|
241
255
|
|
|
242
|
-
if (!this._left) {
|
|
243
|
-
this._addClientLeftReport();
|
|
244
|
-
}
|
|
245
256
|
Array.from(this._peerConnections.values()).forEach((peerConnection) => peerConnection.close());
|
|
246
257
|
|
|
247
258
|
this.emit('close');
|
|
@@ -493,17 +504,56 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
493
504
|
for (const { timestamp, ...callEvent } of sample.customCallEvents ?? []) {
|
|
494
505
|
switch (callEvent.name) {
|
|
495
506
|
case CallEventType.CLIENT_JOINED: {
|
|
496
|
-
const lastJoined = this.
|
|
507
|
+
const lastJoined = this.joined;
|
|
497
508
|
|
|
498
|
-
this.
|
|
509
|
+
this.joined = timestamp;
|
|
499
510
|
|
|
500
|
-
if
|
|
511
|
+
// if it is joined before and it is joined again
|
|
512
|
+
if (lastJoined && this.joined && lastJoined !== this.joined) {
|
|
501
513
|
this.emit('rejoined', { lastJoined });
|
|
502
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
|
+
}
|
|
503
519
|
break;
|
|
504
520
|
}
|
|
505
521
|
case CallEventType.CLIENT_LEFT: {
|
|
506
|
-
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
|
+
});
|
|
507
557
|
break;
|
|
508
558
|
}
|
|
509
559
|
case CallEventType.CLIENT_ISSUE: {
|
|
@@ -594,7 +644,9 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
594
644
|
}, this.userId);
|
|
595
645
|
|
|
596
646
|
this.reports.addCallMetaReport(callMetaReport);
|
|
597
|
-
codec.mimeType && this.
|
|
647
|
+
if (codec.mimeType && !this.mediaCodecs.find((c) => c.mimeType === codec.mimeType)) {
|
|
648
|
+
this.mediaCodecs.push(codec);
|
|
649
|
+
}
|
|
598
650
|
}
|
|
599
651
|
|
|
600
652
|
for (const iceServer of sample.iceServers ?? []) {
|
|
@@ -621,9 +673,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
621
673
|
type: CallMetaType.MEDIA_DEVICE,
|
|
622
674
|
payload: mediaDevice,
|
|
623
675
|
}, this.userId);
|
|
624
|
-
|
|
676
|
+
|
|
625
677
|
this.reports.addCallMetaReport(callMetaReport);
|
|
626
|
-
mediaDevice.
|
|
678
|
+
if (mediaDevice.id && !this.mediaDevices.find((d) => d.id === mediaDevice.id)) {
|
|
679
|
+
this.mediaDevices.push(mediaDevice);
|
|
680
|
+
}
|
|
627
681
|
}
|
|
628
682
|
|
|
629
683
|
for (const mediaSource of sample.mediaSources ?? []) {
|
|
@@ -851,6 +905,48 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
851
905
|
}
|
|
852
906
|
}
|
|
853
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
|
|
854
950
|
for (const peerConnection of this._peerConnections.values()) {
|
|
855
951
|
if (!peerConnection.visited) {
|
|
856
952
|
peerConnection.close();
|
|
@@ -1038,20 +1134,4 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
1038
1134
|
|
|
1039
1135
|
return result;
|
|
1040
1136
|
}
|
|
1041
|
-
|
|
1042
|
-
private _addClientLeftReport() {
|
|
1043
|
-
if (this._left) return;
|
|
1044
|
-
this._left = Date.now();
|
|
1045
|
-
|
|
1046
|
-
this.reports.addCallEventReport(createClientLeftEventReport(
|
|
1047
|
-
this.serviceId,
|
|
1048
|
-
this.mediaUnitId,
|
|
1049
|
-
this.roomId,
|
|
1050
|
-
this.callId,
|
|
1051
|
-
this.clientId,
|
|
1052
|
-
this._left,
|
|
1053
|
-
this.userId,
|
|
1054
|
-
this.marker,
|
|
1055
|
-
));
|
|
1056
|
-
}
|
|
1057
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,
|
|
@@ -5,6 +5,7 @@ import { OutboundAudioTrackReport, OutboundVideoTrackReport } from '@observertc/
|
|
|
5
5
|
import { ObservedInboundVideoTrack } from './ObservedInboundVideoTrack';
|
|
6
6
|
import { calculateBaseVideoScore, CalculatedScore } from './common/CalculatedScore';
|
|
7
7
|
import { ClientIssue } from './monitors/CallSummary';
|
|
8
|
+
import { SupportedVideoCodecType } from './common/types';
|
|
8
9
|
|
|
9
10
|
export type ObservedOutboundVideoTrackModel = {
|
|
10
11
|
trackId: string;
|
|
@@ -50,8 +51,13 @@ export class ObservedOutboundVideoTrack extends EventEmitter {
|
|
|
50
51
|
public readonly created = Date.now();
|
|
51
52
|
public visited = false;
|
|
52
53
|
|
|
54
|
+
// timestamp of the MEDIA_TRACK_ADDED event
|
|
55
|
+
public added?: number;
|
|
56
|
+
// timestamp of the MEDIA_TRACK_REMOVED event
|
|
57
|
+
public removed?: number;
|
|
58
|
+
|
|
53
59
|
public contentType: 'lowmotion' | 'standard' | 'highmotion' = 'standard';
|
|
54
|
-
public codec
|
|
60
|
+
public codec?: SupportedVideoCodecType;
|
|
55
61
|
public highestLayer?: ObservedOutboundVideoTrackStats;
|
|
56
62
|
|
|
57
63
|
public bitrate = 0;
|
|
@@ -241,6 +247,9 @@ export class ObservedOutboundVideoTrack extends EventEmitter {
|
|
|
241
247
|
// setting up sfu connection as it is not always available at the first sample
|
|
242
248
|
|
|
243
249
|
this.visited = true;
|
|
250
|
+
// a peer connection is active if it has at least one active track
|
|
251
|
+
this.peerConnection.visited = true;
|
|
252
|
+
|
|
244
253
|
this._updated = now;
|
|
245
254
|
this.emit('update', {
|
|
246
255
|
elapsedTimeInMs,
|
|
@@ -42,7 +42,12 @@ export declare interface ObservedPeerConnection {
|
|
|
42
42
|
export class ObservedPeerConnection extends EventEmitter {
|
|
43
43
|
public readonly created = Date.now();
|
|
44
44
|
public visited = true;
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
// timestamp of the PEER_CONNECTION_OPENED event
|
|
47
|
+
public opened?: number;
|
|
48
|
+
// timestamp of the PEER_CONNECTION_CLOSED event
|
|
49
|
+
public closedTimestamp?: number;
|
|
50
|
+
|
|
46
51
|
private _elapsedTimeSinceLastUpdate?: number;
|
|
47
52
|
private _statsTimestamp?: number;
|
|
48
53
|
|