@observertc/observer-js 0.40.3-beta → 0.40.5-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/CallSummary.d.ts +2 -9
- package/lib/CallSummary.d.ts.map +1 -1
- package/lib/ObservedCall.d.ts +2 -0
- package/lib/ObservedCall.d.ts.map +1 -1
- package/lib/ObservedCall.js +8 -0
- package/lib/ObservedClient.d.ts +20 -2
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +57 -18
- package/lib/ObservedDataChannel.d.ts +1 -0
- package/lib/ObservedDataChannel.d.ts.map +1 -1
- package/lib/ObservedDataChannel.js +1 -1
- package/lib/ObservedICE.d.ts +1 -0
- package/lib/ObservedICE.d.ts.map +1 -1
- package/lib/ObservedICE.js +1 -1
- package/lib/ObservedInboundTrack.d.ts +1 -0
- package/lib/ObservedInboundTrack.d.ts.map +1 -1
- package/lib/ObservedInboundTrack.js +1 -1
- package/lib/ObservedOutboundTrack.d.ts +1 -0
- package/lib/ObservedOutboundTrack.d.ts.map +1 -1
- package/lib/ObservedOutboundTrack.js +2 -1
- package/lib/ObservedPeerConnection.d.ts +6 -3
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/ObservedPeerConnection.js +51 -42
- package/lib/ObservedSfu.d.ts +12 -0
- package/lib/ObservedSfu.d.ts.map +1 -1
- package/lib/ObservedSfu.js +76 -0
- package/lib/ObservedSfuInboundRtpPad.d.ts +38 -0
- package/lib/ObservedSfuInboundRtpPad.d.ts.map +1 -0
- package/lib/ObservedSfuInboundRtpPad.js +67 -0
- package/lib/ObservedSfuOutboundRtpPad.d.ts +38 -0
- package/lib/ObservedSfuOutboundRtpPad.d.ts.map +1 -0
- package/lib/ObservedSfuOutboundRtpPad.js +68 -0
- package/lib/ObservedSfuSctpChannel.d.ts +38 -0
- package/lib/ObservedSfuSctpChannel.d.ts.map +1 -0
- package/lib/ObservedSfuSctpChannel.js +53 -0
- package/lib/ObservedSfuTransport.d.ts +54 -0
- package/lib/ObservedSfuTransport.d.ts.map +1 -0
- package/lib/ObservedSfuTransport.js +116 -0
- package/lib/Observer.d.ts +5 -0
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +21 -0
- package/package.json +1 -1
- package/src/CallSummary.ts +2 -10
- package/src/ObservedCall.ts +9 -0
- package/src/ObservedClient.ts +71 -21
- package/src/ObservedDataChannel.ts +2 -0
- package/src/ObservedICE.ts +3 -0
- package/src/ObservedInboundTrack.ts +2 -0
- package/src/ObservedOutboundTrack.ts +3 -0
- package/src/ObservedPeerConnection.ts +56 -45
- package/src/ObservedSfu.ts +118 -2
- package/src/ObservedSfuInboundRtpPad.ts +100 -0
- package/src/ObservedSfuOutboundRtpPad.ts +101 -0
- package/src/ObservedSfuSctpChannel.ts +97 -0
- package/src/ObservedSfuTransport.ts +179 -0
- package/src/Observer.ts +31 -1
|
@@ -49,9 +49,9 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
49
49
|
public totalReceivedAudioBytes = 0;
|
|
50
50
|
public totalReceivedVideoBytes = 0;
|
|
51
51
|
|
|
52
|
-
public
|
|
53
|
-
public
|
|
54
|
-
public
|
|
52
|
+
public deltaInboundPacketsLost = 0;
|
|
53
|
+
public deltaInboundPacketsReceived = 0;
|
|
54
|
+
public deltaOutboundPacketsSent = 0;
|
|
55
55
|
public deltaDataChannelBytesSent = 0;
|
|
56
56
|
public deltaDataChannelBytesReceived = 0;
|
|
57
57
|
public deltaInboundReceivedBytes = 0;
|
|
@@ -73,6 +73,7 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
73
73
|
private _closed = false;
|
|
74
74
|
private _updated = Date.now();
|
|
75
75
|
private _sample?: ObservedPeerConnectionStats;
|
|
76
|
+
private _marker?: string;
|
|
76
77
|
|
|
77
78
|
public readonly ICE = ObservedICE.create(this);
|
|
78
79
|
private readonly _inboundAudioTracks = new Map<string, ObservedInboundTrack<'audio'>>();
|
|
@@ -170,6 +171,20 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
170
171
|
return this._updated - this.created;
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
public get marker() {
|
|
175
|
+
return this._marker;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
public set marker(value: string | undefined) {
|
|
179
|
+
this._marker = value;
|
|
180
|
+
this._inboundAudioTracks.forEach((track) => (track.marker = value));
|
|
181
|
+
this._inboundVideoTracks.forEach((track) => (track.marker = value));
|
|
182
|
+
this._outboundAudioTracks.forEach((track) => (track.marker = value));
|
|
183
|
+
this._outboundVideoTracks.forEach((track) => (track.marker = value));
|
|
184
|
+
this._dataChannels.forEach((channel) => (channel.marker = value));
|
|
185
|
+
this.ICE.marker = value;
|
|
186
|
+
}
|
|
187
|
+
|
|
173
188
|
public get closed() {
|
|
174
189
|
return this._closed;
|
|
175
190
|
}
|
|
@@ -191,9 +206,9 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
191
206
|
}
|
|
192
207
|
|
|
193
208
|
public resetMetrics() {
|
|
194
|
-
this.
|
|
195
|
-
this.
|
|
196
|
-
this.
|
|
209
|
+
this.deltaInboundPacketsLost = 0;
|
|
210
|
+
this.deltaInboundPacketsReceived = 0;
|
|
211
|
+
this.deltaOutboundPacketsSent = 0;
|
|
197
212
|
|
|
198
213
|
this.deltaDataChannelBytesSent = 0;
|
|
199
214
|
this.deltaDataChannelBytesReceived = 0;
|
|
@@ -209,26 +224,26 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
209
224
|
}
|
|
210
225
|
|
|
211
226
|
public updateMetrics() {
|
|
212
|
-
this.totalInboundPacketsLost = 0;
|
|
213
|
-
this.totalInboundPacketsReceived = 0;
|
|
214
|
-
this.totalOutboundPacketsSent = 0;
|
|
215
|
-
this.totalDataChannelBytesSent = 0;
|
|
216
|
-
this.totalDataChannelBytesReceived = 0;
|
|
227
|
+
// this.totalInboundPacketsLost = 0;
|
|
228
|
+
// this.totalInboundPacketsReceived = 0;
|
|
229
|
+
// this.totalOutboundPacketsSent = 0;
|
|
230
|
+
// this.totalDataChannelBytesSent = 0;
|
|
231
|
+
// this.totalDataChannelBytesReceived = 0;
|
|
217
232
|
|
|
218
|
-
this.totalSentAudioBytes = 0;
|
|
219
|
-
this.totalSentVideoBytes = 0;
|
|
220
|
-
this.totalReceivedAudioBytes = 0;
|
|
221
|
-
this.totalReceivedVideoBytes = 0;
|
|
222
|
-
this.sendingAudioBitrate = 0;
|
|
223
|
-
this.sendingVideoBitrate = 0;
|
|
224
|
-
this.receivingAudioBitrate = 0;
|
|
225
|
-
this.receivingVideoBitrate = 0;
|
|
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;
|
|
226
241
|
|
|
227
242
|
let sumRttInMs = 0;
|
|
228
243
|
|
|
229
244
|
this._inboundAudioTracks.forEach((track) => {
|
|
230
|
-
this.
|
|
231
|
-
this.
|
|
245
|
+
this.deltaInboundPacketsLost += track.deltaLostPackets;
|
|
246
|
+
this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
|
|
232
247
|
this.deltaInboundReceivedBytes += track.deltaBytesReceived;
|
|
233
248
|
|
|
234
249
|
this.deltaReceivedAudioBytes += track.deltaBytesReceived;
|
|
@@ -236,17 +251,12 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
236
251
|
|
|
237
252
|
this.receivingAudioBitrate += track.bitrate;
|
|
238
253
|
|
|
239
|
-
this.totalInboundPacketsLost += track.totalLostPackets;
|
|
240
|
-
this.totalInboundPacketsReceived += track.totalReceivedPackets;
|
|
241
|
-
this.totalReceivedAudioBytes += track.totalBytesReceived;
|
|
242
|
-
this.totalReceivedAudioPacktes += track.totalReceivedPackets;
|
|
243
|
-
|
|
244
254
|
sumRttInMs = (track.rttInMs ?? 0);
|
|
245
255
|
});
|
|
246
256
|
|
|
247
257
|
this._inboundVideoTracks.forEach((track) => {
|
|
248
|
-
this.
|
|
249
|
-
this.
|
|
258
|
+
this.deltaInboundPacketsLost += track.deltaLostPackets;
|
|
259
|
+
this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
|
|
250
260
|
this.deltaInboundReceivedBytes += track.deltaBytesReceived;
|
|
251
261
|
|
|
252
262
|
this.deltaReceivedVideoBytes += track.deltaBytesReceived;
|
|
@@ -254,16 +264,11 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
254
264
|
|
|
255
265
|
this.receivingVideoBitrate += track.bitrate;
|
|
256
266
|
|
|
257
|
-
this.totalInboundPacketsLost += track.totalLostPackets;
|
|
258
|
-
this.totalInboundPacketsReceived += track.totalReceivedPackets;
|
|
259
|
-
this.totalReceivedVideoBytes += track.totalBytesReceived;
|
|
260
|
-
this.totalReceivedVideoPackets += track.totalReceivedPackets;
|
|
261
|
-
|
|
262
267
|
sumRttInMs = (track.rttInMs ?? 0);
|
|
263
268
|
});
|
|
264
269
|
|
|
265
270
|
this._outboundAudioTracks.forEach((track) => {
|
|
266
|
-
this.
|
|
271
|
+
this.deltaOutboundPacketsSent += track.deltaSentPackets;
|
|
267
272
|
this.deltaOutboundSentBytes += track.deltaSentBytes;
|
|
268
273
|
|
|
269
274
|
this.deltaSentAudioBytes += track.deltaSentBytes;
|
|
@@ -271,15 +276,11 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
271
276
|
|
|
272
277
|
this.sendingAudioBitrate += track.bitrate;
|
|
273
278
|
|
|
274
|
-
this.totalOutboundPacketsSent += track.totalSentPackets;
|
|
275
|
-
this.totalSentAudioBytes += track.totalSentBytes;
|
|
276
|
-
this.totalSentAudioPackets += track.totalSentPackets;
|
|
277
|
-
|
|
278
279
|
sumRttInMs = (track.rttInMs ?? 0);
|
|
279
280
|
});
|
|
280
281
|
|
|
281
282
|
this._outboundVideoTracks.forEach((track) => {
|
|
282
|
-
this.
|
|
283
|
+
this.deltaOutboundPacketsSent += track.deltaSentPackets;
|
|
283
284
|
this.deltaOutboundSentBytes += track.deltaSentBytes;
|
|
284
285
|
|
|
285
286
|
this.deltaSentVideoBytes += track.deltaSentBytes;
|
|
@@ -287,18 +288,12 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
287
288
|
|
|
288
289
|
this.sendingVideoBitrate += track.bitrate;
|
|
289
290
|
|
|
290
|
-
this.totalOutboundPacketsSent += track.totalSentPackets;
|
|
291
|
-
this.totalSentVideoBytes += track.totalSentBytes;
|
|
292
|
-
this.totalSentVideoPackets += track.totalSentPackets;
|
|
293
|
-
|
|
294
291
|
sumRttInMs = (track.rttInMs ?? 0);
|
|
295
292
|
});
|
|
296
293
|
|
|
297
294
|
this._dataChannels.forEach((channel) => {
|
|
298
295
|
this.deltaDataChannelBytesSent += channel.deltaBytesSent;
|
|
299
296
|
this.deltaDataChannelBytesReceived += channel.deltaBytesReceived;
|
|
300
|
-
this.totalDataChannelBytesSent += channel.totalBytesSent;
|
|
301
|
-
this.totalDataChannelBytesReceived += channel.totalBytesReceived;
|
|
302
297
|
});
|
|
303
298
|
|
|
304
299
|
const iceRttInMs = this.ICE.stats?.currentRoundTripTime;
|
|
@@ -308,7 +303,22 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
308
303
|
sumRttInMs += iceRttInMs;
|
|
309
304
|
nrOfBelongings += 1;
|
|
310
305
|
}
|
|
306
|
+
|
|
311
307
|
this.avgRttInMs = 0 < nrOfBelongings ? sumRttInMs / nrOfBelongings : undefined;
|
|
308
|
+
this.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
|
|
309
|
+
this.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
|
|
310
|
+
this.totalInboundPacketsLost += this.deltaInboundPacketsLost;
|
|
311
|
+
this.totalInboundPacketsReceived += this.deltaInboundPacketsReceived;
|
|
312
|
+
this.totalOutboundPacketsSent += this.deltaOutboundPacketsSent;
|
|
313
|
+
this.totalSentAudioBytes += this.deltaSentAudioBytes;
|
|
314
|
+
this.totalSentVideoBytes += this.deltaSentVideoBytes;
|
|
315
|
+
this.totalReceivedAudioBytes += this.deltaReceivedAudioBytes;
|
|
316
|
+
this.totalReceivedVideoBytes += this.deltaReceivedVideoBytes;
|
|
317
|
+
this.totalReceivedAudioPacktes += this.deltaReceivedAudioPackets;
|
|
318
|
+
this.totalReceivedVideoPackets += this.deltaReceivedVideoPackets;
|
|
319
|
+
this.totalSentAudioPackets += this.deltaSentAudioBytes;
|
|
320
|
+
this.totalSentVideoPackets += this.deltaSentVideoBytes;
|
|
321
|
+
|
|
312
322
|
}
|
|
313
323
|
|
|
314
324
|
public update(sample: PeerConnectionTransport, timestamp: number) {
|
|
@@ -330,6 +340,7 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
330
340
|
...sample,
|
|
331
341
|
timestamp,
|
|
332
342
|
sampleSeq: -1, // deprecated
|
|
343
|
+
marker: this.marker,
|
|
333
344
|
};
|
|
334
345
|
|
|
335
346
|
this.reports.addPeerConnectionTransportReports(report);
|
package/src/ObservedSfu.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
import { Observer } from './Observer';
|
|
3
3
|
import { SfuSample } from '@observertc/sample-schemas-js';
|
|
4
|
+
import { ObservedSfuTransport, ObservedSfuTransportModel } from './ObservedSfuTransport';
|
|
5
|
+
import { SfuEventReport, SfuExtensionReport } from '@observertc/report-schemas-js';
|
|
4
6
|
|
|
5
7
|
export type ObservedSfuModel= {
|
|
6
8
|
serviceId: string;
|
|
9
|
+
mediaUnitId: string;
|
|
7
10
|
sfuId: string;
|
|
8
11
|
joined?: number;
|
|
9
12
|
};
|
|
@@ -11,6 +14,7 @@ export type ObservedSfuModel= {
|
|
|
11
14
|
export type ObservedSfuEvents = {
|
|
12
15
|
update: [],
|
|
13
16
|
close: [],
|
|
17
|
+
newtransport: [ObservedSfuTransport],
|
|
14
18
|
};
|
|
15
19
|
|
|
16
20
|
export declare interface ObservedSfu<AppData extends Record<string, unknown> = Record<string, unknown>> {
|
|
@@ -28,7 +32,12 @@ export class ObservedSfu<AppData extends Record<string, unknown> = Record<string
|
|
|
28
32
|
|
|
29
33
|
private _updated = Date.now();
|
|
30
34
|
private _closed = false;
|
|
31
|
-
|
|
35
|
+
private _marker?: string;
|
|
36
|
+
private _timeZoneOffsetInHours?: number;
|
|
37
|
+
private _left?: number;
|
|
38
|
+
|
|
39
|
+
private readonly _transports = new Map<string, ObservedSfuTransport>();
|
|
40
|
+
|
|
32
41
|
public constructor(
|
|
33
42
|
private readonly _model: ObservedSfuModel,
|
|
34
43
|
public readonly observer: Observer,
|
|
@@ -38,11 +47,23 @@ export class ObservedSfu<AppData extends Record<string, unknown> = Record<string
|
|
|
38
47
|
this.setMaxListeners(Infinity);
|
|
39
48
|
}
|
|
40
49
|
|
|
50
|
+
public get marker() {
|
|
51
|
+
return this._marker;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public get reports() {
|
|
55
|
+
return this.observer.reports;
|
|
56
|
+
}
|
|
57
|
+
|
|
41
58
|
public get serviceId() {
|
|
42
59
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
43
60
|
return this._model.serviceId!;
|
|
44
61
|
}
|
|
45
62
|
|
|
63
|
+
public get mediaUnitId() {
|
|
64
|
+
return this._model.mediaUnitId;
|
|
65
|
+
}
|
|
66
|
+
|
|
46
67
|
public get sfuId() {
|
|
47
68
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
48
69
|
return this._model.sfuId!;
|
|
@@ -53,6 +74,10 @@ export class ObservedSfu<AppData extends Record<string, unknown> = Record<string
|
|
|
53
74
|
return Number(this._model.joined!);
|
|
54
75
|
}
|
|
55
76
|
|
|
77
|
+
public get transports(): ReadonlyMap<string, ObservedSfuTransport> {
|
|
78
|
+
return this._transports;
|
|
79
|
+
}
|
|
80
|
+
|
|
56
81
|
public get updated() {
|
|
57
82
|
return this._updated;
|
|
58
83
|
}
|
|
@@ -64,6 +89,9 @@ export class ObservedSfu<AppData extends Record<string, unknown> = Record<string
|
|
|
64
89
|
public close() {
|
|
65
90
|
if (this._closed) return;
|
|
66
91
|
this._closed = true;
|
|
92
|
+
|
|
93
|
+
[ ...this._transports.values() ].forEach((transport) => transport.close());
|
|
94
|
+
|
|
67
95
|
this.emit('close');
|
|
68
96
|
}
|
|
69
97
|
|
|
@@ -71,7 +99,95 @@ export class ObservedSfu<AppData extends Record<string, unknown> = Record<string
|
|
|
71
99
|
if (this._closed) throw new Error(`Sfu ${this.sfuId} is closed`);
|
|
72
100
|
if (sample.sfuId !== this.sfuId) throw new Error(`Sfu ${this.sfuId} is not the same as sample.sfuId`);
|
|
73
101
|
|
|
102
|
+
if (!this._timeZoneOffsetInHours && sample.timeZoneOffsetInHours) {
|
|
103
|
+
this._timeZoneOffsetInHours = sample.timeZoneOffsetInHours;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
for (const customSfuEvents of sample.customSfuEvents ?? []) {
|
|
107
|
+
const report: SfuEventReport = {
|
|
108
|
+
serviceId: this.serviceId,
|
|
109
|
+
mediaUnitId: this.mediaUnitId,
|
|
110
|
+
sfuId: this.sfuId,
|
|
111
|
+
...customSfuEvents,
|
|
112
|
+
timestamp: sample.timestamp,
|
|
113
|
+
marker: this._marker,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
this.reports.addSfuEventReport(report);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for (const extensionStats of sample.extensionStats ?? []) {
|
|
120
|
+
|
|
121
|
+
const report: SfuExtensionReport = {
|
|
122
|
+
serviceId: this.serviceId,
|
|
123
|
+
mediaUnitId: this.mediaUnitId,
|
|
124
|
+
sfuId: this.sfuId,
|
|
125
|
+
extensionType: extensionStats.type,
|
|
126
|
+
payload: extensionStats.payload,
|
|
127
|
+
timestamp: sample.timestamp,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
this.reports.addSfuExtensionReport(report);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
for (const transport of sample.transports ?? []) {
|
|
134
|
+
const observedSfuTransport = this._transports.get(transport.transportId) ?? this._createTransport({
|
|
135
|
+
sfuTransportId: transport.transportId,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
observedSfuTransport.update(transport, sample.timestamp);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
for (const inboundRtpPad of sample.inboundRtpPads ?? []) {
|
|
142
|
+
const transport = this._transports.get(inboundRtpPad.transportId) ?? this._createTransport({
|
|
143
|
+
sfuTransportId: inboundRtpPad.transportId,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const observedSfuInboundRtpPad = transport.inboundRtpPads.get(inboundRtpPad.padId) ?? transport.createSfuInboundRtpPad({
|
|
147
|
+
sfuInboundRtpPadId: inboundRtpPad.padId,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
observedSfuInboundRtpPad.update(inboundRtpPad, sample.timestamp);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
for (const outboundRtpPad of sample.outboundRtpPads ?? []) {
|
|
154
|
+
const transport = this._transports.get(outboundRtpPad.transportId) ?? this._createTransport({
|
|
155
|
+
sfuTransportId: outboundRtpPad.transportId,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const observedSfuOutboundRtpPad = transport.outboundRtpPads.get(outboundRtpPad.padId) ?? transport.createSfuOutboundRtpPad({
|
|
159
|
+
sfuOutboundRtpPadId: outboundRtpPad.padId,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
observedSfuOutboundRtpPad.update(outboundRtpPad, sample.timestamp);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
for (const sctpChannel of sample.sctpChannels ?? []) {
|
|
166
|
+
const transport = this._transports.get(sctpChannel.transportId) ?? this._createTransport({
|
|
167
|
+
sfuTransportId: sctpChannel.transportId,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const observedSfuSctpChannel = transport.sctpChannels.get(sctpChannel.channelId) ?? transport.createSfuSctpChannel({
|
|
171
|
+
sfuSctpChannelId: sctpChannel.channelId,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
observedSfuSctpChannel.update(sctpChannel, sample.timestamp);
|
|
175
|
+
}
|
|
176
|
+
|
|
74
177
|
this._updated = Date.now();
|
|
75
178
|
this.emit('update');
|
|
76
179
|
}
|
|
77
|
-
|
|
180
|
+
|
|
181
|
+
private _createTransport(model: ObservedSfuTransportModel) {
|
|
182
|
+
const result = new ObservedSfuTransport(model, this);
|
|
183
|
+
|
|
184
|
+
result.once('close', () => {
|
|
185
|
+
this._transports.delete(model.sfuTransportId);
|
|
186
|
+
});
|
|
187
|
+
this._transports.set(model.sfuTransportId, result);
|
|
188
|
+
|
|
189
|
+
this.emit('newtransport', result);
|
|
190
|
+
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { SfuInboundRtpPad } from '@observertc/sample-schemas-js';
|
|
3
|
+
import { ObservedSfuTransport } from './ObservedSfuTransport';
|
|
4
|
+
import { SfuInboundRtpPadReport } from '@observertc/report-schemas-js';
|
|
5
|
+
|
|
6
|
+
export type ObservedSfuInboundRtpPadModel= {
|
|
7
|
+
sfuInboundRtpPadId: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ObservedSfuInboundRtpPadEvents = {
|
|
11
|
+
update: [],
|
|
12
|
+
close: [],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export declare interface ObservedSfuInboundRtpPad {
|
|
16
|
+
on<U extends keyof ObservedSfuInboundRtpPadEvents>(event: U, listener: (...args: ObservedSfuInboundRtpPadEvents[U]) => void): this;
|
|
17
|
+
off<U extends keyof ObservedSfuInboundRtpPadEvents>(event: U, listener: (...args: ObservedSfuInboundRtpPadEvents[U]) => void): this;
|
|
18
|
+
once<U extends keyof ObservedSfuInboundRtpPadEvents>(event: U, listener: (...args: ObservedSfuInboundRtpPadEvents[U]) => void): this;
|
|
19
|
+
emit<U extends keyof ObservedSfuInboundRtpPadEvents>(event: U, ...args: ObservedSfuInboundRtpPadEvents[U]): boolean;
|
|
20
|
+
|
|
21
|
+
update(sample: SfuInboundRtpPad, timestamp: number): void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class ObservedSfuInboundRtpPad extends EventEmitter {
|
|
25
|
+
public readonly created = Date.now();
|
|
26
|
+
|
|
27
|
+
public stats?: SfuInboundRtpPad;
|
|
28
|
+
public marker?: string;
|
|
29
|
+
private _updated = Date.now();
|
|
30
|
+
private _closed = false;
|
|
31
|
+
|
|
32
|
+
public constructor(
|
|
33
|
+
private readonly _model: ObservedSfuInboundRtpPadModel,
|
|
34
|
+
public readonly transport: ObservedSfuTransport,
|
|
35
|
+
) {
|
|
36
|
+
super();
|
|
37
|
+
this.setMaxListeners(Infinity);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public get reports() {
|
|
41
|
+
return this.transport.reports;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public get serviceId() {
|
|
45
|
+
return this.transport.serviceId;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public get mediaUnitId() {
|
|
49
|
+
return this.transport.mediaUnitId;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public get sfuId() {
|
|
53
|
+
return this.transport.sfuId;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public get sfuTransportId() {
|
|
57
|
+
return this.transport.sfuTransportId;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public get sfuRtpPadId() {
|
|
61
|
+
return this._model.sfuInboundRtpPadId;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public get updated() {
|
|
65
|
+
return this._updated;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public get closed() {
|
|
69
|
+
return this._closed;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public close() {
|
|
73
|
+
if (this._closed) return;
|
|
74
|
+
this._closed = true;
|
|
75
|
+
this.emit('close');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public update(sample: SfuInboundRtpPad, timestamp: number) {
|
|
79
|
+
|
|
80
|
+
const { streamId: sfuStreamId, padId: rtpPadId, ...reportData } = sample;
|
|
81
|
+
|
|
82
|
+
const report: SfuInboundRtpPadReport = {
|
|
83
|
+
serviceId: this.serviceId,
|
|
84
|
+
mediaUnitId: this.mediaUnitId,
|
|
85
|
+
sfuId: this.sfuId,
|
|
86
|
+
callId: undefined, // TODO: where to get this from?
|
|
87
|
+
sfuStreamId,
|
|
88
|
+
rtpPadId,
|
|
89
|
+
...reportData,
|
|
90
|
+
timestamp,
|
|
91
|
+
marker: this.marker,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
this.reports.addSfuInboundRtpPadReport(report);
|
|
95
|
+
this.stats = sample;
|
|
96
|
+
|
|
97
|
+
this._updated = Date.now();
|
|
98
|
+
this.emit('update');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { SfuOutboundRtpPad } from '@observertc/sample-schemas-js';
|
|
3
|
+
import { SfuOutboundRtpPadReport } from '@observertc/report-schemas-js';
|
|
4
|
+
import { ObservedSfuTransport } from './ObservedSfuTransport';
|
|
5
|
+
|
|
6
|
+
export type ObservedSfuOutboundRtpPadModel= {
|
|
7
|
+
sfuOutboundRtpPadId: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ObservedSfuOutboundRtpPadEvents = {
|
|
11
|
+
update: [],
|
|
12
|
+
close: [],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export declare interface ObservedSfuOutboundRtpPad {
|
|
16
|
+
on<U extends keyof ObservedSfuOutboundRtpPadEvents>(event: U, listener: (...args: ObservedSfuOutboundRtpPadEvents[U]) => void): this;
|
|
17
|
+
off<U extends keyof ObservedSfuOutboundRtpPadEvents>(event: U, listener: (...args: ObservedSfuOutboundRtpPadEvents[U]) => void): this;
|
|
18
|
+
once<U extends keyof ObservedSfuOutboundRtpPadEvents>(event: U, listener: (...args: ObservedSfuOutboundRtpPadEvents[U]) => void): this;
|
|
19
|
+
emit<U extends keyof ObservedSfuOutboundRtpPadEvents>(event: U, ...args: ObservedSfuOutboundRtpPadEvents[U]): boolean;
|
|
20
|
+
|
|
21
|
+
update(sample: SfuOutboundRtpPad, timestamp: number): void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class ObservedSfuOutboundRtpPad extends EventEmitter {
|
|
25
|
+
public readonly created = Date.now();
|
|
26
|
+
|
|
27
|
+
public stats?: SfuOutboundRtpPad;
|
|
28
|
+
public marker?: string;
|
|
29
|
+
private _updated = Date.now();
|
|
30
|
+
private _closed = false;
|
|
31
|
+
|
|
32
|
+
public constructor(
|
|
33
|
+
private readonly _model: ObservedSfuOutboundRtpPadModel,
|
|
34
|
+
public readonly transport: ObservedSfuTransport,
|
|
35
|
+
) {
|
|
36
|
+
super();
|
|
37
|
+
this.setMaxListeners(Infinity);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public get reports() {
|
|
41
|
+
return this.transport.reports;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public get serviceId() {
|
|
45
|
+
return this.transport.serviceId;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public get mediaUnitId() {
|
|
49
|
+
return this.transport.mediaUnitId;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public get sfuId() {
|
|
53
|
+
return this.transport.sfuId;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public get sfuTransportId() {
|
|
57
|
+
return this.transport.sfuTransportId;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public get sfuRtpPadId() {
|
|
61
|
+
return this._model.sfuOutboundRtpPadId;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public get updated() {
|
|
65
|
+
return this._updated;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public get closed() {
|
|
69
|
+
return this._closed;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public close() {
|
|
73
|
+
if (this._closed) return;
|
|
74
|
+
this._closed = true;
|
|
75
|
+
this.emit('close');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public update(sample: SfuOutboundRtpPad, timestamp: number) {
|
|
79
|
+
|
|
80
|
+
const { streamId: sfuStreamId, padId: rtpPadId, sinkId: sfuSinkId, ...reportData } = sample;
|
|
81
|
+
|
|
82
|
+
const report: SfuOutboundRtpPadReport = {
|
|
83
|
+
serviceId: this.serviceId,
|
|
84
|
+
mediaUnitId: this.mediaUnitId,
|
|
85
|
+
sfuId: this.sfuId,
|
|
86
|
+
callId: undefined, // TODO: where to get this from?
|
|
87
|
+
sfuStreamId,
|
|
88
|
+
sfuSinkId,
|
|
89
|
+
rtpPadId,
|
|
90
|
+
...reportData,
|
|
91
|
+
timestamp,
|
|
92
|
+
marker: this.marker,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
this.reports.addSfuOutboundRtpPadReport(report);
|
|
96
|
+
this.stats = sample;
|
|
97
|
+
|
|
98
|
+
this._updated = Date.now();
|
|
99
|
+
this.emit('update');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { SfuSctpChannel } from '@observertc/sample-schemas-js';
|
|
3
|
+
import { ObservedSfuTransport } from './ObservedSfuTransport';
|
|
4
|
+
import { SfuSctpStreamReport } from '@observertc/report-schemas-js';
|
|
5
|
+
|
|
6
|
+
export type ObservedSfuSctpChannelModel= {
|
|
7
|
+
sfuSctpChannelId: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ObservedSfuSctpChannelEvents = {
|
|
11
|
+
update: [],
|
|
12
|
+
close: [],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export declare interface ObservedSfuSctpChannel {
|
|
16
|
+
on<U extends keyof ObservedSfuSctpChannelEvents>(event: U, listener: (...args: ObservedSfuSctpChannelEvents[U]) => void): this;
|
|
17
|
+
off<U extends keyof ObservedSfuSctpChannelEvents>(event: U, listener: (...args: ObservedSfuSctpChannelEvents[U]) => void): this;
|
|
18
|
+
once<U extends keyof ObservedSfuSctpChannelEvents>(event: U, listener: (...args: ObservedSfuSctpChannelEvents[U]) => void): this;
|
|
19
|
+
emit<U extends keyof ObservedSfuSctpChannelEvents>(event: U, ...args: ObservedSfuSctpChannelEvents[U]): boolean;
|
|
20
|
+
|
|
21
|
+
update(sample: SfuSctpChannel, timestamp: number): void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class ObservedSfuSctpChannel extends EventEmitter {
|
|
25
|
+
public readonly created = Date.now();
|
|
26
|
+
|
|
27
|
+
public stats?: SfuSctpChannel;
|
|
28
|
+
public marker?: string;
|
|
29
|
+
private _updated = Date.now();
|
|
30
|
+
private _closed = false;
|
|
31
|
+
|
|
32
|
+
public constructor(
|
|
33
|
+
private readonly _model: ObservedSfuSctpChannelModel,
|
|
34
|
+
public readonly transport: ObservedSfuTransport,
|
|
35
|
+
) {
|
|
36
|
+
super();
|
|
37
|
+
this.setMaxListeners(Infinity);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public get serviceId() {
|
|
41
|
+
return this.transport.serviceId;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public get sfuId() {
|
|
45
|
+
return this.transport.sfuId;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public get mediaUnitId() {
|
|
49
|
+
return this.transport.mediaUnitId;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public get sfuTransportId() {
|
|
53
|
+
return this.transport.sfuTransportId;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public get sfuSctpChannelId() {
|
|
57
|
+
return this._model.sfuSctpChannelId;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public get reports() {
|
|
61
|
+
return this.transport.reports;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public get updated() {
|
|
65
|
+
return this._updated;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public get closed() {
|
|
69
|
+
return this._closed;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public close() {
|
|
73
|
+
if (this._closed) return;
|
|
74
|
+
this._closed = true;
|
|
75
|
+
this.emit('close');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public update(sample: SfuSctpChannel, timestamp: number) {
|
|
79
|
+
|
|
80
|
+
const report: SfuSctpStreamReport = {
|
|
81
|
+
serviceId: this.serviceId,
|
|
82
|
+
mediaUnitId: this.mediaUnitId,
|
|
83
|
+
sfuId: this.sfuId,
|
|
84
|
+
callId: undefined, // TODO: where to get this from?
|
|
85
|
+
roomId: undefined, // TODO: where to get this from?
|
|
86
|
+
...sample,
|
|
87
|
+
timestamp,
|
|
88
|
+
marker: this.marker,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
this.reports.addSfuTransportReport(report);
|
|
92
|
+
this.stats = sample;
|
|
93
|
+
|
|
94
|
+
this._updated = Date.now();
|
|
95
|
+
this.emit('update');
|
|
96
|
+
}
|
|
97
|
+
}
|