@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.
@@ -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 started(): number;
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;IACf,OAAO,EAAE,MAAM,CAAC;CAChB,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"}
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"}
@@ -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 started() {
48
- return Number(this._model.started);
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
- lostPackets?: number;
25
- receivedPackets?: number;
26
- receivedFrames?: number;
27
- decodedFrames?: number;
28
- droppedFrames?: number;
29
- receivedSamples?: number;
30
- silentConcealedSamples?: number;
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
- resetMetrics(): void;
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":"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"}
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
- resetMetrics() {
99
- this.bitrate = 0;
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
- const bitrate = (((_f = sample.bytesReceived) !== null && _f !== void 0 ? _f : 0) - ((_g = lastStat === null || lastStat === void 0 ? void 0 : lastStat.bytesReceived) !== null && _g !== void 0 ? _g : 0)) * 8 / (elapsedTimeInMs / 1000);
130
- const lostPackets = ((_h = sample.packetsLost) !== null && _h !== void 0 ? _h : 0) - ((_j = lastStat === null || lastStat === void 0 ? void 0 : lastStat.packetsLost) !== null && _j !== void 0 ? _j : 0);
131
- const receivedPackets = ((_k = sample.packetsReceived) !== null && _k !== void 0 ? _k : 0) - ((_l = lastStat === null || lastStat === void 0 ? void 0 : lastStat.packetsReceived) !== null && _l !== void 0 ? _l : 0);
132
- const fractionLost = 0 < receivedPackets && 0 < lostPackets ? (lostPackets / (receivedPackets + lostPackets)) : 0;
133
- let decodedFrames;
134
- let droppedFrames;
135
- let receivedFrames;
136
- let silentConcealedSamples;
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
- decodedFrames = ((_m = videoSample.framesDecoded) !== null && _m !== void 0 ? _m : 0) - ((_o = lastVideoStat === null || lastVideoStat === void 0 ? void 0 : lastVideoStat.framesDecoded) !== null && _o !== void 0 ? _o : 0);
141
- droppedFrames = ((_p = videoSample.framesDropped) !== null && _p !== void 0 ? _p : 0) - ((_q = lastVideoStat === null || lastVideoStat === void 0 ? void 0 : lastVideoStat.framesDropped) !== null && _q !== void 0 ? _q : 0);
142
- receivedFrames = ((_r = videoSample.framesReceived) !== null && _r !== void 0 ? _r : 0) - ((_s = lastVideoStat === null || lastVideoStat === void 0 ? void 0 : lastVideoStat.framesReceived) !== null && _s !== void 0 ? _s : 0);
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
- silentConcealedSamples = ((_t = audioSample.silentConcealedSamples) !== null && _t !== void 0 ? _t : 0) - ((_u = lastAudioStat === null || lastAudioStat === void 0 ? void 0 : lastAudioStat.silentConcealedSamples) !== null && _u !== void 0 ? _u : 0);
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, lostPackets,
152
- receivedPackets,
153
- receivedFrames,
154
- decodedFrames,
155
- droppedFrames,
156
- silentConcealedSamples });
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":"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"}
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
- resetMetrics() {
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
- const bitrate = (((_a = sample.bytesSent) !== null && _a !== void 0 ? _a : 0) - ((_b = lastStat === null || lastStat === void 0 ? void 0 : lastStat.bytesSent) !== null && _b !== void 0 ? _b : 0)) * 8 / (elapsedTimeInMs / 1000);
98
- const deltaLostPackets = ((_c = sample.packetsLost) !== null && _c !== void 0 ? _c : 0) - ((_d = lastStat === null || lastStat === void 0 ? void 0 : lastStat.packetsLost) !== null && _d !== void 0 ? _d : 0);
99
- const deltaSentPackets = ((_e = sample.packetsSent) !== null && _e !== void 0 ? _e : 0) - ((_f = lastStat === null || lastStat === void 0 ? void 0 : lastStat.packetsSent) !== null && _f !== void 0 ? _f : 0);
100
- const deltaSentBytes = ((_g = sample.bytesSent) !== null && _g !== void 0 ? _g : 0) - ((_h = lastStat === null || lastStat === void 0 ? void 0 : lastStat.bytesSent) !== null && _h !== void 0 ? _h : 0);
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
- deltaEncodedFrames = ((_j = videoSample.framesEncoded) !== null && _j !== void 0 ? _j : 0) - ((_k = lastVideoStats === null || lastVideoStats === void 0 ? void 0 : lastVideoStats.framesEncoded) !== null && _k !== void 0 ? _k : 0);
107
- deltaSentFrames = ((_l = videoSample.framesSent) !== null && _l !== void 0 ? _l : 0) - ((_m = lastVideoStats === null || lastVideoStats === void 0 ? void 0 : lastVideoStats.framesSent) !== null && _m !== void 0 ? _m : 0);
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) => { var _a; return acc + ((_a = stat.rttInMs) !== null && _a !== void 0 ? _a : 0); }, 0) / (this._stats.size || 1);
118
- this.totalLostPackets = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.packetsLost) !== null && _a !== void 0 ? _a : 0); }, 0);
119
- this.totalSentPackets = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.packetsSent) !== null && _a !== void 0 ? _a : 0); }, 0);
120
- this.totalSentBytes = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.bytesSent) !== null && _a !== void 0 ? _a : 0); }, 0);
121
- this.totalSentFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.deltaSentPackets) !== null && _a !== void 0 ? _a : 0); }, 0);
122
- this.deltaEncodedFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.deltaEncodedFrames) !== null && _a !== void 0 ? _a : 0); }, 0);
123
- this.deltaSentFrames = [...this._stats.values()].reduce((acc, stat) => { var _a; return acc + ((_a = stat.deltaSentFrames) !== null && _a !== void 0 ? _a : 0); }, 0);
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._inboundAudioTracks.forEach((track) => track.resetMetrics());
159
- this._inboundVideoTracks.forEach((track) => track.resetMetrics());
160
- this._outboundAudioTracks.forEach((track) => track.resetMetrics());
161
- this._outboundVideoTracks.forEach((track) => track.resetMetrics());
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' | 'started'> & {
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>;
@@ -1 +1 @@
1
- {"version":3,"file":"Observer.d.ts","sourceRoot":"","sources":["../src/Observer.ts"],"names":[],"mappings":"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"}
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, started: Date.now() }), this, appData);
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, call.started));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@observertc/observer-js",
3
- "version": "0.40.5-beta",
3
+ "version": "0.40.7-beta",
4
4
  "description": "Server Side NodeJS Library for processing ObserveRTC Samples",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -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 started() {
67
- return Number(this._model.started);
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
- lostPackets?: number;
29
- receivedPackets?: number;
30
- receivedFrames?: number;
31
- decodedFrames?: number;
32
- droppedFrames?: number;
33
- receivedSamples?: number;
34
- silentConcealedSamples?: number;
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 resetMetrics() {
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
- const bitrate = ((sample.bytesReceived ?? 0) - (lastStat?.bytesReceived ?? 0)) * 8 / (elapsedTimeInMs / 1000);
219
- const lostPackets = (sample.packetsLost ?? 0) - (lastStat?.packetsLost ?? 0);
220
- const receivedPackets = (sample.packetsReceived ?? 0) - (lastStat?.packetsReceived ?? 0);
221
- const fractionLost = 0 < receivedPackets && 0 < lostPackets ? (lostPackets / (receivedPackets + lostPackets)) : 0;
222
- let decodedFrames: number | undefined;
223
- let droppedFrames: number | undefined;
224
- let receivedFrames: number | undefined;
225
- let silentConcealedSamples: number | undefined;
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
- decodedFrames = (videoSample.framesDecoded ?? 0) - (lastVideoStat?.framesDecoded ?? 0);
232
- droppedFrames = (videoSample.framesDropped ?? 0) - (lastVideoStat?.framesDropped ?? 0);
233
- receivedFrames = (videoSample.framesReceived ?? 0) - (lastVideoStat?.framesReceived ?? 0);
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
- silentConcealedSamples = (audioSample.silentConcealedSamples ?? 0) - (lastAudioStat?.silentConcealedSamples ?? 0);
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
- lostPackets,
248
- receivedPackets,
249
- receivedFrames,
250
- decodedFrames,
251
- droppedFrames,
252
- silentConcealedSamples,
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 resetMetrics() {
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
- const bitrate = ((sample.bytesSent ?? 0) - (lastStat?.bytesSent ?? 0)) * 8 / (elapsedTimeInMs / 1000);
176
- const deltaLostPackets = (sample.packetsLost ?? 0) - (lastStat?.packetsLost ?? 0);
177
- const deltaSentPackets = (sample.packetsSent ?? 0) - (lastStat?.packetsSent ?? 0);
178
- const deltaSentBytes = (sample.bytesSent ?? 0) - (lastStat?.bytesSent ?? 0);
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
- deltaEncodedFrames = (videoSample.framesEncoded ?? 0) - (lastVideoStats?.framesEncoded ?? 0);
187
- deltaSentFrames = (videoSample.framesSent ?? 0) - (lastVideoStats?.framesSent ?? 0);
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._inboundAudioTracks.forEach((track) => track.resetMetrics());
221
- this._inboundVideoTracks.forEach((track) => track.resetMetrics());
222
- this._outboundAudioTracks.forEach((track) => track.resetMetrics());
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' | 'started'> & { appData: T }
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
- call.started,
132
+ started,
134
133
  ));
135
134
 
136
135
  this.emit('newcall', call);