@observertc/observer-js 0.9.1-beta → 0.9.2-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/Evaluator.d.ts.map +1 -1
- package/lib/Evaluator.js +13 -2
- package/lib/Observer.d.ts +3 -1
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +19 -1
- package/lib/common/logger.d.ts +2 -2
- package/lib/common/logger.d.ts.map +1 -1
- package/lib/common/logger.js +49 -35
- package/lib/common/types.d.ts +22 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/middlewares/CommitTransactionMiddleware.d.ts.map +1 -1
- package/lib/middlewares/CommitTransactionMiddleware.js +25 -0
- package/lib/middlewares/TransactionContext.d.ts +4 -2
- package/lib/middlewares/TransactionContext.d.ts.map +1 -1
- package/lib/middlewares/TransactionContext.js +2 -1
- package/lib/middlewares/TransactoinProcessor.d.ts.map +1 -1
- package/lib/middlewares/TransactoinProcessor.js +3 -2
- package/lib/middlewares/VisitObservedCallsMiddleware.d.ts +1 -1
- package/lib/middlewares/VisitObservedCallsMiddleware.d.ts.map +1 -1
- package/lib/middlewares/VisitObservedCallsMiddleware.js +2 -2
- package/lib/middlewares/VisitObservedSfusMiddleware.d.ts +6 -0
- package/lib/middlewares/VisitObservedSfusMiddleware.d.ts.map +1 -0
- package/lib/middlewares/VisitObservedSfusMiddleware.js +142 -0
- package/lib/middlewares/visitors/visitClient.d.ts.map +1 -1
- package/lib/middlewares/visitors/visitClient.js +13 -0
- package/lib/middlewares/visitors/{visitOutboundVideoTarcks.d.ts → visitOutboundVideoTarck.d.ts} +1 -1
- package/lib/middlewares/visitors/visitOutboundVideoTarck.d.ts.map +1 -0
- package/lib/middlewares/visitors/visitSfu.d.ts +5 -0
- package/lib/middlewares/visitors/visitSfu.d.ts.map +1 -0
- package/lib/middlewares/visitors/visitSfu.js +79 -0
- package/lib/middlewares/visitors/visitSfuInboundRtpPad.d.ts +5 -0
- package/lib/middlewares/visitors/visitSfuInboundRtpPad.d.ts.map +1 -0
- package/lib/middlewares/visitors/visitSfuInboundRtpPad.js +60 -0
- package/lib/middlewares/visitors/visitSfuOutboundRtpPad.d.ts +5 -0
- package/lib/middlewares/visitors/visitSfuOutboundRtpPad.d.ts.map +1 -0
- package/lib/middlewares/visitors/visitSfuOutboundRtpPad.js +61 -0
- package/lib/middlewares/visitors/visitSfuSctpChannel.d.ts +5 -0
- package/lib/middlewares/visitors/visitSfuSctpChannel.d.ts.map +1 -0
- package/lib/middlewares/visitors/visitSfuSctpChannel.js +58 -0
- package/lib/middlewares/visitors/visitSfuTransport.d.ts +5 -0
- package/lib/middlewares/visitors/visitSfuTransport.d.ts.map +1 -0
- package/lib/middlewares/visitors/visitSfuTransport.js +59 -0
- package/lib/samples/ObservedSfu.d.ts +27 -0
- package/lib/samples/ObservedSfu.d.ts.map +1 -0
- package/lib/samples/ObservedSfu.js +72 -0
- package/lib/samples/ObservedSfuInboundRtpPad.d.ts +15 -0
- package/lib/samples/ObservedSfuInboundRtpPad.d.ts.map +1 -0
- package/lib/samples/ObservedSfuInboundRtpPad.js +21 -0
- package/lib/samples/ObservedSfuOutboundRtpPad.d.ts +15 -0
- package/lib/samples/ObservedSfuOutboundRtpPad.d.ts.map +1 -0
- package/lib/samples/ObservedSfuOutboundRtpPad.js +21 -0
- package/lib/samples/ObservedSfuSctpChannel.d.ts +15 -0
- package/lib/samples/ObservedSfuSctpChannel.d.ts.map +1 -0
- package/lib/samples/ObservedSfuSctpChannel.js +21 -0
- package/lib/samples/ObservedSfuTransport.d.ts +30 -0
- package/lib/samples/ObservedSfuTransport.d.ts.map +1 -0
- package/lib/samples/ObservedSfuTransport.js +93 -0
- package/lib/samples/ObservedSfus.d.ts +16 -0
- package/lib/samples/ObservedSfus.d.ts.map +1 -0
- package/lib/samples/ObservedSfus.js +66 -0
- package/lib/sinks/ObserverSink.d.ts +3 -3
- package/lib/sinks/ObserverSink.d.ts.map +1 -1
- package/lib/sources/ObservedSfuSource.d.ts +14 -0
- package/lib/sources/ObservedSfuSource.d.ts.map +1 -0
- package/lib/sources/ObservedSfuSource.js +2 -0
- package/lib/sources/Sources.d.ts +8 -0
- package/lib/sources/Sources.d.ts.map +1 -1
- package/lib/sources/Sources.js +47 -1
- package/lib/storages/StorageProvider.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Evaluator.ts +14 -2
- package/src/Observer.ts +22 -1
- package/src/common/logger.ts +145 -127
- package/src/common/types.ts +27 -0
- package/src/middlewares/CommitTransactionMiddleware.ts +46 -6
- package/src/middlewares/TransactionContext.ts +7 -3
- package/src/middlewares/TransactoinProcessor.ts +3 -1
- package/src/middlewares/VisitObservedCallsMiddleware.ts +1 -1
- package/src/middlewares/VisitObservedSfusMiddleware.ts +202 -0
- package/src/middlewares/visitors/visitClient.ts +15 -0
- package/src/middlewares/visitors/visitSfu.ts +64 -0
- package/src/middlewares/visitors/visitSfuInboundRtpPad.ts +50 -0
- package/src/middlewares/visitors/visitSfuOutboundRtpPad.ts +51 -0
- package/src/middlewares/visitors/visitSfuSctpChannel.ts +48 -0
- package/src/middlewares/visitors/visitSfuTransport.ts +48 -0
- package/src/samples/ObservedSfu.ts +108 -0
- package/src/samples/ObservedSfuInboundRtpPad.ts +34 -0
- package/src/samples/ObservedSfuOutboundRtpPad.ts +34 -0
- package/src/samples/ObservedSfuSctpChannel.ts +35 -0
- package/src/samples/ObservedSfuTransport.ts +130 -0
- package/src/samples/ObservedSfus.ts +85 -0
- package/src/sinks/ObserverSink.ts +5 -3
- package/src/sources/ObservedSfuSource.ts +23 -0
- package/src/sources/Sources.ts +54 -3
- package/src/storages/StorageProvider.ts +1 -4
- package/lib/middlewares/visitors/visitOutboundVideoTarcks.d.ts.map +0 -1
- package/lib/storages/StorageFactory.d.ts +0 -27
- package/lib/storages/StorageFactory.d.ts.map +0 -1
- package/lib/storages/StorageFactory.js +0 -37
- package/src/storages/StorageFactory.ts +0 -58
- /package/lib/middlewares/visitors/{visitOutboundVideoTarcks.js → visitOutboundVideoTarck.js} +0 -0
- /package/src/middlewares/visitors/{visitOutboundVideoTarcks.ts → visitOutboundVideoTarck.ts} +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { Middleware } from './Middleware';
|
|
2
|
+
import { TransactionContext } from './TransactionContext';
|
|
3
|
+
import { ReportsCollector } from '../common/ReportsCollector';
|
|
4
|
+
import { createLogger } from '../common/logger';
|
|
5
|
+
import { visitSfu } from './visitors/visitSfu';
|
|
6
|
+
import { visitSfuTransport } from './visitors/visitSfuTransport';
|
|
7
|
+
import { visitSfuInboundRtpPad } from './visitors/visitSfuInboundRtpPad';
|
|
8
|
+
import { visitSfuOutboundRtpPad } from './visitors/visitSfuOutboundRtpPad';
|
|
9
|
+
import { visitSfuSctpChannel } from './visitors/visitSfuSctpChannel';
|
|
10
|
+
|
|
11
|
+
export const logger = createLogger('VisitObservedCallsMiddleware');
|
|
12
|
+
|
|
13
|
+
export function createVisitObservedSfusMiddleware(
|
|
14
|
+
reports: ReportsCollector,
|
|
15
|
+
fetchSamples: boolean
|
|
16
|
+
): Middleware<TransactionContext> {
|
|
17
|
+
const process = async (transaction: TransactionContext) => {
|
|
18
|
+
const {
|
|
19
|
+
observedSfus,
|
|
20
|
+
updatedSfus,
|
|
21
|
+
deletedSfus,
|
|
22
|
+
|
|
23
|
+
updatedSfuTransports,
|
|
24
|
+
deletedSfuTransports,
|
|
25
|
+
|
|
26
|
+
updatedSfuInboundRtpPads,
|
|
27
|
+
deletedSfuInboundRtpPads,
|
|
28
|
+
|
|
29
|
+
updatedSfuOutboundRtpPads,
|
|
30
|
+
deletedSfuOutboundRtpPads,
|
|
31
|
+
|
|
32
|
+
updatedSfuSctpChannels,
|
|
33
|
+
deletedSfuSctpChannels
|
|
34
|
+
|
|
35
|
+
} = transaction;
|
|
36
|
+
|
|
37
|
+
const visitedSfuIds = new Set<string>();
|
|
38
|
+
const visitedSfuTransportIds = new Set<string>();
|
|
39
|
+
const visitedSfuInboundRtpPadIds = new Set<string>();
|
|
40
|
+
const visitedSfuOutboundRtpPadIds = new Set<string>();
|
|
41
|
+
const visitedSfuSctpChannels = new Set<string>();
|
|
42
|
+
|
|
43
|
+
for (const observedSfu of observedSfus.observedSfus()) {
|
|
44
|
+
const { sfuId } = observedSfu;
|
|
45
|
+
|
|
46
|
+
visitSfu(observedSfu, updatedSfus, reports, fetchSamples);
|
|
47
|
+
|
|
48
|
+
visitedSfuIds.add(sfuId);
|
|
49
|
+
const storedSfu = updatedSfus.get(sfuId);
|
|
50
|
+
|
|
51
|
+
if (!storedSfu) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (const observedSfuTransport of observedSfu.observedSfuTransports()) {
|
|
56
|
+
const { transportId } = observedSfuTransport;
|
|
57
|
+
|
|
58
|
+
visitSfuTransport(observedSfuTransport, storedSfu, updatedSfuTransports, reports, fetchSamples);
|
|
59
|
+
|
|
60
|
+
visitedSfuTransportIds.add(transportId);
|
|
61
|
+
const storedSfuTransport = updatedSfuTransports.get(transportId);
|
|
62
|
+
|
|
63
|
+
if (!storedSfuTransport) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
for (const sfuInboundRtpPad of observedSfuTransport.inboundRtpPads()) {
|
|
68
|
+
visitSfuInboundRtpPad(sfuInboundRtpPad, storedSfuTransport, updatedSfuInboundRtpPads, reports, fetchSamples);
|
|
69
|
+
|
|
70
|
+
visitedSfuInboundRtpPadIds.add(sfuInboundRtpPad.padId);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for (const sfuOutboundRtpPad of observedSfuTransport.outboundRtpPads()) {
|
|
74
|
+
visitSfuOutboundRtpPad(sfuOutboundRtpPad, storedSfuTransport, updatedSfuOutboundRtpPads, reports, fetchSamples);
|
|
75
|
+
|
|
76
|
+
visitedSfuInboundRtpPadIds.add(sfuOutboundRtpPad.padId);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const sfuSctpChannel of observedSfuTransport.sfuSctpChannels()) {
|
|
80
|
+
visitSfuSctpChannel(sfuSctpChannel, storedSfuTransport, updatedSfuSctpChannels, reports, fetchSamples);
|
|
81
|
+
|
|
82
|
+
visitedSfuSctpChannels.add(sfuSctpChannel.channelId);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
for (const [sfuId, sfu] of Array.from(updatedSfus.entries())) {
|
|
88
|
+
|
|
89
|
+
if (visitedSfuIds.has(sfuId)) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
deletedSfus.add(sfuId);
|
|
93
|
+
|
|
94
|
+
if (sfu.serviceId && sfu.mediaUnitId) {
|
|
95
|
+
reports.addSfuEventReport({
|
|
96
|
+
serviceId: sfu.serviceId,
|
|
97
|
+
mediaUnitId: sfu.mediaUnitId,
|
|
98
|
+
name: "SFU_LEFT",
|
|
99
|
+
sfuId,
|
|
100
|
+
timestamp: Date.now(),
|
|
101
|
+
marker: sfu.marker,
|
|
102
|
+
message: 'SFU is detached',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const [sfuTransportId, sfuTransport] of Array.from(updatedSfuTransports.entries())) {
|
|
108
|
+
if (visitedSfuTransportIds.has(sfuTransportId)) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
// delete PeerConnection
|
|
112
|
+
const { serviceId, sfuId, transportId } = sfuTransport;
|
|
113
|
+
|
|
114
|
+
if (!serviceId || !sfuId || !transportId) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const storedSfu = updatedSfus.get(sfuId);
|
|
119
|
+
|
|
120
|
+
updatedSfuTransports.delete(transportId);
|
|
121
|
+
deletedSfuTransports.add(transportId);
|
|
122
|
+
|
|
123
|
+
// also update the peer connection model
|
|
124
|
+
if (storedSfu) {
|
|
125
|
+
storedSfu.sfuTransportIds = storedSfu.sfuTransportIds.filter((tId) => tId !== transportId);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
for (const [padId, sfuInboundRtpPad] of Array.from(updatedSfuInboundRtpPads.entries())) {
|
|
130
|
+
if (visitedSfuInboundRtpPadIds.has(padId)) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// delete Sfu Inbound Rtp Pad
|
|
134
|
+
const { serviceId, rtpPadId, sfuTransportId } = sfuInboundRtpPad;
|
|
135
|
+
|
|
136
|
+
if (!serviceId || !sfuTransportId || !rtpPadId) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
|
|
141
|
+
|
|
142
|
+
updatedSfuInboundRtpPads.delete(rtpPadId);
|
|
143
|
+
deletedSfuInboundRtpPads.add(rtpPadId);
|
|
144
|
+
|
|
145
|
+
// also update the sfu transport model
|
|
146
|
+
if (storedSfuTransport) {
|
|
147
|
+
storedSfuTransport.inboundRtpPadIds = storedSfuTransport.inboundRtpPadIds.filter((tId) => tId !== rtpPadId);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
for (const [padId, sfuOutboundRtpPad] of Array.from(updatedSfuOutboundRtpPads.entries())) {
|
|
152
|
+
if (visitedSfuOutboundRtpPadIds.has(padId)) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// delete Sfu Outbound Rtp Pad
|
|
157
|
+
const { serviceId, rtpPadId, sfuTransportId } = sfuOutboundRtpPad;
|
|
158
|
+
|
|
159
|
+
if (!serviceId || !sfuTransportId || !rtpPadId) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
|
|
164
|
+
|
|
165
|
+
updatedSfuOutboundRtpPads.delete(rtpPadId);
|
|
166
|
+
deletedSfuOutboundRtpPads.add(rtpPadId);
|
|
167
|
+
|
|
168
|
+
// also update the sfu transport model
|
|
169
|
+
if (storedSfuTransport) {
|
|
170
|
+
storedSfuTransport.outboundRtpPadIds = storedSfuTransport.outboundRtpPadIds.filter((tId) => tId !== rtpPadId);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
for (const [channelId, sfuSctpChannel] of Array.from(updatedSfuSctpChannels.entries())) {
|
|
175
|
+
if (visitedSfuSctpChannels.has(channelId)) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// delete Sfu Outbound Rtp Pad
|
|
180
|
+
const { serviceId, sfuSctpChannelId, sfuTransportId } = sfuSctpChannel;
|
|
181
|
+
|
|
182
|
+
if (!serviceId || !sfuTransportId || !sfuSctpChannelId) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
|
|
187
|
+
|
|
188
|
+
updatedSfuSctpChannels.delete(sfuSctpChannelId);
|
|
189
|
+
deletedSfuSctpChannels.add(sfuSctpChannelId);
|
|
190
|
+
|
|
191
|
+
// also update the sfu transport model
|
|
192
|
+
if (storedSfuTransport) {
|
|
193
|
+
storedSfuTransport.sctpChannelIds = storedSfuTransport.sctpChannelIds.filter((tId) => tId !== sfuSctpChannelId);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
const result = async (context: TransactionContext, next?: Middleware<TransactionContext>) => {
|
|
198
|
+
await process(context);
|
|
199
|
+
if (next) await next(context);
|
|
200
|
+
};
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
@@ -85,6 +85,7 @@ export function visitClient(
|
|
|
85
85
|
reports.addCallMetaReport(callMetaReport);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
+
|
|
88
89
|
|
|
89
90
|
if (clientSample.localSDPs && 0 < clientSample.localSDPs.length) {
|
|
90
91
|
for (const localSDP of clientSample.localSDPs) {
|
|
@@ -111,6 +112,20 @@ export function visitClient(
|
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
if (clientSample.customCallEvents && 0 < clientSample.customCallEvents.length) {
|
|
116
|
+
for (const callEvent of clientSample.customCallEvents) {
|
|
117
|
+
reports.addCallEventReport({
|
|
118
|
+
serviceId,
|
|
119
|
+
mediaUnitId,
|
|
120
|
+
roomId,
|
|
121
|
+
callId,
|
|
122
|
+
clientId,
|
|
123
|
+
timestamp: Date.now(),
|
|
124
|
+
...callEvent,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
114
129
|
if (clientSample.userMediaErrors && 0 < clientSample.userMediaErrors.length) {
|
|
115
130
|
for (const userMediaError of clientSample.userMediaErrors) {
|
|
116
131
|
const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as Models from '../../models/Models';
|
|
2
|
+
import { ReportsCollector } from '../../common/ReportsCollector';
|
|
3
|
+
import { ObservedSfu } from '../../samples/ObservedSfu';
|
|
4
|
+
|
|
5
|
+
export function visitSfu(
|
|
6
|
+
observedSfu: ObservedSfu,
|
|
7
|
+
storedSfus: Map<string, Models.Sfu>,
|
|
8
|
+
reports: ReportsCollector,
|
|
9
|
+
fetchSamples: boolean
|
|
10
|
+
) {
|
|
11
|
+
const { mediaUnitId, serviceId, sfuId, timeZoneId, marker } = observedSfu;
|
|
12
|
+
let storedSfu = storedSfus.get(sfuId);
|
|
13
|
+
if (!storedSfu) {
|
|
14
|
+
const timestamp = Date.now();
|
|
15
|
+
storedSfu = new Models.Sfu({
|
|
16
|
+
serviceId,
|
|
17
|
+
sfuId,
|
|
18
|
+
joined: BigInt(timestamp),
|
|
19
|
+
mediaUnitId,
|
|
20
|
+
timeZoneId,
|
|
21
|
+
marker,
|
|
22
|
+
sfuTransportIds: [],
|
|
23
|
+
});
|
|
24
|
+
storedSfus.set(sfuId, storedSfu);
|
|
25
|
+
|
|
26
|
+
reports.addSfuEventReport({
|
|
27
|
+
serviceId,
|
|
28
|
+
mediaUnitId,
|
|
29
|
+
name: "SFU_JOINED",
|
|
30
|
+
sfuId,
|
|
31
|
+
timestamp,
|
|
32
|
+
marker,
|
|
33
|
+
message: 'SFU is joined',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const sfuSample of observedSfu.samples()) {
|
|
38
|
+
|
|
39
|
+
if (sfuSample.customSfuEvents) {
|
|
40
|
+
for (const sfuEvent of sfuSample.customSfuEvents) {
|
|
41
|
+
reports.addSfuEventReport({
|
|
42
|
+
serviceId,
|
|
43
|
+
mediaUnitId,
|
|
44
|
+
sfuId,
|
|
45
|
+
timestamp: Date.now(),
|
|
46
|
+
...sfuEvent,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (sfuSample.extensionStats) {
|
|
52
|
+
for (const extensionStats of sfuSample.extensionStats) {
|
|
53
|
+
reports.addSfuExtensionReport({
|
|
54
|
+
serviceId,
|
|
55
|
+
mediaUnitId,
|
|
56
|
+
sfuId,
|
|
57
|
+
timestamp: Date.now(),
|
|
58
|
+
payload: extensionStats.payload,
|
|
59
|
+
extensionType: extensionStats.type,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as Models from '../../models/Models';
|
|
2
|
+
import { ReportsCollector } from '../../common/ReportsCollector';
|
|
3
|
+
import { SfuInboundRtpPadReport } from '@observertc/report-schemas-js';
|
|
4
|
+
import { ObservedSfuInboundRtpPad } from '../../samples/ObservedSfuInboundRtpPad';
|
|
5
|
+
|
|
6
|
+
export function visitSfuInboundRtpPad(
|
|
7
|
+
observedSfuInboundRtpPad: ObservedSfuInboundRtpPad,
|
|
8
|
+
storedSfuTransport: Models.SfuTransport,
|
|
9
|
+
storedSfuInboundRtpPads: Map<string, Models.SfuInboundRtpPad>,
|
|
10
|
+
reports: ReportsCollector,
|
|
11
|
+
fetchSamples: boolean
|
|
12
|
+
) {
|
|
13
|
+
const { padId: rtpPadId } = observedSfuInboundRtpPad;
|
|
14
|
+
|
|
15
|
+
const { transportId: sfuTransportId } = observedSfuInboundRtpPad.sfuTransport;
|
|
16
|
+
|
|
17
|
+
const { serviceId, sfuId, mediaUnitId, marker, minTimestamp: timestamp } = observedSfuInboundRtpPad.sfuTransport.sfu;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
let storedSfuInboundRtpPad = storedSfuInboundRtpPads.get(rtpPadId);
|
|
21
|
+
if (!storedSfuInboundRtpPad) {
|
|
22
|
+
storedSfuInboundRtpPad = new Models.SfuInboundRtpPad({
|
|
23
|
+
serviceId,
|
|
24
|
+
sfuId,
|
|
25
|
+
mediaUnitId,
|
|
26
|
+
sfuTransportId,
|
|
27
|
+
added: BigInt(Date.now()),
|
|
28
|
+
marker,
|
|
29
|
+
});
|
|
30
|
+
storedSfuInboundRtpPads.set(rtpPadId, storedSfuInboundRtpPad);
|
|
31
|
+
|
|
32
|
+
storedSfuTransport.inboundRtpPadIds.push(rtpPadId);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const sfuInboundRtpPad of observedSfuInboundRtpPad.samples()) {
|
|
36
|
+
const report: SfuInboundRtpPadReport = {
|
|
37
|
+
serviceId,
|
|
38
|
+
sfuId,
|
|
39
|
+
mediaUnitId,
|
|
40
|
+
rtpPadId,
|
|
41
|
+
...sfuInboundRtpPad,
|
|
42
|
+
sfuStreamId: sfuInboundRtpPad.streamId,
|
|
43
|
+
timestamp,
|
|
44
|
+
};
|
|
45
|
+
reports.addSfuTransportReport(report);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (fetchSamples) {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as Models from '../../models/Models';
|
|
2
|
+
import { ReportsCollector } from '../../common/ReportsCollector';
|
|
3
|
+
import { SfuOutboundRtpPadReport } from '@observertc/report-schemas-js';
|
|
4
|
+
import { ObservedSfuTransport } from '../../samples/ObservedSfuTransport';
|
|
5
|
+
import { ObservedSfuOutboundRtpPad } from '../../samples/ObservedSfuOutboundRtpPad';
|
|
6
|
+
|
|
7
|
+
export function visitSfuOutboundRtpPad(
|
|
8
|
+
observedSfuOutboundRtpPad: ObservedSfuOutboundRtpPad,
|
|
9
|
+
storedSfuTransport: Models.SfuTransport,
|
|
10
|
+
storedSfuOutboundRtpPads: Map<string, Models.SfuOutboundRtpPad>,
|
|
11
|
+
reports: ReportsCollector,
|
|
12
|
+
fetchSamples: boolean
|
|
13
|
+
) {
|
|
14
|
+
const { padId: rtpPadId } = observedSfuOutboundRtpPad;
|
|
15
|
+
|
|
16
|
+
const { transportId: sfuTransportId } = observedSfuOutboundRtpPad.sfuTransport;
|
|
17
|
+
|
|
18
|
+
const { serviceId, sfuId, mediaUnitId, marker, minTimestamp: timestamp } = observedSfuOutboundRtpPad.sfuTransport.sfu;
|
|
19
|
+
|
|
20
|
+
let storedSfuOutboundRtpPad = storedSfuOutboundRtpPads.get(rtpPadId);
|
|
21
|
+
if (!storedSfuOutboundRtpPad) {
|
|
22
|
+
storedSfuOutboundRtpPad = new Models.SfuOutboundRtpPad({
|
|
23
|
+
serviceId,
|
|
24
|
+
sfuId,
|
|
25
|
+
mediaUnitId,
|
|
26
|
+
sfuTransportId,
|
|
27
|
+
added: BigInt(Date.now()),
|
|
28
|
+
marker,
|
|
29
|
+
});
|
|
30
|
+
storedSfuOutboundRtpPads.set(rtpPadId, storedSfuOutboundRtpPad);
|
|
31
|
+
|
|
32
|
+
storedSfuTransport.outboundRtpPadIds.push(rtpPadId);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const sfuOutboundRtpPad of observedSfuOutboundRtpPad.samples()) {
|
|
36
|
+
const report: SfuOutboundRtpPadReport = {
|
|
37
|
+
serviceId,
|
|
38
|
+
sfuId,
|
|
39
|
+
mediaUnitId,
|
|
40
|
+
rtpPadId,
|
|
41
|
+
...sfuOutboundRtpPad,
|
|
42
|
+
sfuStreamId: sfuOutboundRtpPad.streamId,
|
|
43
|
+
sfuSinkId: sfuOutboundRtpPad.sinkId,
|
|
44
|
+
timestamp,
|
|
45
|
+
};
|
|
46
|
+
reports.addSfuTransportReport(report);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (fetchSamples) {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as Models from '../../models/Models';
|
|
2
|
+
import { ReportsCollector } from '../../common/ReportsCollector';
|
|
3
|
+
import { SfuSctpStreamReport } from '@observertc/report-schemas-js';
|
|
4
|
+
import { ObservedSfuSctpChannel } from '../../samples/ObservedSfuSctpChannel';
|
|
5
|
+
|
|
6
|
+
export function visitSfuSctpChannel(
|
|
7
|
+
observedSfuSctpChannel: ObservedSfuSctpChannel,
|
|
8
|
+
storedSfuTransport: Models.SfuTransport,
|
|
9
|
+
storedSfuSctpChannels: Map<string, Models.SfuSctpChannel>,
|
|
10
|
+
reports: ReportsCollector,
|
|
11
|
+
fetchSamples: boolean
|
|
12
|
+
) {
|
|
13
|
+
const { channelId } = observedSfuSctpChannel;
|
|
14
|
+
|
|
15
|
+
const { transportId: sfuTransportId } = observedSfuSctpChannel.sfuTransport;
|
|
16
|
+
|
|
17
|
+
const { serviceId, sfuId, mediaUnitId, marker, minTimestamp: timestamp } = observedSfuSctpChannel.sfuTransport.sfu;
|
|
18
|
+
|
|
19
|
+
let storedSfuSctpChannel = storedSfuSctpChannels.get(channelId);
|
|
20
|
+
if (!storedSfuSctpChannel) {
|
|
21
|
+
storedSfuSctpChannel = new Models.SfuSctpChannel({
|
|
22
|
+
serviceId,
|
|
23
|
+
sfuId,
|
|
24
|
+
mediaUnitId,
|
|
25
|
+
sfuTransportId,
|
|
26
|
+
opened: BigInt(Date.now()),
|
|
27
|
+
marker,
|
|
28
|
+
});
|
|
29
|
+
storedSfuSctpChannels.set(channelId, storedSfuSctpChannel);
|
|
30
|
+
|
|
31
|
+
storedSfuTransport.sctpChannelIds.push(channelId);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (const sfuSctpChannel of observedSfuSctpChannel.samples()) {
|
|
35
|
+
const report: SfuSctpStreamReport = {
|
|
36
|
+
serviceId,
|
|
37
|
+
sfuId,
|
|
38
|
+
mediaUnitId,
|
|
39
|
+
...sfuSctpChannel,
|
|
40
|
+
timestamp,
|
|
41
|
+
};
|
|
42
|
+
reports.addSfuTransportReport(report);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (fetchSamples) {
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as Models from '../../models/Models';
|
|
2
|
+
import { ReportsCollector } from '../../common/ReportsCollector';
|
|
3
|
+
import { SFUTransportReport } from '@observertc/report-schemas-js';
|
|
4
|
+
import { ObservedSfuTransport } from '../../samples/ObservedSfuTransport';
|
|
5
|
+
|
|
6
|
+
export function visitSfuTransport(
|
|
7
|
+
observedSfuTransport: ObservedSfuTransport,
|
|
8
|
+
storedSfu: Models.Sfu,
|
|
9
|
+
storedSfuTransports: Map<string, Models.SfuTransport>,
|
|
10
|
+
reports: ReportsCollector,
|
|
11
|
+
fetchSamples: boolean
|
|
12
|
+
) {
|
|
13
|
+
const { transportId } = observedSfuTransport;
|
|
14
|
+
|
|
15
|
+
const { serviceId, sfuId, mediaUnitId, marker, minTimestamp: timestamp } = observedSfuTransport.sfu;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
let storedSfuTransport = storedSfuTransports.get(transportId);
|
|
19
|
+
if (!storedSfuTransport) {
|
|
20
|
+
storedSfuTransport = new Models.SfuTransport({
|
|
21
|
+
serviceId,
|
|
22
|
+
sfuId,
|
|
23
|
+
mediaUnitId,
|
|
24
|
+
transportId,
|
|
25
|
+
opened: BigInt(Date.now()),
|
|
26
|
+
marker,
|
|
27
|
+
inboundRtpPadIds: [],
|
|
28
|
+
outboundRtpPadIds: [],
|
|
29
|
+
});
|
|
30
|
+
storedSfuTransports.set(transportId, storedSfuTransport);
|
|
31
|
+
|
|
32
|
+
storedSfu.sfuTransportIds.push(transportId);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const sfuTransport of observedSfuTransport.transportSamples()) {
|
|
36
|
+
const report: SFUTransportReport = {
|
|
37
|
+
serviceId,
|
|
38
|
+
sfuId,
|
|
39
|
+
mediaUnitId,
|
|
40
|
+
...sfuTransport,
|
|
41
|
+
timestamp,
|
|
42
|
+
};
|
|
43
|
+
reports.addSfuTransportReport(report);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (fetchSamples) {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { ClientSample, SfuSample } from '@observertc/sample-schemas-js';
|
|
2
|
+
import { ObservedPeerConnection, ObservedPeerConnectionBuilder } from './ObservedPeerConnection';
|
|
3
|
+
import { ObservedCall } from './ObservedCall';
|
|
4
|
+
import { ObservedSfuTransport, ObservedSfuTransportBuilder } from './ObservedSfuTransport';
|
|
5
|
+
|
|
6
|
+
export interface ObservedSfu {
|
|
7
|
+
readonly serviceId: string;
|
|
8
|
+
readonly sfuId: string;
|
|
9
|
+
readonly mediaUnitId: string;
|
|
10
|
+
|
|
11
|
+
observedSfuTransports(): IterableIterator<ObservedSfuTransport>;
|
|
12
|
+
getObservedSfuTransport(sfuId: string): ObservedSfuTransport | undefined;
|
|
13
|
+
samples(): IterableIterator<SfuSample>;
|
|
14
|
+
|
|
15
|
+
readonly marker?: string;
|
|
16
|
+
readonly timeZoneId?: string;
|
|
17
|
+
|
|
18
|
+
minTimestamp: number;
|
|
19
|
+
maxTimestamp: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class ObservedSfuBuilder {
|
|
23
|
+
private _minTimestamp?: number;
|
|
24
|
+
private _maxTimestamp?: number;
|
|
25
|
+
private _sfuTransports = new Map<string, ObservedSfuTransportBuilder>();
|
|
26
|
+
private _sfuSamples: SfuSample[] = [];
|
|
27
|
+
public constructor(
|
|
28
|
+
private _config: Omit<
|
|
29
|
+
ObservedSfu,
|
|
30
|
+
| keyof IterableIterator<ObservedPeerConnection>
|
|
31
|
+
| 'samples'
|
|
32
|
+
| 'observedSfuTransports'
|
|
33
|
+
| 'getObservedSfuTransport'
|
|
34
|
+
| 'minTimestamp'
|
|
35
|
+
| 'maxTimestamp'
|
|
36
|
+
>
|
|
37
|
+
) {}
|
|
38
|
+
|
|
39
|
+
public addSfuSample(sfuSample: SfuSample) {
|
|
40
|
+
this._sfuSamples.push(sfuSample);
|
|
41
|
+
|
|
42
|
+
if (sfuSample.transports) {
|
|
43
|
+
for (const sfuTransport of sfuSample.transports) {
|
|
44
|
+
const builder = this._getOrCreateSfuTransportBuilder(sfuTransport.transportId);
|
|
45
|
+
builder.addTransportSample(sfuTransport);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (sfuSample.inboundRtpPads) {
|
|
50
|
+
for (const inboundRtpPad of sfuSample.inboundRtpPads) {
|
|
51
|
+
const builder = this._getOrCreateSfuTransportBuilder(inboundRtpPad.transportId);
|
|
52
|
+
builder.addSfuInboundRtpPad(inboundRtpPad);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (sfuSample.outboundRtpPads) {
|
|
57
|
+
for (const outboundRtpPad of sfuSample.outboundRtpPads) {
|
|
58
|
+
const builder = this._getOrCreateSfuTransportBuilder(outboundRtpPad.transportId);
|
|
59
|
+
builder.addSfuOutboundRtpPad(outboundRtpPad);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (sfuSample.sctpChannels) {
|
|
64
|
+
for (const sctpChannel of sfuSample.sctpChannels) {
|
|
65
|
+
const builder = this._getOrCreateSfuTransportBuilder(sctpChannel.transportId);
|
|
66
|
+
builder.addSfuSctpChannel(sctpChannel);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (this._minTimestamp === undefined || sfuSample.timestamp < this._minTimestamp) {
|
|
71
|
+
this._minTimestamp = sfuSample.timestamp;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (this._maxTimestamp === undefined || this._maxTimestamp < sfuSample.timestamp) {
|
|
75
|
+
this._maxTimestamp = sfuSample.timestamp;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private _getOrCreateSfuTransportBuilder(transportId: string): ObservedSfuTransportBuilder {
|
|
80
|
+
let result = this._sfuTransports.get(transportId);
|
|
81
|
+
if (!result) {
|
|
82
|
+
result = new ObservedSfuTransportBuilder({
|
|
83
|
+
transportId,
|
|
84
|
+
});
|
|
85
|
+
this._sfuTransports.set(transportId, result);
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public build(): ObservedSfu {
|
|
91
|
+
const observedSfuTransports = new Map<string, ObservedSfuTransport>();
|
|
92
|
+
|
|
93
|
+
const result: ObservedSfu = {
|
|
94
|
+
...this._config,
|
|
95
|
+
minTimestamp: this._minTimestamp ?? Date.now(),
|
|
96
|
+
maxTimestamp: this._maxTimestamp ?? Date.now(),
|
|
97
|
+
samples: () => this._sfuSamples.values(),
|
|
98
|
+
observedSfuTransports: () => observedSfuTransports.values(),
|
|
99
|
+
getObservedSfuTransport: (transportId: string) => observedSfuTransports.get(transportId),
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
for (const builder of this._sfuTransports.values()) {
|
|
103
|
+
const observedSfuTransport = builder.build(result);
|
|
104
|
+
observedSfuTransports.set(observedSfuTransport.transportId, observedSfuTransport);
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SfuInboundRtpPad } from '@observertc/sample-schemas-js';
|
|
2
|
+
import { ObservedSfuTransport } from './ObservedSfuTransport';
|
|
3
|
+
|
|
4
|
+
export interface ObservedSfuInboundRtpPad {
|
|
5
|
+
readonly sfuTransport: ObservedSfuTransport;
|
|
6
|
+
readonly padId: string;
|
|
7
|
+
|
|
8
|
+
samples(): IterableIterator<SfuInboundRtpPad>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class ObservedSfuInboundRtpPadBuilder {
|
|
12
|
+
private _samples: SfuInboundRtpPad[] = [];
|
|
13
|
+
public constructor(
|
|
14
|
+
private _config: Omit<
|
|
15
|
+
ObservedSfuInboundRtpPad,
|
|
16
|
+
| keyof IterableIterator<SfuInboundRtpPad>
|
|
17
|
+
| 'sfuTransport'
|
|
18
|
+
| 'samples'
|
|
19
|
+
>
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
public addSample(sfuInboundRtpPad: SfuInboundRtpPad) {
|
|
23
|
+
this._samples.push(sfuInboundRtpPad);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public build(sfuTransport: ObservedSfuTransport): ObservedSfuInboundRtpPad {
|
|
27
|
+
const result: ObservedSfuInboundRtpPad = {
|
|
28
|
+
sfuTransport,
|
|
29
|
+
...this._config,
|
|
30
|
+
samples: () => this._samples.values(),
|
|
31
|
+
};
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SfuOutboundRtpPad } from '@observertc/sample-schemas-js';
|
|
2
|
+
import { ObservedSfuTransport } from './ObservedSfuTransport';
|
|
3
|
+
|
|
4
|
+
export interface ObservedSfuOutboundRtpPad {
|
|
5
|
+
readonly sfuTransport: ObservedSfuTransport;
|
|
6
|
+
readonly padId: string;
|
|
7
|
+
|
|
8
|
+
samples(): IterableIterator<SfuOutboundRtpPad>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class ObservedSfuOutboundRtpPadBuilder {
|
|
12
|
+
private _samples: SfuOutboundRtpPad[] = [];
|
|
13
|
+
public constructor(
|
|
14
|
+
private _config: Omit<
|
|
15
|
+
ObservedSfuOutboundRtpPad,
|
|
16
|
+
| keyof IterableIterator<SfuOutboundRtpPad>
|
|
17
|
+
| 'sfuTransport'
|
|
18
|
+
| 'samples'
|
|
19
|
+
>
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
public addSample(sfuInboundRtpPad: SfuOutboundRtpPad) {
|
|
23
|
+
this._samples.push(sfuInboundRtpPad);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public build(sfuTransport: ObservedSfuTransport): ObservedSfuOutboundRtpPad {
|
|
27
|
+
const result: ObservedSfuOutboundRtpPad = {
|
|
28
|
+
sfuTransport,
|
|
29
|
+
...this._config,
|
|
30
|
+
samples: () => this._samples.values(),
|
|
31
|
+
};
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
}
|