@observertc/observer-js 0.40.5-beta → 0.40.7-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ObservedCall.d.ts +1 -2
- package/lib/ObservedCall.d.ts.map +1 -1
- package/lib/ObservedCall.js +2 -2
- package/lib/ObservedInboundTrack.d.ts +11 -8
- package/lib/ObservedInboundTrack.d.ts.map +1 -1
- package/lib/ObservedInboundTrack.js +89 -52
- package/lib/ObservedOutboundTrack.d.ts +3 -1
- package/lib/ObservedOutboundTrack.d.ts.map +1 -1
- package/lib/ObservedOutboundTrack.js +70 -30
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/ObservedPeerConnection.js +12 -17
- package/lib/Observer.d.ts +2 -1
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +3 -3
- package/package.json +1 -1
- package/src/ObservedCall.ts +2 -3
- package/src/ObservedInboundTrack.ts +108 -62
- package/src/ObservedOutboundTrack.ts +82 -30
- package/src/ObservedPeerConnection.ts +17 -21
- package/src/Observer.ts +3 -4
package/lib/ObservedCall.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ export type ObservedCallModel = {
|
|
|
7
7
|
serviceId: string;
|
|
8
8
|
roomId: string;
|
|
9
9
|
callId: string;
|
|
10
|
-
started: number;
|
|
11
10
|
};
|
|
12
11
|
export type ObservedCallEvents = {
|
|
13
12
|
update: [];
|
|
@@ -36,7 +35,7 @@ export declare class ObservedCall<AppData extends Record<string, unknown> = Reco
|
|
|
36
35
|
get reports(): import("./ReportsCollector").ReportsCollector;
|
|
37
36
|
get roomId(): string;
|
|
38
37
|
get callId(): string;
|
|
39
|
-
get
|
|
38
|
+
get updated(): number;
|
|
40
39
|
get ended(): number | undefined;
|
|
41
40
|
get clients(): ReadonlyMap<string, ObservedClient>;
|
|
42
41
|
get closed(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedCall.d.ts","sourceRoot":"","sources":["../src/ObservedCall.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,MAAM,MAAM,iBAAiB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ObservedCall.d.ts","sourceRoot":"","sources":["../src/ObservedCall.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,MAAM,MAAM,iBAAiB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE,EAAE,CAAC;IACX,SAAS,EAAE,CAAC,cAAc,CAAC,CAAC;IAC5B,KAAK,EAAE,EAAE,CAAC;CACV,CAAA;AAED,MAAM,CAAC,OAAO,WAAW,YAAY;IACpC,EAAE,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3G,GAAG,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5G,IAAI,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7G,IAAI,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CAC5F;AAED,qBAAa,YAAY,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,YAAY;IAY/G,OAAO,CAAC,QAAQ,CAAC,MAAM;aACP,QAAQ,EAAE,QAAQ;aAClB,OAAO,EAAE,OAAO;IAbjC,SAAgB,OAAO,SAAc;IAErC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAE9D,SAAgB,+BAA+B,uDAA8D;IAC7G,SAAgB,+BAA+B,uDAA8D;IAC7G,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,MAAM,CAAC,CAAS;gBAGN,MAAM,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO;IAMjC,IAAW,SAAS,IAAI,MAAM,CAG7B;IAED,IAAW,OAAO,kDAEjB;IAED,IAAW,MAAM,WAGhB;IAED,IAAW,MAAM,WAGhB;IAED,IAAW,OAAO,WAEjB;IAED,IAAW,KAAK,uBAEf;IAED,IAAW,OAAO,IAAI,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAExD;IAED,IAAW,MAAM,YAEhB;IAEM,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM;IAUxB,YAAY,CAAC,aAAa,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,mBAAmB,GAAG;QAAE,OAAO,EAAE,aAAa,CAAC;QAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;CAmC5M"}
|
package/lib/ObservedCall.js
CHANGED
|
@@ -44,8 +44,8 @@ class ObservedCall extends events_1.EventEmitter {
|
|
|
44
44
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
45
45
|
return this._model.callId;
|
|
46
46
|
}
|
|
47
|
-
get
|
|
48
|
-
return
|
|
47
|
+
get updated() {
|
|
48
|
+
return this._updated;
|
|
49
49
|
}
|
|
50
50
|
get ended() {
|
|
51
51
|
return this._ended;
|
|
@@ -21,14 +21,16 @@ export type ObservedInboundTrackStats<K extends MediaKind> = ObservedInboundTrac
|
|
|
21
21
|
bitrate: number;
|
|
22
22
|
fractionLost: number;
|
|
23
23
|
rttInMs?: number;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
deltaReceivedBytes?: number;
|
|
25
|
+
deltaLostPackets?: number;
|
|
26
|
+
deltaReceivedPackets?: number;
|
|
27
|
+
deltaReceivedFrames?: number;
|
|
28
|
+
deltaDecodedFrames?: number;
|
|
29
|
+
deltaDroppedFrames?: number;
|
|
30
|
+
deltaReceivedSamples?: number;
|
|
31
|
+
deltaSilentConcealedSamples?: number;
|
|
31
32
|
fractionLoss?: number;
|
|
33
|
+
statsTimestamp: number;
|
|
32
34
|
};
|
|
33
35
|
export declare interface ObservedInboundTrack<Kind extends MediaKind> {
|
|
34
36
|
on<U extends keyof ObservedInboundTrackEvents<Kind>>(event: U, listener: (...args: ObservedInboundTrackEvents<Kind>[U]) => void): this;
|
|
@@ -45,6 +47,7 @@ export declare class ObservedInboundTrack<Kind extends MediaKind> extends EventE
|
|
|
45
47
|
private _closed;
|
|
46
48
|
private _updated;
|
|
47
49
|
private _remoteOutboundTrack?;
|
|
50
|
+
private _lastMaxStatsTimestamp;
|
|
48
51
|
bitrate: number;
|
|
49
52
|
rttInMs?: number;
|
|
50
53
|
fractionLoss: number;
|
|
@@ -83,6 +86,6 @@ export declare class ObservedInboundTrack<Kind extends MediaKind> extends EventE
|
|
|
83
86
|
get remoteOutboundTrack(): ObservedOutboundTrack<Kind> | undefined;
|
|
84
87
|
get closed(): boolean;
|
|
85
88
|
close(): void;
|
|
86
|
-
|
|
89
|
+
updateMetrics(): void;
|
|
87
90
|
}
|
|
88
91
|
//# sourceMappingURL=ObservedInboundTrack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedInboundTrack.d.ts","sourceRoot":"","sources":["../src/ObservedInboundTrack.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,MAAM,yBAAyB,CAAC,CAAC,SAAS,SAAS,IAAI;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,CAAC,CAAC;IACR,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,SAAS,IAAI;IAC7D,MAAM,EAAE,EAAE,CAAC;IACX,KAAK,EAAE,EAAE,CAAC;IACV,mBAAmB,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,+BAA+B,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,SAAS,OAAO,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAE7H,MAAM,MAAM,yBAAyB,CAAC,CAAC,SAAS,SAAS,IAAI,+BAA+B,CAAC,CAAC,CAAC,GAAG;IACjG,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,
|
|
1
|
+
{"version":3,"file":"ObservedInboundTrack.d.ts","sourceRoot":"","sources":["../src/ObservedInboundTrack.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ class ObservedInboundTrack extends events_1.EventEmitter {
|
|
|
11
11
|
this._stats = new Map();
|
|
12
12
|
this._closed = false;
|
|
13
13
|
this._updated = Date.now();
|
|
14
|
+
this._lastMaxStatsTimestamp = 0;
|
|
14
15
|
this.bitrate = 0;
|
|
15
16
|
this.fractionLoss = 0;
|
|
16
17
|
this.totalLostPackets = 0;
|
|
@@ -95,24 +96,12 @@ class ObservedInboundTrack extends events_1.EventEmitter {
|
|
|
95
96
|
this._closed = true;
|
|
96
97
|
this.emit('close');
|
|
97
98
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.rttInMs = undefined;
|
|
101
|
-
this.deltaBytesReceived = 0;
|
|
102
|
-
this.deltaLostPackets = 0;
|
|
103
|
-
this.deltaReceivedFrames = 0;
|
|
104
|
-
this.deltaDecodedFrames = 0;
|
|
105
|
-
this.deltaDroppedFrames = 0;
|
|
106
|
-
this.deltaReceivedSamples = 0;
|
|
107
|
-
this.deltaSilentConcealedSamples = 0;
|
|
108
|
-
this.fractionLoss = 0;
|
|
109
|
-
}
|
|
110
|
-
update(sample, timestamp) {
|
|
111
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
99
|
+
update(sample, statsTimestamp) {
|
|
100
|
+
var _a, _b, _c, _d, _e;
|
|
112
101
|
if (this._closed)
|
|
113
102
|
return;
|
|
114
103
|
const now = Date.now();
|
|
115
|
-
const report = Object.assign(Object.assign({ serviceId: this.peerConnection.client.call.serviceId, roomId: this.peerConnection.client.call.roomId, callId: this.peerConnection.client.call.callId, clientId: this.peerConnection.client.clientId, userId: this.peerConnection.client.userId, mediaUnitId: this.peerConnection.client.mediaUnitId, peerConnectionId: this.peerConnection.peerConnectionId }, sample), { timestamp, sampleSeq: -1, remoteClientId: (_a = sample.remoteClientId) !== null && _a !== void 0 ? _a : (_b = this.remoteOutboundTrack) === null || _b === void 0 ? void 0 : _b.peerConnection.client.clientId, remoteUserId: (_c = this.remoteOutboundTrack) === null || _c === void 0 ? void 0 : _c.peerConnection.client.userId, remoteTrackId: (_d = this.remoteOutboundTrack) === null || _d === void 0 ? void 0 : _d.trackId, remotePeerConnectionId: (_e = this.remoteOutboundTrack) === null || _e === void 0 ? void 0 : _e.peerConnection.peerConnectionId, marker: this.marker });
|
|
104
|
+
const report = Object.assign(Object.assign({ serviceId: this.peerConnection.client.call.serviceId, roomId: this.peerConnection.client.call.roomId, callId: this.peerConnection.client.call.callId, clientId: this.peerConnection.client.clientId, userId: this.peerConnection.client.userId, mediaUnitId: this.peerConnection.client.mediaUnitId, peerConnectionId: this.peerConnection.peerConnectionId }, sample), { timestamp: statsTimestamp, sampleSeq: -1, remoteClientId: (_a = sample.remoteClientId) !== null && _a !== void 0 ? _a : (_b = this.remoteOutboundTrack) === null || _b === void 0 ? void 0 : _b.peerConnection.client.clientId, remoteUserId: (_c = this.remoteOutboundTrack) === null || _c === void 0 ? void 0 : _c.peerConnection.client.userId, remoteTrackId: (_d = this.remoteOutboundTrack) === null || _d === void 0 ? void 0 : _d.trackId, remotePeerConnectionId: (_e = this.remoteOutboundTrack) === null || _e === void 0 ? void 0 : _e.peerConnection.peerConnectionId, marker: this.marker });
|
|
116
105
|
if (this.kind === 'audio')
|
|
117
106
|
this.reports.addInboundAudioTrackReport(report);
|
|
118
107
|
else if (this.kind === 'video')
|
|
@@ -126,56 +115,104 @@ class ObservedInboundTrack extends events_1.EventEmitter {
|
|
|
126
115
|
const elapsedTimeInMs = Math.max(1, now - this._updated);
|
|
127
116
|
const lastStat = this._stats.get(sample.ssrc);
|
|
128
117
|
const rttInMs = sample.roundTripTime ? sample.roundTripTime * 1000 : undefined;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
let
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
118
|
+
let bitrate = 0;
|
|
119
|
+
let deltaReceivedBytes = 0;
|
|
120
|
+
let fractionLost = 0;
|
|
121
|
+
let deltaLostPackets = 0;
|
|
122
|
+
let deltaReceivedPackets = 0;
|
|
123
|
+
if ((lastStat === null || lastStat === void 0 ? void 0 : lastStat.bytesReceived) && sample.bytesReceived && lastStat.bytesReceived < sample.bytesReceived) {
|
|
124
|
+
deltaReceivedBytes = sample.bytesReceived - lastStat.bytesReceived;
|
|
125
|
+
bitrate = deltaReceivedBytes / (elapsedTimeInMs / 1000);
|
|
126
|
+
}
|
|
127
|
+
if ((lastStat === null || lastStat === void 0 ? void 0 : lastStat.packetsReceived) && (sample === null || sample === void 0 ? void 0 : sample.packetsReceived) && lastStat.packetsReceived < sample.packetsReceived) {
|
|
128
|
+
deltaReceivedPackets = sample.packetsReceived - lastStat.packetsReceived;
|
|
129
|
+
}
|
|
130
|
+
if ((lastStat === null || lastStat === void 0 ? void 0 : lastStat.packetsLost) && sample.packetsLost && lastStat.packetsLost < sample.packetsLost) {
|
|
131
|
+
deltaLostPackets = sample.packetsLost - lastStat.packetsLost;
|
|
132
|
+
if (0 < deltaReceivedPackets) {
|
|
133
|
+
fractionLost = deltaLostPackets / (deltaReceivedPackets + deltaLostPackets);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
let deltaDecodedFrames;
|
|
137
|
+
let deltaDroppedFrames;
|
|
138
|
+
let deltaReceivedFrames;
|
|
139
|
+
let deltaSilentConcealedSamples;
|
|
137
140
|
if (this.kind === 'video') {
|
|
138
141
|
const videoSample = sample;
|
|
139
142
|
const lastVideoStat = lastStat;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
if (videoSample.framesDecoded && (lastVideoStat === null || lastVideoStat === void 0 ? void 0 : lastVideoStat.framesDecoded) && lastVideoStat.framesDecoded < videoSample.framesDecoded) {
|
|
144
|
+
deltaDecodedFrames = videoSample.framesDecoded - lastVideoStat.framesDecoded;
|
|
145
|
+
}
|
|
146
|
+
if (videoSample.framesDropped && (lastVideoStat === null || lastVideoStat === void 0 ? void 0 : lastVideoStat.framesDropped) && lastVideoStat.framesDropped < videoSample.framesDropped) {
|
|
147
|
+
deltaDroppedFrames = videoSample.framesDropped - lastVideoStat.framesDropped;
|
|
148
|
+
}
|
|
149
|
+
if (videoSample.framesReceived && (lastVideoStat === null || lastVideoStat === void 0 ? void 0 : lastVideoStat.framesReceived) && lastVideoStat.framesReceived < videoSample.framesReceived) {
|
|
150
|
+
deltaReceivedFrames = videoSample.framesReceived - lastVideoStat.framesReceived;
|
|
151
|
+
}
|
|
143
152
|
}
|
|
144
153
|
else if (this.kind === 'audio') {
|
|
145
154
|
const audioSample = sample;
|
|
146
155
|
const lastAudioStat = lastStat;
|
|
147
|
-
|
|
156
|
+
if (audioSample.silentConcealedSamples && (lastAudioStat === null || lastAudioStat === void 0 ? void 0 : lastAudioStat.silentConcealedSamples) && lastAudioStat.silentConcealedSamples < audioSample.silentConcealedSamples) {
|
|
157
|
+
deltaSilentConcealedSamples = audioSample.silentConcealedSamples - lastAudioStat.silentConcealedSamples;
|
|
158
|
+
}
|
|
148
159
|
}
|
|
149
160
|
const stats = Object.assign(Object.assign({}, sample), { fractionLost,
|
|
150
161
|
rttInMs,
|
|
151
|
-
bitrate, ssrc: sample.ssrc,
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
162
|
+
bitrate, ssrc: sample.ssrc, deltaReceivedBytes,
|
|
163
|
+
deltaLostPackets,
|
|
164
|
+
deltaReceivedPackets,
|
|
165
|
+
deltaReceivedFrames,
|
|
166
|
+
deltaDecodedFrames,
|
|
167
|
+
deltaDroppedFrames,
|
|
168
|
+
deltaSilentConcealedSamples,
|
|
169
|
+
statsTimestamp });
|
|
157
170
|
this._stats.set(sample.ssrc, stats);
|
|
158
|
-
this.bitrate = [...this._stats.values()].reduce((acc, stat) => acc + stat.bitrate, 0);
|
|
159
|
-
this.rttInMs = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.rttInMs) !== null && _a !== void 0 ? _a : 0); }, 0) / (this._stats.size || 1);
|
|
160
|
-
this.totalLostPackets = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.lostPackets) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
161
|
-
this.totalReceivedPackets = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.receivedPackets) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
162
|
-
this.totalBytesReceived = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.bytesReceived) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
163
|
-
this.totalReceivedFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.receivedFrames) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
164
|
-
this.totalDecodedFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.decodedFrames) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
165
|
-
this.totalDroppedFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.droppedFrames) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
166
|
-
this.totalReceivedSamples = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.receivedSamples) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
167
|
-
this.totalSilentConcealedSamples = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.silentConcealedSamples) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
168
|
-
this.deltaLostPackets = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.lostPackets) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
169
|
-
this.deltaReceivedPackets = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.receivedPackets) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
170
|
-
this.deltaBytesReceived = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.bytesReceived) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
171
|
-
this.deltaReceivedFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.receivedFrames) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
172
|
-
this.deltaDecodedFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.decodedFrames) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
173
|
-
this.deltaDroppedFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.droppedFrames) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
174
|
-
this.deltaReceivedSamples = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.receivedSamples) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
175
|
-
this.deltaSilentConcealedSamples = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.silentConcealedSamples) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
176
|
-
this.fractionLoss = 0 < this.deltaReceivedPackets && 0 < this.deltaLostPackets ? (this.deltaLostPackets / (this.deltaReceivedPackets + this.deltaLostPackets)) : 0;
|
|
177
171
|
this._updated = now;
|
|
178
172
|
this.emit('update');
|
|
179
173
|
}
|
|
174
|
+
updateMetrics() {
|
|
175
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
176
|
+
let maxStatsTimestamp = 0;
|
|
177
|
+
let rttInMsSum = 0;
|
|
178
|
+
let size = 0;
|
|
179
|
+
this.bitrate = 0;
|
|
180
|
+
this.rttInMs = undefined;
|
|
181
|
+
this.deltaBytesReceived = 0;
|
|
182
|
+
this.deltaLostPackets = 0;
|
|
183
|
+
this.deltaReceivedFrames = 0;
|
|
184
|
+
this.deltaDecodedFrames = 0;
|
|
185
|
+
this.deltaDroppedFrames = 0;
|
|
186
|
+
this.deltaReceivedSamples = 0;
|
|
187
|
+
this.deltaSilentConcealedSamples = 0;
|
|
188
|
+
this.fractionLoss = 0;
|
|
189
|
+
for (const [, stats] of this._stats) {
|
|
190
|
+
if (stats.statsTimestamp <= this._lastMaxStatsTimestamp)
|
|
191
|
+
continue;
|
|
192
|
+
this.deltaBytesReceived += (_a = stats.deltaReceivedBytes) !== null && _a !== void 0 ? _a : 0;
|
|
193
|
+
this.deltaLostPackets += (_b = stats.deltaLostPackets) !== null && _b !== void 0 ? _b : 0;
|
|
194
|
+
this.deltaReceivedPackets += (_c = stats.deltaReceivedFrames) !== null && _c !== void 0 ? _c : 0;
|
|
195
|
+
this.deltaReceivedFrames += (_d = stats.deltaReceivedFrames) !== null && _d !== void 0 ? _d : 0;
|
|
196
|
+
this.deltaDecodedFrames += (_e = stats.deltaDecodedFrames) !== null && _e !== void 0 ? _e : 0;
|
|
197
|
+
this.deltaDroppedFrames += (_f = stats.deltaDroppedFrames) !== null && _f !== void 0 ? _f : 0;
|
|
198
|
+
this.deltaReceivedSamples += (_g = stats.deltaReceivedSamples) !== null && _g !== void 0 ? _g : 0;
|
|
199
|
+
this.deltaSilentConcealedSamples += (_h = stats.deltaSilentConcealedSamples) !== null && _h !== void 0 ? _h : 0;
|
|
200
|
+
this.bitrate += stats.bitrate;
|
|
201
|
+
maxStatsTimestamp = Math.max(maxStatsTimestamp, stats.statsTimestamp);
|
|
202
|
+
rttInMsSum += (_j = stats.rttInMs) !== null && _j !== void 0 ? _j : 0;
|
|
203
|
+
++size;
|
|
204
|
+
}
|
|
205
|
+
this.totalBytesReceived += this.deltaBytesReceived;
|
|
206
|
+
this.totalLostPackets += this.deltaLostPackets;
|
|
207
|
+
this.totalReceivedPackets += this.deltaReceivedPackets;
|
|
208
|
+
this.totalReceivedFrames += this.deltaReceivedFrames;
|
|
209
|
+
this.totalDecodedFrames += this.deltaDecodedFrames;
|
|
210
|
+
this.totalDroppedFrames += this.deltaDroppedFrames;
|
|
211
|
+
this.totalReceivedSamples += this.deltaReceivedSamples;
|
|
212
|
+
this.totalSilentConcealedSamples += this.deltaSilentConcealedSamples;
|
|
213
|
+
this.rttInMs = rttInMsSum / Math.max(size, 1);
|
|
214
|
+
this.fractionLoss = 0 < this.deltaReceivedPackets && 0 < this.deltaLostPackets ? (this.deltaLostPackets / (this.deltaReceivedPackets + this.deltaLostPackets)) : 0;
|
|
215
|
+
this._lastMaxStatsTimestamp = maxStatsTimestamp;
|
|
216
|
+
}
|
|
180
217
|
}
|
|
181
218
|
exports.ObservedInboundTrack = ObservedInboundTrack;
|
|
@@ -23,6 +23,7 @@ export type ObservedOutboundTrackStats<K extends MediaKind> = ObservedOutboundTr
|
|
|
23
23
|
deltaSentBytes: number;
|
|
24
24
|
deltaSentFrames?: number;
|
|
25
25
|
deltaEncodedFrames?: number;
|
|
26
|
+
statsTimestamp: number;
|
|
26
27
|
};
|
|
27
28
|
export declare interface ObservedOutboundTrack<Kind extends MediaKind> {
|
|
28
29
|
on<U extends keyof ObservedOutboundTrackEvents>(event: U, listener: (...args: ObservedOutboundTrackEvents[U]) => void): this;
|
|
@@ -48,6 +49,7 @@ export declare class ObservedOutboundTrack<Kind extends MediaKind> extends Event
|
|
|
48
49
|
deltaSentFrames: number;
|
|
49
50
|
deltaEncodedFrames: number;
|
|
50
51
|
private readonly _stats;
|
|
52
|
+
private _lastMaxStatsTimestamp;
|
|
51
53
|
private _closed;
|
|
52
54
|
private _updated;
|
|
53
55
|
private _remoteInboundTracks;
|
|
@@ -67,7 +69,7 @@ export declare class ObservedOutboundTrack<Kind extends MediaKind> extends Event
|
|
|
67
69
|
get stats(): ReadonlyMap<number, ObservedOutboundTrackStats<Kind>>;
|
|
68
70
|
get closed(): boolean;
|
|
69
71
|
close(): void;
|
|
70
|
-
resetMetrics(): void;
|
|
71
72
|
connectInboundTrack(track: ObservedInboundTrack<Kind>): void;
|
|
73
|
+
updateMetrics(): void;
|
|
72
74
|
}
|
|
73
75
|
//# sourceMappingURL=ObservedOutboundTrack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedOutboundTrack.d.ts","sourceRoot":"","sources":["../src/ObservedOutboundTrack.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,SAAS,IAAI;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,CAAC,CAAC;IACR,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACzC,MAAM,EAAE,EAAE,CAAC;IACX,KAAK,EAAE,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,gCAAgC,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,SAAS,OAAO,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAEhI,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,SAAS,IAAI,gCAAgC,CAAC,CAAC,CAAC,GAAG;IACnG,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ObservedOutboundTrack.d.ts","sourceRoot":"","sources":["../src/ObservedOutboundTrack.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ class ObservedOutboundTrack extends events_1.EventEmitter {
|
|
|
19
19
|
this.deltaSentFrames = 0;
|
|
20
20
|
this.deltaEncodedFrames = 0;
|
|
21
21
|
this._stats = new Map();
|
|
22
|
+
this._lastMaxStatsTimestamp = 0;
|
|
22
23
|
this._closed = false;
|
|
23
24
|
this._updated = Date.now();
|
|
24
25
|
this._remoteInboundTracks = new Map();
|
|
@@ -72,21 +73,11 @@ class ObservedOutboundTrack extends events_1.EventEmitter {
|
|
|
72
73
|
this._closed = true;
|
|
73
74
|
this.emit('close');
|
|
74
75
|
}
|
|
75
|
-
|
|
76
|
-
this.bitrate = 0;
|
|
77
|
-
this.rttInMs = 0;
|
|
78
|
-
this.deltaLostPackets = 0;
|
|
79
|
-
this.deltaSentPackets = 0;
|
|
80
|
-
this.deltaSentBytes = 0;
|
|
81
|
-
this.deltaSentFrames = 0;
|
|
82
|
-
this.deltaEncodedFrames = 0;
|
|
83
|
-
}
|
|
84
|
-
update(sample, timestamp) {
|
|
85
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
76
|
+
update(sample, statsTimestamp) {
|
|
86
77
|
if (this._closed)
|
|
87
78
|
return;
|
|
88
79
|
const now = Date.now();
|
|
89
|
-
const report = Object.assign(Object.assign({ serviceId: this.peerConnection.client.serviceId, roomId: this.peerConnection.client.call.roomId, callId: this.peerConnection.client.call.callId, clientId: this.peerConnection.client.clientId, userId: this.peerConnection.client.userId, mediaUnitId: this.peerConnection.client.mediaUnitId, peerConnectionId: this.peerConnection.peerConnectionId }, sample), { timestamp, sampleSeq: -1, marker: this.marker });
|
|
80
|
+
const report = Object.assign(Object.assign({ serviceId: this.peerConnection.client.serviceId, roomId: this.peerConnection.client.call.roomId, callId: this.peerConnection.client.call.callId, clientId: this.peerConnection.client.clientId, userId: this.peerConnection.client.userId, mediaUnitId: this.peerConnection.client.mediaUnitId, peerConnectionId: this.peerConnection.peerConnectionId }, sample), { timestamp: statsTimestamp, sampleSeq: -1, marker: this.marker });
|
|
90
81
|
if (this.kind === 'audio')
|
|
91
82
|
this.reports.addOutboundAudioTrackReport(report);
|
|
92
83
|
else if (this.kind === 'video')
|
|
@@ -94,36 +85,53 @@ class ObservedOutboundTrack extends events_1.EventEmitter {
|
|
|
94
85
|
const elapsedTimeInMs = Math.max(1, now - this._updated);
|
|
95
86
|
const lastStat = this._stats.get(sample.ssrc);
|
|
96
87
|
const rttInMs = sample.roundTripTime ? sample.roundTripTime * 1000 : undefined;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
88
|
+
let bitrate = 0;
|
|
89
|
+
let deltaLostPackets = 0;
|
|
90
|
+
let deltaSentPackets = 0;
|
|
91
|
+
let deltaSentBytes = 0;
|
|
92
|
+
if (sample.bytesSent && (lastStat === null || lastStat === void 0 ? void 0 : lastStat.bytesSent) && lastStat.bytesSent < sample.bytesSent) {
|
|
93
|
+
bitrate = (sample.bytesSent - lastStat.bytesSent) * 8 / (elapsedTimeInMs / 1000);
|
|
94
|
+
}
|
|
95
|
+
if (sample.packetsLost && (lastStat === null || lastStat === void 0 ? void 0 : lastStat.packetsLost) && lastStat.packetsLost < sample.packetsLost) {
|
|
96
|
+
deltaLostPackets = sample.packetsLost - lastStat.packetsLost;
|
|
97
|
+
}
|
|
98
|
+
if (sample.packetsSent && (lastStat === null || lastStat === void 0 ? void 0 : lastStat.packetsSent) && lastStat.packetsSent < sample.packetsSent) {
|
|
99
|
+
deltaSentPackets = sample.packetsSent - lastStat.packetsSent;
|
|
100
|
+
}
|
|
101
|
+
if (sample.bytesSent && (lastStat === null || lastStat === void 0 ? void 0 : lastStat.bytesSent) && lastStat.bytesSent < sample.bytesSent) {
|
|
102
|
+
deltaSentBytes = sample.bytesSent - lastStat.bytesSent;
|
|
103
|
+
}
|
|
101
104
|
let deltaEncodedFrames;
|
|
102
105
|
let deltaSentFrames;
|
|
103
106
|
if (this.kind === 'video') {
|
|
104
107
|
const videoSample = sample;
|
|
105
108
|
const lastVideoStats = lastStat;
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
if ((videoSample === null || videoSample === void 0 ? void 0 : videoSample.framesEncoded) && (lastVideoStats === null || lastVideoStats === void 0 ? void 0 : lastVideoStats.framesEncoded) && lastVideoStats.framesEncoded < videoSample.framesEncoded) {
|
|
110
|
+
deltaEncodedFrames = videoSample.framesEncoded - lastVideoStats.framesEncoded;
|
|
111
|
+
}
|
|
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
|
+
deltaSentFrames = videoSample.framesSent - lastVideoStats.framesSent;
|
|
114
|
+
}
|
|
108
115
|
}
|
|
109
116
|
const stats = Object.assign(Object.assign({}, sample), { rttInMs,
|
|
110
117
|
bitrate, ssrc: sample.ssrc, deltaLostPackets,
|
|
111
118
|
deltaSentPackets,
|
|
112
119
|
deltaSentBytes,
|
|
113
120
|
deltaEncodedFrames,
|
|
114
|
-
deltaSentFrames
|
|
121
|
+
deltaSentFrames,
|
|
122
|
+
statsTimestamp });
|
|
115
123
|
this._stats.set(sample.ssrc, stats);
|
|
116
|
-
this.bitrate = [...this._stats.values()].reduce((acc, stat) => acc + stat.bitrate, 0);
|
|
117
|
-
this.rttInMs = [...this._stats.values()].reduce((acc, stat) =>
|
|
118
|
-
this.totalLostPackets = [...this._stats.values()].reduce((acc, stat) =>
|
|
119
|
-
this.totalSentPackets = [...this._stats.values()].reduce((acc, stat) =>
|
|
120
|
-
this.totalSentBytes = [...this._stats.values()].reduce((acc, stat) =>
|
|
121
|
-
this.totalSentFrames = [...this._stats.values()].reduce((acc, stat) =>
|
|
122
|
-
this.deltaEncodedFrames = [...this._stats.values()].reduce((acc, stat) =>
|
|
123
|
-
this.deltaSentFrames = [...this._stats.values()].reduce((acc, stat) =>
|
|
124
|
-
this.deltaLostPackets = [...this._stats.values()].reduce((acc, stat) => acc + stat.deltaLostPackets, 0);
|
|
125
|
-
this.deltaSentPackets = [...this._stats.values()].reduce((acc, stat) => acc + stat.deltaSentPackets, 0);
|
|
126
|
-
this.deltaSentBytes = [...this._stats.values()].reduce((acc, stat) => acc + stat.deltaSentBytes, 0);
|
|
124
|
+
// this.bitrate = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.bitrate, 0);
|
|
125
|
+
// this.rttInMs = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.rttInMs ?? 0), 0) / (this._stats.size || 1);
|
|
126
|
+
// this.totalLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.packetsLost ?? 0), 0);
|
|
127
|
+
// this.totalSentPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.packetsSent ?? 0), 0);
|
|
128
|
+
// this.totalSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.bytesSent ?? 0), 0);
|
|
129
|
+
// this.totalSentFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaSentPackets ?? 0), 0);
|
|
130
|
+
// this.deltaEncodedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaEncodedFrames ?? 0), 0);
|
|
131
|
+
// this.deltaSentFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaSentFrames ?? 0), 0);
|
|
132
|
+
// this.deltaLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaLostPackets, 0);
|
|
133
|
+
// this.deltaSentPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentPackets, 0);
|
|
134
|
+
// this.deltaSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentBytes, 0);
|
|
127
135
|
// setting up sfu connection as it is not always available at the first sample
|
|
128
136
|
if (sample.sfuStreamId && !this._model.sfuStreamId) {
|
|
129
137
|
this._model.sfuStreamId = sample.sfuStreamId;
|
|
@@ -152,5 +160,37 @@ class ObservedOutboundTrack extends events_1.EventEmitter {
|
|
|
152
160
|
});
|
|
153
161
|
this._remoteInboundTracks.set(track.trackId, track);
|
|
154
162
|
}
|
|
163
|
+
updateMetrics() {
|
|
164
|
+
var _a, _b, _c, _d, _e, _f;
|
|
165
|
+
let maxStatsTimestamp = 0;
|
|
166
|
+
let rttInMsSum = 0;
|
|
167
|
+
let size = 0;
|
|
168
|
+
this.bitrate = 0;
|
|
169
|
+
this.rttInMs = undefined;
|
|
170
|
+
this.deltaLostPackets = 0;
|
|
171
|
+
this.deltaSentPackets = 0;
|
|
172
|
+
this.deltaSentBytes = 0;
|
|
173
|
+
this.deltaSentFrames = 0;
|
|
174
|
+
this.deltaEncodedFrames = 0;
|
|
175
|
+
for (const [, stats] of this._stats) {
|
|
176
|
+
if (stats.statsTimestamp <= this._lastMaxStatsTimestamp)
|
|
177
|
+
continue;
|
|
178
|
+
this.deltaLostPackets += (_a = stats.deltaLostPackets) !== null && _a !== void 0 ? _a : 0;
|
|
179
|
+
this.deltaSentPackets += (_b = stats.deltaSentPackets) !== null && _b !== void 0 ? _b : 0;
|
|
180
|
+
this.deltaSentBytes += (_c = stats.deltaSentBytes) !== null && _c !== void 0 ? _c : 0;
|
|
181
|
+
this.deltaSentFrames += (_d = stats.deltaSentFrames) !== null && _d !== void 0 ? _d : 0;
|
|
182
|
+
this.deltaEncodedFrames += (_e = stats.deltaEncodedFrames) !== null && _e !== void 0 ? _e : 0;
|
|
183
|
+
this.bitrate += stats.bitrate;
|
|
184
|
+
maxStatsTimestamp = Math.max(maxStatsTimestamp, stats.statsTimestamp);
|
|
185
|
+
rttInMsSum += (_f = stats.rttInMs) !== null && _f !== void 0 ? _f : 0;
|
|
186
|
+
++size;
|
|
187
|
+
}
|
|
188
|
+
this.totalLostPackets += this.deltaLostPackets;
|
|
189
|
+
this.totalSentPackets += this.deltaSentPackets;
|
|
190
|
+
this.totalSentBytes += this.deltaSentBytes;
|
|
191
|
+
this.totalSentFrames += this.deltaSentFrames;
|
|
192
|
+
this.rttInMs = rttInMsSum / Math.max(size, 1);
|
|
193
|
+
this._lastMaxStatsTimestamp = maxStatsTimestamp;
|
|
194
|
+
}
|
|
155
195
|
}
|
|
156
196
|
exports.ObservedOutboundTrack = ObservedOutboundTrack;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservedPeerConnection.d.ts","sourceRoot":"","sources":["../src/ObservedPeerConnection.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ObservedPeerConnection.d.ts","sourceRoot":"","sources":["../src/ObservedPeerConnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -151,33 +151,25 @@ class ObservedPeerConnection extends events_1.EventEmitter {
|
|
|
151
151
|
this.deltaOutboundPacketsSent = 0;
|
|
152
152
|
this.deltaDataChannelBytesSent = 0;
|
|
153
153
|
this.deltaDataChannelBytesReceived = 0;
|
|
154
|
+
this.deltaInboundReceivedBytes = 0;
|
|
155
|
+
this.deltaOutboundSentBytes = 0;
|
|
154
156
|
this.deltaReceivedAudioBytes = 0;
|
|
155
157
|
this.deltaReceivedVideoBytes = 0;
|
|
158
|
+
this.deltaReceivedAudioPackets = 0;
|
|
159
|
+
this.deltaReceivedVideoPackets = 0;
|
|
156
160
|
this.deltaSentAudioBytes = 0;
|
|
157
161
|
this.deltaSentVideoBytes = 0;
|
|
158
|
-
this.
|
|
159
|
-
this.
|
|
160
|
-
this.
|
|
161
|
-
this.
|
|
162
|
+
this.sendingAudioBitrate = 0;
|
|
163
|
+
this.sendingVideoBitrate = 0;
|
|
164
|
+
this.receivingAudioBitrate = 0;
|
|
165
|
+
this.receivingVideoBitrate = 0;
|
|
162
166
|
}
|
|
163
167
|
updateMetrics() {
|
|
164
|
-
// this.totalInboundPacketsLost = 0;
|
|
165
|
-
// this.totalInboundPacketsReceived = 0;
|
|
166
|
-
// this.totalOutboundPacketsSent = 0;
|
|
167
|
-
// this.totalDataChannelBytesSent = 0;
|
|
168
|
-
// this.totalDataChannelBytesReceived = 0;
|
|
169
168
|
var _a;
|
|
170
|
-
// this.totalSentAudioBytes = 0;
|
|
171
|
-
// this.totalSentVideoBytes = 0;
|
|
172
|
-
// this.totalReceivedAudioBytes = 0;
|
|
173
|
-
// this.totalReceivedVideoBytes = 0;
|
|
174
|
-
// this.sendingAudioBitrate = 0;
|
|
175
|
-
// this.sendingVideoBitrate = 0;
|
|
176
|
-
// this.receivingAudioBitrate = 0;
|
|
177
|
-
// this.receivingVideoBitrate = 0;
|
|
178
169
|
let sumRttInMs = 0;
|
|
179
170
|
this._inboundAudioTracks.forEach((track) => {
|
|
180
171
|
var _a;
|
|
172
|
+
track.updateMetrics();
|
|
181
173
|
this.deltaInboundPacketsLost += track.deltaLostPackets;
|
|
182
174
|
this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
|
|
183
175
|
this.deltaInboundReceivedBytes += track.deltaBytesReceived;
|
|
@@ -188,6 +180,7 @@ class ObservedPeerConnection extends events_1.EventEmitter {
|
|
|
188
180
|
});
|
|
189
181
|
this._inboundVideoTracks.forEach((track) => {
|
|
190
182
|
var _a;
|
|
183
|
+
track.updateMetrics();
|
|
191
184
|
this.deltaInboundPacketsLost += track.deltaLostPackets;
|
|
192
185
|
this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
|
|
193
186
|
this.deltaInboundReceivedBytes += track.deltaBytesReceived;
|
|
@@ -198,6 +191,7 @@ class ObservedPeerConnection extends events_1.EventEmitter {
|
|
|
198
191
|
});
|
|
199
192
|
this._outboundAudioTracks.forEach((track) => {
|
|
200
193
|
var _a;
|
|
194
|
+
track.updateMetrics();
|
|
201
195
|
this.deltaOutboundPacketsSent += track.deltaSentPackets;
|
|
202
196
|
this.deltaOutboundSentBytes += track.deltaSentBytes;
|
|
203
197
|
this.deltaSentAudioBytes += track.deltaSentBytes;
|
|
@@ -207,6 +201,7 @@ class ObservedPeerConnection extends events_1.EventEmitter {
|
|
|
207
201
|
});
|
|
208
202
|
this._outboundVideoTracks.forEach((track) => {
|
|
209
203
|
var _a;
|
|
204
|
+
track.updateMetrics();
|
|
210
205
|
this.deltaOutboundPacketsSent += track.deltaSentPackets;
|
|
211
206
|
this.deltaOutboundSentBytes += track.deltaSentBytes;
|
|
212
207
|
this.deltaSentVideoBytes += track.deltaSentBytes;
|
package/lib/Observer.d.ts
CHANGED
|
@@ -45,8 +45,9 @@ export declare class Observer extends EventEmitter {
|
|
|
45
45
|
private _reportTimer?;
|
|
46
46
|
private _closed;
|
|
47
47
|
constructor(config: ObserverConfig);
|
|
48
|
-
createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(config: PartialBy<ObservedCallModel, 'serviceId'
|
|
48
|
+
createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(config: PartialBy<ObservedCallModel, 'serviceId'> & {
|
|
49
49
|
appData: T;
|
|
50
|
+
started?: number;
|
|
50
51
|
}): ObservedCall<T>;
|
|
51
52
|
createObservedSfu<AppData extends Record<string, unknown> = Record<string, unknown>>(model: ObservedSfuModel, appData: AppData): ObservedSfu<AppData>;
|
|
52
53
|
get observedCalls(): ReadonlyMap<string, ObservedCall>;
|
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;AAI9D,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;IAE3C,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C,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;aA0BxB,MAAM,EAAE,cAAc;WAzBzB,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;IAEhE,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,
|
|
1
|
+
{"version":3,"file":"Observer.d.ts","sourceRoot":"","sources":["../src/Observer.ts"],"names":[],"mappings":"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"}
|
package/lib/Observer.js
CHANGED
|
@@ -62,8 +62,8 @@ class Observer extends events_1.EventEmitter {
|
|
|
62
62
|
if (this._closed) {
|
|
63
63
|
throw new Error('Attempted to create a call source on a closed observer');
|
|
64
64
|
}
|
|
65
|
-
const { appData } = config, model = __rest(config, ["appData"]);
|
|
66
|
-
const call = new ObservedCall_1.ObservedCall(Object.assign(Object.assign({}, model), { serviceId: this.config.defaultServiceId
|
|
65
|
+
const { appData, started = Date.now() } = config, model = __rest(config, ["appData", "started"]);
|
|
66
|
+
const call = new ObservedCall_1.ObservedCall(Object.assign(Object.assign({}, model), { serviceId: this.config.defaultServiceId }), this, appData);
|
|
67
67
|
if (this._closed)
|
|
68
68
|
throw new Error('Cannot create an observed call on a closed observer');
|
|
69
69
|
if (this._observedCalls.has(call.callId))
|
|
@@ -73,7 +73,7 @@ class Observer extends events_1.EventEmitter {
|
|
|
73
73
|
this.reports.addCallEventReport((0, callEventReports_1.createCallEndedEventReport)(call.serviceId, call.roomId, call.callId, Date.now()));
|
|
74
74
|
});
|
|
75
75
|
this._observedCalls.set(call.callId, call);
|
|
76
|
-
this.reports.addCallEventReport((0, callEventReports_1.createCallStartedEventReport)(call.serviceId, call.roomId, call.callId,
|
|
76
|
+
this.reports.addCallEventReport((0, callEventReports_1.createCallStartedEventReport)(call.serviceId, call.roomId, call.callId, started));
|
|
77
77
|
this.emit('newcall', call);
|
|
78
78
|
return call;
|
|
79
79
|
}
|
package/package.json
CHANGED
package/src/ObservedCall.ts
CHANGED
|
@@ -8,7 +8,6 @@ export type ObservedCallModel = {
|
|
|
8
8
|
serviceId: string;
|
|
9
9
|
roomId: string;
|
|
10
10
|
callId: string;
|
|
11
|
-
started: number,
|
|
12
11
|
};
|
|
13
12
|
|
|
14
13
|
export type ObservedCallEvents = {
|
|
@@ -63,8 +62,8 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
63
62
|
return this._model.callId!;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
public get
|
|
67
|
-
return
|
|
65
|
+
public get updated() {
|
|
66
|
+
return this._updated;
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
public get ended() {
|
|
@@ -25,14 +25,16 @@ export type ObservedInboundTrackStats<K extends MediaKind> = ObservedInboundTrac
|
|
|
25
25
|
bitrate: number;
|
|
26
26
|
fractionLost: number;
|
|
27
27
|
rttInMs?: number;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
deltaReceivedBytes?: number;
|
|
29
|
+
deltaLostPackets?: number;
|
|
30
|
+
deltaReceivedPackets?: number;
|
|
31
|
+
deltaReceivedFrames?: number;
|
|
32
|
+
deltaDecodedFrames?: number;
|
|
33
|
+
deltaDroppedFrames?: number;
|
|
34
|
+
deltaReceivedSamples?: number;
|
|
35
|
+
deltaSilentConcealedSamples?: number;
|
|
35
36
|
fractionLoss?: number;
|
|
37
|
+
statsTimestamp: number;
|
|
36
38
|
};
|
|
37
39
|
|
|
38
40
|
// {
|
|
@@ -55,6 +57,8 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
|
|
|
55
57
|
private _closed = false;
|
|
56
58
|
private _updated = Date.now();
|
|
57
59
|
private _remoteOutboundTrack?: ObservedOutboundTrack<Kind>;
|
|
60
|
+
private _lastMaxStatsTimestamp = 0;
|
|
61
|
+
|
|
58
62
|
public bitrate = 0;
|
|
59
63
|
public rttInMs?: number;
|
|
60
64
|
public fractionLoss = 0;
|
|
@@ -165,20 +169,7 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
|
|
|
165
169
|
this.emit('close');
|
|
166
170
|
}
|
|
167
171
|
|
|
168
|
-
public
|
|
169
|
-
this.bitrate = 0;
|
|
170
|
-
this.rttInMs = undefined;
|
|
171
|
-
this.deltaBytesReceived = 0;
|
|
172
|
-
this.deltaLostPackets = 0;
|
|
173
|
-
this.deltaReceivedFrames = 0;
|
|
174
|
-
this.deltaDecodedFrames = 0;
|
|
175
|
-
this.deltaDroppedFrames = 0;
|
|
176
|
-
this.deltaReceivedSamples = 0;
|
|
177
|
-
this.deltaSilentConcealedSamples = 0;
|
|
178
|
-
this.fractionLoss = 0;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
public update(sample: ObservedInboundTrackStatsUpdate<Kind>, timestamp: number) {
|
|
172
|
+
public update(sample: ObservedInboundTrackStatsUpdate<Kind>, statsTimestamp: number) {
|
|
182
173
|
if (this._closed) return;
|
|
183
174
|
|
|
184
175
|
const now = Date.now();
|
|
@@ -191,7 +182,7 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
|
|
|
191
182
|
mediaUnitId: this.peerConnection.client.mediaUnitId,
|
|
192
183
|
peerConnectionId: this.peerConnection.peerConnectionId,
|
|
193
184
|
...sample,
|
|
194
|
-
timestamp,
|
|
185
|
+
timestamp: statsTimestamp,
|
|
195
186
|
sampleSeq: -1,
|
|
196
187
|
|
|
197
188
|
remoteClientId: sample.remoteClientId ?? this.remoteOutboundTrack?.peerConnection.client.clientId,
|
|
@@ -215,27 +206,51 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
|
|
|
215
206
|
const elapsedTimeInMs = Math.max(1, now - this._updated);
|
|
216
207
|
const lastStat = this._stats.get(sample.ssrc);
|
|
217
208
|
const rttInMs = sample.roundTripTime ? sample.roundTripTime * 1000 : undefined;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
let
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
209
|
+
let bitrate = 0;
|
|
210
|
+
let deltaReceivedBytes = 0;
|
|
211
|
+
let fractionLost = 0;
|
|
212
|
+
let deltaLostPackets = 0;
|
|
213
|
+
let deltaReceivedPackets = 0;
|
|
214
|
+
|
|
215
|
+
if (lastStat?.bytesReceived && sample.bytesReceived && lastStat.bytesReceived < sample.bytesReceived) {
|
|
216
|
+
deltaReceivedBytes = sample.bytesReceived - lastStat.bytesReceived;
|
|
217
|
+
bitrate = deltaReceivedBytes / (elapsedTimeInMs / 1000);
|
|
218
|
+
}
|
|
219
|
+
if (lastStat?.packetsReceived && sample?.packetsReceived && lastStat.packetsReceived < sample.packetsReceived) {
|
|
220
|
+
deltaReceivedPackets = sample.packetsReceived - lastStat.packetsReceived;
|
|
221
|
+
}
|
|
222
|
+
if (lastStat?.packetsLost && sample.packetsLost && lastStat.packetsLost < sample.packetsLost) {
|
|
223
|
+
deltaLostPackets = sample.packetsLost - lastStat.packetsLost;
|
|
224
|
+
if (0 < deltaReceivedPackets) {
|
|
225
|
+
fractionLost = deltaLostPackets / (deltaReceivedPackets + deltaLostPackets);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
let deltaDecodedFrames: number | undefined;
|
|
230
|
+
let deltaDroppedFrames: number | undefined;
|
|
231
|
+
let deltaReceivedFrames: number | undefined;
|
|
232
|
+
let deltaSilentConcealedSamples: number | undefined;
|
|
226
233
|
|
|
227
234
|
if (this.kind === 'video') {
|
|
228
235
|
const videoSample = sample as InboundVideoTrack;
|
|
229
236
|
const lastVideoStat = lastStat as InboundVideoTrack | undefined;
|
|
230
237
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
238
|
+
if (videoSample.framesDecoded && lastVideoStat?.framesDecoded && lastVideoStat.framesDecoded < videoSample.framesDecoded) {
|
|
239
|
+
deltaDecodedFrames = videoSample.framesDecoded - lastVideoStat.framesDecoded;
|
|
240
|
+
}
|
|
241
|
+
if (videoSample.framesDropped && lastVideoStat?.framesDropped && lastVideoStat.framesDropped < videoSample.framesDropped) {
|
|
242
|
+
deltaDroppedFrames = videoSample.framesDropped - lastVideoStat.framesDropped;
|
|
243
|
+
}
|
|
244
|
+
if (videoSample.framesReceived && lastVideoStat?.framesReceived && lastVideoStat.framesReceived < videoSample.framesReceived) {
|
|
245
|
+
deltaReceivedFrames = videoSample.framesReceived - lastVideoStat.framesReceived;
|
|
246
|
+
}
|
|
234
247
|
} else if (this.kind === 'audio') {
|
|
235
248
|
const audioSample = sample as InboundAudioTrack;
|
|
236
249
|
const lastAudioStat = lastStat as InboundAudioTrack | undefined;
|
|
237
|
-
|
|
238
|
-
|
|
250
|
+
|
|
251
|
+
if (audioSample.silentConcealedSamples && lastAudioStat?.silentConcealedSamples && lastAudioStat.silentConcealedSamples < audioSample.silentConcealedSamples) {
|
|
252
|
+
deltaSilentConcealedSamples = audioSample.silentConcealedSamples - lastAudioStat.silentConcealedSamples;
|
|
253
|
+
}
|
|
239
254
|
}
|
|
240
255
|
|
|
241
256
|
const stats: ObservedInboundTrackStats<Kind> = {
|
|
@@ -244,38 +259,69 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
|
|
|
244
259
|
rttInMs,
|
|
245
260
|
bitrate,
|
|
246
261
|
ssrc: sample.ssrc,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
262
|
+
deltaReceivedBytes,
|
|
263
|
+
deltaLostPackets,
|
|
264
|
+
deltaReceivedPackets,
|
|
265
|
+
deltaReceivedFrames,
|
|
266
|
+
deltaDecodedFrames,
|
|
267
|
+
deltaDroppedFrames,
|
|
268
|
+
deltaSilentConcealedSamples,
|
|
269
|
+
statsTimestamp,
|
|
253
270
|
};
|
|
254
271
|
|
|
255
272
|
this._stats.set(sample.ssrc, stats);
|
|
256
273
|
|
|
257
|
-
this.bitrate = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.bitrate, 0);
|
|
258
|
-
this.rttInMs = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.rttInMs ?? 0), 0) / (this._stats.size || 1);
|
|
259
|
-
this.totalLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.lostPackets ?? 0), 0);
|
|
260
|
-
this.totalReceivedPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.receivedPackets ?? 0), 0);
|
|
261
|
-
this.totalBytesReceived = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.bytesReceived ?? 0), 0);
|
|
262
|
-
this.totalReceivedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.receivedFrames ?? 0), 0);
|
|
263
|
-
this.totalDecodedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.decodedFrames ?? 0), 0);
|
|
264
|
-
this.totalDroppedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.droppedFrames ?? 0), 0);
|
|
265
|
-
this.totalReceivedSamples = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.receivedSamples ?? 0), 0);
|
|
266
|
-
this.totalSilentConcealedSamples = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.silentConcealedSamples ?? 0), 0);
|
|
267
|
-
|
|
268
|
-
this.deltaLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.lostPackets ?? 0), 0);
|
|
269
|
-
this.deltaReceivedPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.receivedPackets ?? 0), 0);
|
|
270
|
-
this.deltaBytesReceived = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.bytesReceived ?? 0), 0);
|
|
271
|
-
this.deltaReceivedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.receivedFrames ?? 0), 0);
|
|
272
|
-
this.deltaDecodedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.decodedFrames ?? 0), 0);
|
|
273
|
-
this.deltaDroppedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.droppedFrames ?? 0), 0);
|
|
274
|
-
this.deltaReceivedSamples = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.receivedSamples ?? 0), 0);
|
|
275
|
-
this.deltaSilentConcealedSamples = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.silentConcealedSamples ?? 0), 0);
|
|
276
|
-
this.fractionLoss = 0 < this.deltaReceivedPackets && 0 < this.deltaLostPackets ? (this.deltaLostPackets / (this.deltaReceivedPackets + this.deltaLostPackets)) : 0;
|
|
277
|
-
|
|
278
274
|
this._updated = now;
|
|
279
275
|
this.emit('update');
|
|
280
276
|
}
|
|
277
|
+
|
|
278
|
+
public updateMetrics() {
|
|
279
|
+
let maxStatsTimestamp = 0;
|
|
280
|
+
let rttInMsSum = 0;
|
|
281
|
+
let size = 0;
|
|
282
|
+
|
|
283
|
+
this.bitrate = 0;
|
|
284
|
+
this.rttInMs = undefined;
|
|
285
|
+
this.deltaBytesReceived = 0;
|
|
286
|
+
this.deltaLostPackets = 0;
|
|
287
|
+
this.deltaReceivedFrames = 0;
|
|
288
|
+
this.deltaDecodedFrames = 0;
|
|
289
|
+
this.deltaDroppedFrames = 0;
|
|
290
|
+
this.deltaReceivedSamples = 0;
|
|
291
|
+
this.deltaSilentConcealedSamples = 0;
|
|
292
|
+
this.fractionLoss = 0;
|
|
293
|
+
|
|
294
|
+
for (const [ , stats ] of this._stats) {
|
|
295
|
+
if (stats.statsTimestamp <= this._lastMaxStatsTimestamp) continue;
|
|
296
|
+
|
|
297
|
+
this.deltaBytesReceived += stats.deltaReceivedBytes ?? 0;
|
|
298
|
+
this.deltaLostPackets += stats.deltaLostPackets ?? 0;
|
|
299
|
+
this.deltaReceivedPackets += stats.deltaReceivedFrames ?? 0;
|
|
300
|
+
this.deltaReceivedFrames += stats.deltaReceivedFrames ?? 0;
|
|
301
|
+
this.deltaDecodedFrames += stats.deltaDecodedFrames ?? 0;
|
|
302
|
+
this.deltaDroppedFrames += stats.deltaDroppedFrames ?? 0;
|
|
303
|
+
this.deltaReceivedSamples += stats.deltaReceivedSamples ?? 0;
|
|
304
|
+
this.deltaSilentConcealedSamples += stats.deltaSilentConcealedSamples ?? 0;
|
|
305
|
+
this.bitrate += stats.bitrate;
|
|
306
|
+
|
|
307
|
+
maxStatsTimestamp = Math.max(maxStatsTimestamp, stats.statsTimestamp);
|
|
308
|
+
|
|
309
|
+
rttInMsSum += stats.rttInMs ?? 0;
|
|
310
|
+
++size;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
this.totalBytesReceived += this.deltaBytesReceived;
|
|
314
|
+
this.totalLostPackets += this.deltaLostPackets;
|
|
315
|
+
this.totalReceivedPackets += this.deltaReceivedPackets;
|
|
316
|
+
this.totalReceivedFrames += this.deltaReceivedFrames;
|
|
317
|
+
this.totalDecodedFrames += this.deltaDecodedFrames;
|
|
318
|
+
this.totalDroppedFrames += this.deltaDroppedFrames;
|
|
319
|
+
this.totalReceivedSamples += this.deltaReceivedSamples;
|
|
320
|
+
this.totalSilentConcealedSamples += this.deltaSilentConcealedSamples;
|
|
321
|
+
|
|
322
|
+
this.rttInMs = rttInMsSum / Math.max(size, 1);
|
|
323
|
+
this.fractionLoss = 0 < this.deltaReceivedPackets && 0 < this.deltaLostPackets ? (this.deltaLostPackets / (this.deltaReceivedPackets + this.deltaLostPackets)) : 0;
|
|
324
|
+
|
|
325
|
+
this._lastMaxStatsTimestamp = maxStatsTimestamp;
|
|
326
|
+
}
|
|
281
327
|
}
|
|
@@ -28,6 +28,8 @@ export type ObservedOutboundTrackStats<K extends MediaKind> = ObservedOutboundTr
|
|
|
28
28
|
deltaSentBytes: number;
|
|
29
29
|
deltaSentFrames?: number;
|
|
30
30
|
deltaEncodedFrames?: number;
|
|
31
|
+
|
|
32
|
+
statsTimestamp: number;
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
// export type ObservedOutboundTrackStatsUpdate<K extends MediaKind> = {
|
|
@@ -61,6 +63,7 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
61
63
|
public deltaEncodedFrames = 0;
|
|
62
64
|
|
|
63
65
|
private readonly _stats = new Map<number, ObservedOutboundTrackStats<Kind>>();
|
|
66
|
+
private _lastMaxStatsTimestamp = 0;
|
|
64
67
|
|
|
65
68
|
private _closed = false;
|
|
66
69
|
private _updated = Date.now();
|
|
@@ -137,18 +140,7 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
137
140
|
this.emit('close');
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
public
|
|
141
|
-
this.bitrate = 0;
|
|
142
|
-
this.rttInMs = 0;
|
|
143
|
-
|
|
144
|
-
this.deltaLostPackets = 0;
|
|
145
|
-
this.deltaSentPackets = 0;
|
|
146
|
-
this.deltaSentBytes = 0;
|
|
147
|
-
this.deltaSentFrames = 0;
|
|
148
|
-
this.deltaEncodedFrames = 0;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
public update(sample: ObservedOutboundTrackStatsUpdate<Kind>, timestamp: number): void {
|
|
143
|
+
public update(sample: ObservedOutboundTrackStatsUpdate<Kind>, statsTimestamp: number): void {
|
|
152
144
|
if (this._closed) return;
|
|
153
145
|
|
|
154
146
|
const now = Date.now();
|
|
@@ -161,7 +153,7 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
161
153
|
mediaUnitId: this.peerConnection.client.mediaUnitId,
|
|
162
154
|
peerConnectionId: this.peerConnection.peerConnectionId,
|
|
163
155
|
...sample,
|
|
164
|
-
timestamp,
|
|
156
|
+
timestamp: statsTimestamp,
|
|
165
157
|
sampleSeq: -1,
|
|
166
158
|
marker: this.marker,
|
|
167
159
|
};
|
|
@@ -172,10 +164,24 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
172
164
|
const elapsedTimeInMs = Math.max(1, now - this._updated);
|
|
173
165
|
const lastStat = this._stats.get(sample.ssrc);
|
|
174
166
|
const rttInMs = sample.roundTripTime ? sample.roundTripTime * 1000 : undefined;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
167
|
+
let bitrate = 0;
|
|
168
|
+
let deltaLostPackets = 0;
|
|
169
|
+
let deltaSentPackets = 0;
|
|
170
|
+
let deltaSentBytes = 0;
|
|
171
|
+
|
|
172
|
+
if (sample.bytesSent && lastStat?.bytesSent && lastStat.bytesSent < sample.bytesSent) {
|
|
173
|
+
bitrate = (sample.bytesSent - lastStat.bytesSent) * 8 / (elapsedTimeInMs / 1000);
|
|
174
|
+
}
|
|
175
|
+
if (sample.packetsLost && lastStat?.packetsLost && lastStat.packetsLost < sample.packetsLost) {
|
|
176
|
+
deltaLostPackets = sample.packetsLost - lastStat.packetsLost;
|
|
177
|
+
}
|
|
178
|
+
if (sample.packetsSent && lastStat?.packetsSent && lastStat.packetsSent < sample.packetsSent) {
|
|
179
|
+
deltaSentPackets = sample.packetsSent - lastStat.packetsSent;
|
|
180
|
+
}
|
|
181
|
+
if (sample.bytesSent && lastStat?.bytesSent && lastStat.bytesSent < sample.bytesSent) {
|
|
182
|
+
deltaSentBytes = sample.bytesSent - lastStat.bytesSent;
|
|
183
|
+
}
|
|
184
|
+
|
|
179
185
|
let deltaEncodedFrames: number | undefined;
|
|
180
186
|
let deltaSentFrames: number | undefined;
|
|
181
187
|
|
|
@@ -183,8 +189,12 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
183
189
|
const videoSample = sample as OutboundVideoTrack;
|
|
184
190
|
const lastVideoStats = lastStat as OutboundVideoTrack | undefined;
|
|
185
191
|
|
|
186
|
-
|
|
187
|
-
|
|
192
|
+
if (videoSample?.framesEncoded && lastVideoStats?.framesEncoded && lastVideoStats.framesEncoded < videoSample.framesEncoded) {
|
|
193
|
+
deltaEncodedFrames = videoSample.framesEncoded - lastVideoStats.framesEncoded;
|
|
194
|
+
}
|
|
195
|
+
if (videoSample?.framesSent && lastVideoStats?.framesSent && lastVideoStats.framesSent < videoSample.framesSent) {
|
|
196
|
+
deltaSentFrames = videoSample.framesSent - lastVideoStats.framesSent;
|
|
197
|
+
}
|
|
188
198
|
}
|
|
189
199
|
const stats: ObservedOutboundTrackStats<Kind> = {
|
|
190
200
|
...sample,
|
|
@@ -197,23 +207,25 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
197
207
|
deltaSentBytes,
|
|
198
208
|
deltaEncodedFrames,
|
|
199
209
|
deltaSentFrames,
|
|
210
|
+
|
|
211
|
+
statsTimestamp,
|
|
200
212
|
};
|
|
201
213
|
|
|
202
214
|
this._stats.set(sample.ssrc, stats);
|
|
203
215
|
|
|
204
|
-
this.bitrate = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.bitrate, 0);
|
|
205
|
-
this.rttInMs = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.rttInMs ?? 0), 0) / (this._stats.size || 1);
|
|
216
|
+
// this.bitrate = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.bitrate, 0);
|
|
217
|
+
// this.rttInMs = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.rttInMs ?? 0), 0) / (this._stats.size || 1);
|
|
206
218
|
|
|
207
|
-
this.totalLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.packetsLost ?? 0), 0);
|
|
208
|
-
this.totalSentPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.packetsSent ?? 0), 0);
|
|
209
|
-
this.totalSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.bytesSent ?? 0), 0);
|
|
210
|
-
this.totalSentFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaSentPackets ?? 0), 0);
|
|
219
|
+
// this.totalLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.packetsLost ?? 0), 0);
|
|
220
|
+
// this.totalSentPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.packetsSent ?? 0), 0);
|
|
221
|
+
// this.totalSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.bytesSent ?? 0), 0);
|
|
222
|
+
// this.totalSentFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaSentPackets ?? 0), 0);
|
|
211
223
|
|
|
212
|
-
this.deltaEncodedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaEncodedFrames ?? 0), 0);
|
|
213
|
-
this.deltaSentFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaSentFrames ?? 0), 0);
|
|
214
|
-
this.deltaLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaLostPackets, 0);
|
|
215
|
-
this.deltaSentPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentPackets, 0);
|
|
216
|
-
this.deltaSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentBytes, 0);
|
|
224
|
+
// this.deltaEncodedFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaEncodedFrames ?? 0), 0);
|
|
225
|
+
// this.deltaSentFrames = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.deltaSentFrames ?? 0), 0);
|
|
226
|
+
// this.deltaLostPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaLostPackets, 0);
|
|
227
|
+
// this.deltaSentPackets = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentPackets, 0);
|
|
228
|
+
// this.deltaSentBytes = [ ...this._stats.values() ].reduce((acc, stat) => acc + stat.deltaSentBytes, 0);
|
|
217
229
|
|
|
218
230
|
// setting up sfu connection as it is not always available at the first sample
|
|
219
231
|
if (sample.sfuStreamId && !this._model.sfuStreamId) {
|
|
@@ -243,4 +255,44 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
|
|
|
243
255
|
|
|
244
256
|
this._remoteInboundTracks.set(track.trackId, track);
|
|
245
257
|
}
|
|
258
|
+
|
|
259
|
+
public updateMetrics() {
|
|
260
|
+
let maxStatsTimestamp = 0;
|
|
261
|
+
let rttInMsSum = 0;
|
|
262
|
+
let size = 0;
|
|
263
|
+
|
|
264
|
+
this.bitrate = 0;
|
|
265
|
+
this.rttInMs = undefined;
|
|
266
|
+
|
|
267
|
+
this.deltaLostPackets = 0;
|
|
268
|
+
this.deltaSentPackets = 0;
|
|
269
|
+
this.deltaSentBytes = 0;
|
|
270
|
+
this.deltaSentFrames = 0;
|
|
271
|
+
this.deltaEncodedFrames = 0;
|
|
272
|
+
|
|
273
|
+
for (const [ , stats ] of this._stats) {
|
|
274
|
+
if (stats.statsTimestamp <= this._lastMaxStatsTimestamp) continue;
|
|
275
|
+
|
|
276
|
+
this.deltaLostPackets += stats.deltaLostPackets ?? 0;
|
|
277
|
+
this.deltaSentPackets += stats.deltaSentPackets ?? 0;
|
|
278
|
+
this.deltaSentBytes += stats.deltaSentBytes ?? 0;
|
|
279
|
+
this.deltaSentFrames += stats.deltaSentFrames ?? 0;
|
|
280
|
+
this.deltaEncodedFrames += stats.deltaEncodedFrames ?? 0;
|
|
281
|
+
this.bitrate += stats.bitrate;
|
|
282
|
+
|
|
283
|
+
maxStatsTimestamp = Math.max(maxStatsTimestamp, stats.statsTimestamp);
|
|
284
|
+
|
|
285
|
+
rttInMsSum += stats.rttInMs ?? 0;
|
|
286
|
+
++size;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
this.totalLostPackets += this.deltaLostPackets;
|
|
290
|
+
this.totalSentPackets += this.deltaSentPackets;
|
|
291
|
+
this.totalSentBytes += this.deltaSentBytes;
|
|
292
|
+
this.totalSentFrames += this.deltaSentFrames;
|
|
293
|
+
|
|
294
|
+
this.rttInMs = rttInMsSum / Math.max(size, 1);
|
|
295
|
+
|
|
296
|
+
this._lastMaxStatsTimestamp = maxStatsTimestamp;
|
|
297
|
+
}
|
|
246
298
|
}
|
|
@@ -209,39 +209,29 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
209
209
|
this.deltaInboundPacketsLost = 0;
|
|
210
210
|
this.deltaInboundPacketsReceived = 0;
|
|
211
211
|
this.deltaOutboundPacketsSent = 0;
|
|
212
|
-
|
|
213
212
|
this.deltaDataChannelBytesSent = 0;
|
|
214
213
|
this.deltaDataChannelBytesReceived = 0;
|
|
214
|
+
this.deltaInboundReceivedBytes = 0;
|
|
215
|
+
this.deltaOutboundSentBytes = 0;
|
|
216
|
+
|
|
215
217
|
this.deltaReceivedAudioBytes = 0;
|
|
216
218
|
this.deltaReceivedVideoBytes = 0;
|
|
219
|
+
this.deltaReceivedAudioPackets = 0;
|
|
220
|
+
this.deltaReceivedVideoPackets = 0;
|
|
217
221
|
this.deltaSentAudioBytes = 0;
|
|
218
222
|
this.deltaSentVideoBytes = 0;
|
|
219
|
-
|
|
220
|
-
this.
|
|
221
|
-
this.
|
|
222
|
-
this.
|
|
223
|
-
this._outboundVideoTracks.forEach((track) => track.resetMetrics());
|
|
223
|
+
this.sendingAudioBitrate = 0;
|
|
224
|
+
this.sendingVideoBitrate = 0;
|
|
225
|
+
this.receivingAudioBitrate = 0;
|
|
226
|
+
this.receivingVideoBitrate = 0;
|
|
224
227
|
}
|
|
225
228
|
|
|
226
229
|
public updateMetrics() {
|
|
227
|
-
// this.totalInboundPacketsLost = 0;
|
|
228
|
-
// this.totalInboundPacketsReceived = 0;
|
|
229
|
-
// this.totalOutboundPacketsSent = 0;
|
|
230
|
-
// this.totalDataChannelBytesSent = 0;
|
|
231
|
-
// this.totalDataChannelBytesReceived = 0;
|
|
232
|
-
|
|
233
|
-
// this.totalSentAudioBytes = 0;
|
|
234
|
-
// this.totalSentVideoBytes = 0;
|
|
235
|
-
// this.totalReceivedAudioBytes = 0;
|
|
236
|
-
// this.totalReceivedVideoBytes = 0;
|
|
237
|
-
// this.sendingAudioBitrate = 0;
|
|
238
|
-
// this.sendingVideoBitrate = 0;
|
|
239
|
-
// this.receivingAudioBitrate = 0;
|
|
240
|
-
// this.receivingVideoBitrate = 0;
|
|
241
|
-
|
|
242
230
|
let sumRttInMs = 0;
|
|
243
231
|
|
|
244
232
|
this._inboundAudioTracks.forEach((track) => {
|
|
233
|
+
track.updateMetrics();
|
|
234
|
+
|
|
245
235
|
this.deltaInboundPacketsLost += track.deltaLostPackets;
|
|
246
236
|
this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
|
|
247
237
|
this.deltaInboundReceivedBytes += track.deltaBytesReceived;
|
|
@@ -255,6 +245,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
255
245
|
});
|
|
256
246
|
|
|
257
247
|
this._inboundVideoTracks.forEach((track) => {
|
|
248
|
+
track.updateMetrics();
|
|
249
|
+
|
|
258
250
|
this.deltaInboundPacketsLost += track.deltaLostPackets;
|
|
259
251
|
this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
|
|
260
252
|
this.deltaInboundReceivedBytes += track.deltaBytesReceived;
|
|
@@ -268,6 +260,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
268
260
|
});
|
|
269
261
|
|
|
270
262
|
this._outboundAudioTracks.forEach((track) => {
|
|
263
|
+
track.updateMetrics();
|
|
264
|
+
|
|
271
265
|
this.deltaOutboundPacketsSent += track.deltaSentPackets;
|
|
272
266
|
this.deltaOutboundSentBytes += track.deltaSentBytes;
|
|
273
267
|
|
|
@@ -280,6 +274,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
280
274
|
});
|
|
281
275
|
|
|
282
276
|
this._outboundVideoTracks.forEach((track) => {
|
|
277
|
+
track.updateMetrics();
|
|
278
|
+
|
|
283
279
|
this.deltaOutboundPacketsSent += track.deltaSentPackets;
|
|
284
280
|
this.deltaOutboundSentBytes += track.deltaSentBytes;
|
|
285
281
|
|
package/src/Observer.ts
CHANGED
|
@@ -99,17 +99,16 @@ export class Observer extends EventEmitter {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
public createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(
|
|
102
|
-
config: PartialBy<ObservedCallModel, 'serviceId'
|
|
102
|
+
config: PartialBy<ObservedCallModel, 'serviceId'> & { appData: T, started?: number }
|
|
103
103
|
): ObservedCall<T> {
|
|
104
104
|
if (this._closed) {
|
|
105
105
|
throw new Error('Attempted to create a call source on a closed observer');
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
const { appData, ...model } = config;
|
|
108
|
+
const { appData, started = Date.now(), ...model } = config;
|
|
109
109
|
const call = new ObservedCall({
|
|
110
110
|
...model,
|
|
111
111
|
serviceId: this.config.defaultServiceId,
|
|
112
|
-
started: Date.now(),
|
|
113
112
|
}, this, appData);
|
|
114
113
|
|
|
115
114
|
if (this._closed) throw new Error('Cannot create an observed call on a closed observer');
|
|
@@ -130,7 +129,7 @@ export class Observer extends EventEmitter {
|
|
|
130
129
|
call.serviceId,
|
|
131
130
|
call.roomId,
|
|
132
131
|
call.callId,
|
|
133
|
-
|
|
132
|
+
started,
|
|
134
133
|
));
|
|
135
134
|
|
|
136
135
|
this.emit('newcall', call);
|