@observertc/observer-js 0.9.10-beta → 0.9.12-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.
Files changed (94) hide show
  1. package/lib/Evaluator.d.ts +2 -0
  2. package/lib/Evaluator.d.ts.map +1 -1
  3. package/lib/Evaluator.js +2 -4
  4. package/lib/Observer.d.ts.map +1 -1
  5. package/lib/Observer.js +1 -0
  6. package/lib/common/callMetaReports.d.ts +1 -1
  7. package/lib/common/callMetaReports.d.ts.map +1 -1
  8. package/lib/common/callMetaReports.js +2 -1
  9. package/lib/common/utils.d.ts +1 -0
  10. package/lib/common/utils.d.ts.map +1 -1
  11. package/lib/common/utils.js +12 -0
  12. package/lib/middlewares/DeleteOutdatedCallEntries.d.ts +6 -0
  13. package/lib/middlewares/DeleteOutdatedCallEntries.d.ts.map +1 -0
  14. package/lib/middlewares/DeleteOutdatedCallEntries.js +112 -0
  15. package/lib/middlewares/DeleteOutdatedSfuEntries.d.ts +6 -0
  16. package/lib/middlewares/DeleteOutdatedSfuEntries.d.ts.map +1 -0
  17. package/lib/middlewares/DeleteOutdatedSfuEntries.js +118 -0
  18. package/lib/middlewares/TransactionContext.d.ts.map +1 -1
  19. package/lib/middlewares/TransactionContext.js +42 -26
  20. package/lib/middlewares/TransactoinProcessor.d.ts +1 -1
  21. package/lib/middlewares/TransactoinProcessor.d.ts.map +1 -1
  22. package/lib/middlewares/TransactoinProcessor.js +4 -2
  23. package/lib/middlewares/VisitObservedCallsMiddleware.d.ts +2 -1
  24. package/lib/middlewares/VisitObservedCallsMiddleware.d.ts.map +1 -1
  25. package/lib/middlewares/VisitObservedCallsMiddleware.js +20 -90
  26. package/lib/middlewares/visitors/visitClient.d.ts.map +1 -1
  27. package/lib/middlewares/visitors/visitClient.js +26 -17
  28. package/lib/middlewares/visitors/visitInboundAudioTrack.d.ts +1 -1
  29. package/lib/middlewares/visitors/visitInboundAudioTrack.d.ts.map +1 -1
  30. package/lib/middlewares/visitors/visitInboundAudioTrack.js +10 -2
  31. package/lib/middlewares/visitors/visitInboundVideoTrack.d.ts +1 -1
  32. package/lib/middlewares/visitors/visitInboundVideoTrack.d.ts.map +1 -1
  33. package/lib/middlewares/visitors/visitInboundVideoTrack.js +10 -2
  34. package/lib/middlewares/visitors/visitOutboundAudioTrack.d.ts.map +1 -1
  35. package/lib/middlewares/visitors/visitOutboundAudioTrack.js +5 -1
  36. package/lib/middlewares/visitors/visitOutboundVideoTarck.d.ts.map +1 -1
  37. package/lib/middlewares/visitors/visitOutboundVideoTarck.js +5 -1
  38. package/lib/middlewares/visitors/visitPeerConnection.d.ts.map +1 -1
  39. package/lib/middlewares/visitors/visitPeerConnection.js +15 -0
  40. package/lib/models/Models.d.ts +26 -22
  41. package/lib/models/Models.d.ts.map +1 -1
  42. package/lib/models/Models.js +16 -11
  43. package/lib/processes/findRemoteMatches.d.ts +9 -0
  44. package/lib/processes/findRemoteMatches.d.ts.map +1 -0
  45. package/lib/processes/findRemoteMatches.js +83 -0
  46. package/lib/processes/joinClientProcess.d.ts.map +1 -1
  47. package/lib/processes/joinClientProcess.js +1 -2
  48. package/lib/samples/ObservedCalls.d.ts.map +1 -1
  49. package/lib/samples/ObservedCalls.js +16 -7
  50. package/lib/samples/ObservedInboundAudioTrack.d.ts +2 -0
  51. package/lib/samples/ObservedInboundAudioTrack.d.ts.map +1 -1
  52. package/lib/samples/ObservedInboundVideoTrack.d.ts +2 -0
  53. package/lib/samples/ObservedInboundVideoTrack.d.ts.map +1 -1
  54. package/lib/samples/ObservedOutboundAudioTrack.d.ts +1 -0
  55. package/lib/samples/ObservedOutboundAudioTrack.d.ts.map +1 -1
  56. package/lib/samples/ObservedOutboundVideoTrack.d.ts +1 -0
  57. package/lib/samples/ObservedOutboundVideoTrack.d.ts.map +1 -1
  58. package/lib/samples/ObservedPeerConnection.d.ts.map +1 -1
  59. package/lib/samples/ObservedPeerConnection.js +15 -8
  60. package/lib/samples/ObservedSfus.d.ts.map +1 -1
  61. package/lib/samples/ObservedSfus.js +10 -4
  62. package/lib/storages/ObserverStorage.d.ts +4 -0
  63. package/lib/storages/ObserverStorage.d.ts.map +1 -1
  64. package/lib/storages/SimpleStorage.d.ts +1 -0
  65. package/lib/storages/SimpleStorage.d.ts.map +1 -1
  66. package/lib/storages/SimpleStorage.js +3 -0
  67. package/package.json +1 -1
  68. package/src/Evaluator.ts +7 -6
  69. package/src/Observer.ts +1 -0
  70. package/src/common/callMetaReports.ts +2 -0
  71. package/src/common/utils.ts +11 -0
  72. package/src/middlewares/DeleteOutdatedCallEntries.ts +151 -0
  73. package/src/middlewares/DeleteOutdatedSfuEntries.ts +159 -0
  74. package/src/middlewares/TransactionContext.ts +61 -29
  75. package/src/middlewares/TransactoinProcessor.ts +8 -2
  76. package/src/middlewares/VisitObservedCallsMiddleware.ts +42 -128
  77. package/src/middlewares/visitors/visitClient.ts +34 -18
  78. package/src/middlewares/visitors/visitInboundAudioTrack.ts +15 -5
  79. package/src/middlewares/visitors/visitInboundVideoTrack.ts +14 -2
  80. package/src/middlewares/visitors/visitOutboundAudioTrack.ts +6 -2
  81. package/src/middlewares/visitors/visitOutboundVideoTarck.ts +5 -1
  82. package/src/middlewares/visitors/visitPeerConnection.ts +17 -1
  83. package/src/models/Models.ts +40 -34
  84. package/src/processes/findRemoteMatches.ts +94 -0
  85. package/src/processes/joinClientProcess.ts +1 -3
  86. package/src/samples/ObservedCalls.ts +17 -7
  87. package/src/samples/ObservedInboundAudioTrack.ts +2 -0
  88. package/src/samples/ObservedInboundVideoTrack.ts +3 -1
  89. package/src/samples/ObservedOutboundAudioTrack.ts +2 -1
  90. package/src/samples/ObservedOutboundVideoTrack.ts +2 -1
  91. package/src/samples/ObservedPeerConnection.ts +29 -8
  92. package/src/samples/ObservedSfus.ts +10 -5
  93. package/src/storages/ObserverStorage.ts +5 -0
  94. package/src/storages/SimpleStorage.ts +4 -0
@@ -67,41 +67,73 @@ export async function createTransactionContext(
67
67
  sfuSctpChannelStorage,
68
68
  } = storageProvider;
69
69
 
70
- const [clients, sfus] = await Promise.all([clientStorage.getAll(observedCalls.clientIds()), sfuStorage.getAll([])]);
70
+ const [
71
+ [
72
+ clients,
73
+ peerConnections,
74
+ inboundAudioTrackEntries,
75
+ inboundVideoTrackEntries,
76
+ outboundAudioTrackEntries,
77
+ outboundVideoTrackEntries,
78
+ ],
79
+ [
80
+ sfus,
81
+ sfuTransports,
82
+ sfuInboundRtpPads,
83
+ sfuOutboundRtpPads,
84
+ sfuSctpChannels
85
+ ]
86
+ ] = await Promise.all([
87
+ Promise.all([
88
+ clientStorage.getAll(observedCalls.clientIds()),
89
+ peerConnectionStorage.getAll(observedCalls.peerConnectionIds()),
90
+ inboundTrackStorage.getAll(observedCalls.inboundAudioTrackIds()),
91
+ inboundTrackStorage.getAll(observedCalls.inboundVideoTrackIds()),
92
+ outboundTrackStorage.getAll(observedCalls.outboundAudioTrackIds()),
93
+ outboundTrackStorage.getAll(observedCalls.outboundVideoTrackIds()),
94
+ ]),
95
+ Promise.all([
96
+ sfuStorage.getAll(observedSfus.sfuIds()),
97
+ sfuTransportStorage.getAll(observedSfus.sfuTransportIds()),
98
+ sfuInboundRtpPadStorage.getAll(observedCalls.peerConnectionIds()),
99
+ sfuOutboundRtpPadStorage.getAll(observedCalls.peerConnectionIds()),
100
+ sfuSctpChannelStorage.getAll(observedCalls.peerConnectionIds()),
101
+ ])
102
+ ]);
71
103
 
72
- const peerConnectionIds = Array.from(clients.values()).flatMap((client) => client.peerConnectionIds);
104
+ // const peerConnectionIds = Array.from(clients.values()).flatMap((client) => client.peerConnectionIds);
73
105
 
74
- const sfuTransportIds = Array.from(sfus.values()).flatMap((sfu) => sfu.sfuTransportIds);
106
+ // const sfuTransportIds = Array.from(sfus.values()).flatMap((sfu) => sfu.sfuTransportIds);
75
107
 
76
- const [peerConnections, sfuTransports] = await Promise.all([
77
- peerConnectionStorage.getAll(peerConnectionIds),
78
- sfuTransportStorage.getAll(sfuTransportIds),
79
- ]);
108
+ // const [peerConnections, sfuTransports] = await Promise.all([
109
+ // peerConnectionStorage.getAll(peerConnectionIds),
110
+ // sfuTransportStorage.getAll(sfuTransportIds),
111
+ // ]);
80
112
 
81
- const peerConnectionValues = Array.from(peerConnections.values());
82
- const inboundTrackIds = peerConnectionValues.flatMap((pc) => pc.inboundTrackIds);
83
- const outboundTrackIds = peerConnectionValues.flatMap((pc) => pc.outboundTrackIds);
84
-
85
- const sfuTransportValues = Array.from(sfuTransports.values());
86
- const sfuInboundRtpPadIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.inboundRtpPadIds);
87
- const sfuOutboundRtpPadIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.outboundRtpPadIds);
88
- const sfuSctpChannelIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.sctpChannelIds);
89
-
90
- const [inboundTracks, outboundTracks, sfuInboundRtpPads, sfuOutboundRtpPads, sfuSctpChannels] = await Promise.all([
91
- inboundTrackStorage.getAll(inboundTrackIds),
92
- outboundTrackStorage.getAll(outboundTrackIds),
93
- sfuInboundRtpPadStorage.getAll(sfuInboundRtpPadIds),
94
- sfuOutboundRtpPadStorage.getAll(sfuOutboundRtpPadIds),
95
- sfuSctpChannelStorage.getAll(sfuSctpChannelIds),
96
- ]);
113
+ // const peerConnectionValues = Array.from(peerConnections.values());
114
+ // const inboundTrackIds = peerConnectionValues.flatMap((pc) => pc.inboundTrackIds);
115
+ // const outboundTrackIds = peerConnectionValues.flatMap((pc) => pc.outboundTrackIds);
116
+
117
+ // const sfuTransportValues = Array.from(sfuTransports.values());
118
+ // const sfuInboundRtpPadIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.inboundRtpPadIds);
119
+ // const sfuOutboundRtpPadIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.outboundRtpPadIds);
120
+ // const sfuSctpChannelIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.sctpChannelIds);
121
+
122
+ // const [inboundTracks, outboundTracks, sfuInboundRtpPads, sfuOutboundRtpPads, sfuSctpChannels] = await Promise.all([
123
+ // inboundTrackStorage.getAll(inboundTrackIds),
124
+ // outboundTrackStorage.getAll(outboundTrackIds),
125
+ // sfuInboundRtpPadStorage.getAll(sfuInboundRtpPadIds),
126
+ // sfuOutboundRtpPadStorage.getAll(sfuOutboundRtpPadIds),
127
+ // sfuSctpChannelStorage.getAll(sfuSctpChannelIds),
128
+ // ]);
97
129
 
98
- const inboundTrackEntries = Array.from(inboundTracks);
99
- const outboundTrackEntries = Array.from(outboundTracks);
130
+ // const inboundTrackEntries = Array.from(inboundTracks);
131
+ // const outboundTrackEntries = Array.from(outboundTracks);
100
132
 
101
- const inboundAudioTrackEntries = inboundTrackEntries.filter((e) => e[1].kind === 'audio');
102
- const inboundVideoTrackEntries = inboundTrackEntries.filter((e) => e[1].kind === 'video');
103
- const outboundAudioTrackEntries = outboundTrackEntries.filter((e) => e[1].kind === 'audio');
104
- const outboundVideoTrackEntries = outboundTrackEntries.filter((e) => e[1].kind === 'video');
133
+ // const inboundAudioTrackEntries = inboundTrackEntries.filter((e) => e[1].kind === 'audio');
134
+ // const inboundVideoTrackEntries = inboundTrackEntries.filter((e) => e[1].kind === 'video');
135
+ // const outboundAudioTrackEntries = outboundTrackEntries.filter((e) => e[1].kind === 'audio');
136
+ // const outboundVideoTrackEntries = outboundTrackEntries.filter((e) => e[1].kind === 'video');
105
137
 
106
138
  const transactionContext: TransactionContext = {
107
139
  id: uuid(),
@@ -1,6 +1,8 @@
1
1
  import { ReportsCollector } from '../common/ReportsCollector';
2
2
  import { StorageProvider } from '../storages/StorageProvider';
3
3
  import { createCommitTransactionMiddleware } from './CommitTransactionMiddleware';
4
+ import { createDeleteOutdatedCallEntries } from './DeleteOutdatedCallEntries';
5
+ import { createDeleteOutdatedSfuEntries } from './DeleteOutdatedSfuEntries';
4
6
  import { Processor, createProcessor } from './Processor';
5
7
  import { TransactionContext } from './TransactionContext';
6
8
  import { createVisitObservedCallsMiddleware } from './VisitObservedCallsMiddleware';
@@ -9,12 +11,16 @@ import { createVisitObservedSfusMiddleware } from './VisitObservedSfusMiddleware
9
11
  export function createTransactionProcessor(
10
12
  storageProvider: StorageProvider,
11
13
  reportsCollector: ReportsCollector,
12
- fetchSamples: boolean
14
+ fetchSamples: boolean,
15
+ maxIdleTimeInMs: BigInt,
16
+ findRemoteMatches?: boolean,
13
17
  ): Processor<TransactionContext> {
14
18
  return createProcessor(
15
19
  // all of these middlewares must execute sequentially!
16
- createVisitObservedCallsMiddleware(reportsCollector, fetchSamples),
20
+ createVisitObservedCallsMiddleware(storageProvider, reportsCollector, fetchSamples, findRemoteMatches),
17
21
  createVisitObservedSfusMiddleware(reportsCollector, fetchSamples),
22
+ createDeleteOutdatedCallEntries(storageProvider, maxIdleTimeInMs),
23
+ createDeleteOutdatedSfuEntries(storageProvider, maxIdleTimeInMs),
18
24
 
19
25
  // must be the last one!
20
26
  createCommitTransactionMiddleware(storageProvider, reportsCollector)
@@ -7,32 +7,30 @@ import { createLogger } from '../common/logger';
7
7
  import { visitInboundAudioTrack } from './visitors/visitInboundAudioTrack';
8
8
  import { visitOutboundAudioTrack } from './visitors/visitOutboundAudioTrack';
9
9
  import { visitOutboundVideoTrack } from './visitors/visitOutboundVideoTarck';
10
- import { CallEventReport, ClientExtensionReport } from '@observertc/report-schemas-js';
10
+ import { visitInboundVideoTrack } from './visitors/visitInboundVideoTrack';
11
+ import { InboundTrack } from '../models/Models';
12
+ import { StorageProvider } from '../storages/StorageProvider';
13
+ import { findRemoteMatches as findRemoteMatchFunc } from '../processes/findRemoteMatches';
11
14
 
12
15
  export const logger = createLogger('VisitObservedCallsMiddleware');
13
16
 
17
+ const emptyMap = new Map();
18
+
14
19
  export function createVisitObservedCallsMiddleware(
20
+ storages: StorageProvider,
15
21
  reports: ReportsCollector,
16
- fetchSamples: boolean
22
+ fetchSamples: boolean,
23
+ findRemoteMatches?: boolean,
17
24
  ): Middleware<TransactionContext> {
18
25
  const process = async (transaction: TransactionContext) => {
19
26
  const {
20
27
  observedCalls,
21
28
  clients,
22
29
  updatedPeerConnections,
23
- deletedPeerConnections,
24
-
25
30
  updatedInboundAudioTracks,
26
- deletedInboundAudioTracks,
27
-
28
31
  updatedInboundVideoTracks,
29
- deletedInboundVideoTracks,
30
-
31
32
  updatedOutboundAudioTracks,
32
- deletedOutboundAudioTracks,
33
-
34
33
  updatedOutboundVideoTracks,
35
- deletedOutboundVideoTracks,
36
34
  } = transaction;
37
35
 
38
36
  const visitedPeerConnectionIds = new Set<string>();
@@ -40,6 +38,23 @@ export function createVisitObservedCallsMiddleware(
40
38
  const visitedInboundVideoTrackIds = new Set<string>();
41
39
  const visitedOutboundAudioTrackIds = new Set<string>();
42
40
  const visitedOutboundVideoTrackIds = new Set<string>();
41
+
42
+ const {
43
+ remoteTrackIds,
44
+ remotePeerConnectionIds,
45
+ remoteClientIds
46
+ } = !findRemoteMatches ? {
47
+ remoteTrackIds: emptyMap,
48
+ remotePeerConnectionIds: emptyMap,
49
+ remoteClientIds: emptyMap,
50
+ } : await findRemoteMatchFunc(
51
+ storages,
52
+ clients,
53
+ new Map<string, InboundTrack>([...updatedInboundAudioTracks, ...updatedInboundVideoTracks])
54
+ )
55
+
56
+ const now = BigInt(Date.now());
57
+ const fakeTouched = { touched: BigInt(0) };
43
58
 
44
59
  for (const observedCall of observedCalls.observedCalls()) {
45
60
  const { callId, serviceId, roomId } = observedCall;
@@ -48,7 +63,6 @@ export function createVisitObservedCallsMiddleware(
48
63
  const { clientId } = observedClient;
49
64
  const storedClient = clients.get(clientId);
50
65
 
51
- // console.warn("dskfjhdkfhsdkf", observedClient, storedClient);
52
66
  if (!storedClient) {
53
67
  // should not happen as client joined must have run before this
54
68
  logger.warn('Client has not been registered');
@@ -61,7 +75,7 @@ export function createVisitObservedCallsMiddleware(
61
75
  reports,
62
76
  fetchSamples
63
77
  );
64
-
78
+
65
79
  for (const observedPeerConnection of observedClient.observedPeerConnections()) {
66
80
  const { peerConnectionId } = observedPeerConnection;
67
81
 
@@ -75,35 +89,43 @@ export function createVisitObservedCallsMiddleware(
75
89
  );
76
90
  continue;
77
91
  }
78
-
92
+
93
+ storedPeerConnection.touched = now;
79
94
  visitedPeerConnectionIds.add(peerConnectionId);
80
95
 
81
96
  for (const observedInboundAudioTrack of observedPeerConnection.inboundAudioTracks()) {
82
97
  const { trackId } = observedInboundAudioTrack;
83
-
84
98
  visitInboundAudioTrack(
85
99
  observedInboundAudioTrack,
86
100
  storedPeerConnection,
87
101
  updatedInboundAudioTracks,
88
102
  reports,
89
- fetchSamples
103
+ fetchSamples,
104
+ remoteTrackIds.get(trackId),
105
+ remotePeerConnectionIds.get(trackId),
106
+ remoteClientIds.get(trackId),
90
107
  );
91
108
 
92
109
  visitedInboundAudioTrackIds.add(trackId);
110
+ (updatedInboundAudioTracks.get(trackId) ?? fakeTouched).touched = now;
93
111
  }
94
112
 
95
113
  for (const observedInboundVideoTrack of observedPeerConnection.inboundVideoTracks()) {
96
114
  const { trackId } = observedInboundVideoTrack;
97
115
 
98
- visitInboundAudioTrack(
116
+ visitInboundVideoTrack(
99
117
  observedInboundVideoTrack,
100
118
  storedPeerConnection,
101
119
  updatedInboundVideoTracks,
102
120
  reports,
103
- fetchSamples
121
+ fetchSamples,
122
+ remoteTrackIds.get(trackId),
123
+ remotePeerConnectionIds.get(trackId),
124
+ remoteClientIds.get(trackId),
104
125
  );
105
126
 
106
127
  visitedInboundVideoTrackIds.add(trackId);
128
+ (updatedInboundVideoTracks.get(trackId) ?? fakeTouched).touched = now;
107
129
  }
108
130
 
109
131
  for (const observedOutboundAudioTrack of observedPeerConnection.outboundAudioTracks()) {
@@ -118,6 +140,7 @@ export function createVisitObservedCallsMiddleware(
118
140
  );
119
141
 
120
142
  visitedOutboundAudioTrackIds.add(trackId);
143
+ (updatedOutboundAudioTracks.get(trackId) ?? fakeTouched).touched = now;
121
144
  }
122
145
 
123
146
  for (const observedOutboundVideoTrack of observedPeerConnection.outboundVideoTracks()) {
@@ -132,120 +155,11 @@ export function createVisitObservedCallsMiddleware(
132
155
  );
133
156
 
134
157
  visitedOutboundVideoTrackIds.add(trackId);
158
+ (updatedOutboundVideoTracks.get(trackId) ?? fakeTouched).touched = now;
135
159
  }
136
160
  }
137
161
  }
138
162
  }
139
-
140
- for (const [peerConnectionId, peerConnection] of Array.from(updatedPeerConnections.entries())) {
141
- if (visitedPeerConnectionIds.has(peerConnectionId)) {
142
- continue;
143
- }
144
- // delete PeerConnection
145
- const { serviceId, callId, clientId } = peerConnection;
146
-
147
- if (!serviceId || !callId || !clientId) {
148
- continue;
149
- }
150
-
151
- const storedClient = clients.get(clientId);
152
-
153
- updatedPeerConnections.delete(peerConnectionId);
154
- deletedPeerConnections.add(peerConnectionId);
155
-
156
- // also update the client model
157
- if (storedClient) {
158
- storedClient.peerConnectionIds = storedClient.peerConnectionIds.filter((pcId) => pcId !== peerConnectionId);
159
- }
160
- }
161
-
162
- for (const [trackId, inboundAudioTrack] of Array.from(updatedInboundAudioTracks.entries())) {
163
- if (visitedInboundAudioTrackIds.has(trackId)) {
164
- continue;
165
- }
166
- // delete PeerConnection
167
- const { serviceId, callId, clientId, peerConnectionId } = inboundAudioTrack;
168
-
169
- if (!serviceId || !callId || !clientId || !peerConnectionId) {
170
- continue;
171
- }
172
-
173
- const storedPeerConnection = updatedPeerConnections.get(peerConnectionId);
174
-
175
- updatedInboundAudioTracks.delete(peerConnectionId);
176
- deletedInboundAudioTracks.add(peerConnectionId);
177
-
178
- // also update the peer connection model
179
- if (storedPeerConnection) {
180
- storedPeerConnection.inboundTrackIds = storedPeerConnection.inboundTrackIds.filter((tId) => tId !== trackId);
181
- }
182
- }
183
-
184
- for (const [trackId, inboundVideoTrack] of Array.from(updatedInboundVideoTracks.entries())) {
185
- if (visitedInboundVideoTrackIds.has(trackId)) {
186
- continue;
187
- }
188
- // delete PeerConnection
189
- const { serviceId, callId, clientId, peerConnectionId } = inboundVideoTrack;
190
-
191
- if (!serviceId || !callId || !clientId || !peerConnectionId) {
192
- continue;
193
- }
194
-
195
- const storedPeerConnection = updatedPeerConnections.get(peerConnectionId);
196
-
197
- updatedInboundVideoTracks.delete(peerConnectionId);
198
- deletedInboundVideoTracks.add(peerConnectionId);
199
-
200
- // also update the peer connection model
201
- if (storedPeerConnection) {
202
- storedPeerConnection.inboundTrackIds = storedPeerConnection.inboundTrackIds.filter((tId) => tId !== trackId);
203
- }
204
- }
205
-
206
- for (const [trackId, OutboundAudioTrack] of Array.from(updatedOutboundAudioTracks.entries())) {
207
- if (visitedOutboundAudioTrackIds.has(trackId)) {
208
- continue;
209
- }
210
- // delete PeerConnection
211
- const { serviceId, callId, clientId, peerConnectionId } = OutboundAudioTrack;
212
-
213
- if (!serviceId || !callId || !clientId || !peerConnectionId) {
214
- continue;
215
- }
216
-
217
- const storedPeerConnection = updatedPeerConnections.get(peerConnectionId);
218
-
219
- updatedOutboundAudioTracks.delete(peerConnectionId);
220
- deletedOutboundAudioTracks.add(peerConnectionId);
221
-
222
- // also update the peer connection model
223
- if (storedPeerConnection) {
224
- storedPeerConnection.outboundTrackIds = storedPeerConnection.outboundTrackIds.filter((tId) => tId !== trackId);
225
- }
226
- }
227
-
228
- for (const [trackId, OutboundVideoTrack] of Array.from(updatedOutboundVideoTracks.entries())) {
229
- if (visitedOutboundVideoTrackIds.has(trackId)) {
230
- continue;
231
- }
232
- // delete PeerConnection
233
- const { serviceId, callId, clientId, peerConnectionId } = OutboundVideoTrack;
234
-
235
- if (!serviceId || !callId || !clientId || !peerConnectionId) {
236
- continue;
237
- }
238
-
239
- const storedPeerConnection = updatedPeerConnections.get(peerConnectionId);
240
-
241
- updatedOutboundVideoTracks.delete(peerConnectionId);
242
- deletedOutboundVideoTracks.add(peerConnectionId);
243
-
244
- // also update the peer connection model
245
- if (storedPeerConnection) {
246
- storedPeerConnection.outboundTrackIds = storedPeerConnection.outboundTrackIds.filter((tId) => tId !== trackId);
247
- }
248
- }
249
163
  };
250
164
  const result = async (context: TransactionContext, next?: Middleware<TransactionContext>) => {
251
165
  await process(context);
@@ -15,26 +15,33 @@ export function visitClient(
15
15
  reports: ReportsCollector,
16
16
  fetchSamples: boolean
17
17
  ) {
18
- const { mediaUnitId, clientId } = observedClient;
18
+ const { mediaUnitId, clientId, userId } = observedClient;
19
19
 
20
20
  const { callId, serviceId, roomId } = observedClient.call;
21
21
 
22
22
  for (const clientSample of observedClient.samples()) {
23
- if (clientSample.os) {
23
+ if (clientSample.os && (
24
+ client.operationSystem?.name !== clientSample.os.name ||
25
+ client.operationSystem?.version !== clientSample.os.version ||
26
+ client.operationSystem?.versionName !== clientSample.os.versionName
27
+ )) {
24
28
  if (fetchSamples) {
25
29
  client.operationSystem = new Samples_ClientSample_OperationSystem({
26
30
  ...clientSample.os,
27
31
  });
28
32
  }
29
-
33
+
30
34
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
31
35
  type: CallMetaType.OPERATION_SYSTEM,
32
36
  payload: clientSample.os,
33
- });
37
+ }, userId);
34
38
  reports.addCallMetaReport(callMetaReport);
35
39
  }
36
40
 
37
- if (clientSample.engine) {
41
+ if (clientSample.engine && (
42
+ client.engine?.name !== clientSample.engine.name ||
43
+ client.engine?.version !== clientSample.engine.version
44
+ )) {
38
45
  if (fetchSamples) {
39
46
  client.engine = new Samples_ClientSample_Engine({
40
47
  ...clientSample.engine,
@@ -44,11 +51,15 @@ export function visitClient(
44
51
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
45
52
  type: CallMetaType.ENGINE,
46
53
  payload: clientSample.engine,
47
- });
54
+ }, userId);
48
55
  reports.addCallMetaReport(callMetaReport);
49
56
  }
50
57
 
51
- if (clientSample.platform) {
58
+ if (clientSample.platform && (
59
+ client.platform?.model !== clientSample.platform.model ||
60
+ client.platform?.type !== clientSample.platform.type ||
61
+ client.platform?.vendor !== clientSample.platform.vendor
62
+ )) {
52
63
  if (fetchSamples) {
53
64
  client.platform = new Samples_ClientSample_Platform({
54
65
  ...clientSample.platform,
@@ -58,11 +69,14 @@ export function visitClient(
58
69
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
59
70
  type: CallMetaType.PLATFORM,
60
71
  payload: clientSample.platform,
61
- });
72
+ }, userId);
62
73
  reports.addCallMetaReport(callMetaReport);
63
74
  }
64
75
 
65
- if (clientSample.browser) {
76
+ if (clientSample.browser && (
77
+ client.browser?.name !== clientSample.browser.name ||
78
+ client.browser?.version !== clientSample.browser.version
79
+ )) {
66
80
  if (fetchSamples) {
67
81
  client.browser = new Samples_ClientSample_Browser({
68
82
  ...clientSample.browser,
@@ -72,7 +86,7 @@ export function visitClient(
72
86
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
73
87
  type: CallMetaType.BROWSER,
74
88
  payload: clientSample.browser,
75
- });
89
+ }, userId);
76
90
  reports.addCallMetaReport(callMetaReport);
77
91
  }
78
92
 
@@ -81,7 +95,7 @@ export function visitClient(
81
95
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
82
96
  type: CallMetaType.MEDIA_CONSTRAINT,
83
97
  payload: mediaConstraint,
84
- });
98
+ }, userId);
85
99
  reports.addCallMetaReport(callMetaReport);
86
100
  }
87
101
  }
@@ -92,7 +106,7 @@ export function visitClient(
92
106
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
93
107
  type: CallMetaType.LOCAL_SDP,
94
108
  payload: localSDP,
95
- });
109
+ }, userId);
96
110
  reports.addCallMetaReport(callMetaReport);
97
111
  }
98
112
  }
@@ -105,6 +119,7 @@ export function visitClient(
105
119
  roomId,
106
120
  callId,
107
121
  clientId,
122
+ userId,
108
123
  timestamp: Date.now(),
109
124
  payload: extensionStats.payload,
110
125
  extensionType: extensionStats.type,
@@ -120,6 +135,7 @@ export function visitClient(
120
135
  roomId,
121
136
  callId,
122
137
  clientId,
138
+ userId,
123
139
  timestamp: Date.now(),
124
140
  ...callEvent,
125
141
  });
@@ -131,7 +147,7 @@ export function visitClient(
131
147
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
132
148
  type: CallMetaType.USER_MEDIA_ERROR,
133
149
  payload: userMediaError,
134
- });
150
+ }, userId);
135
151
  reports.addCallMetaReport(callMetaReport);
136
152
  }
137
153
  }
@@ -141,7 +157,7 @@ export function visitClient(
141
157
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
142
158
  type: CallMetaType.CERTIFICATE,
143
159
  payload: certificate,
144
- });
160
+ }, userId);
145
161
  reports.addCallMetaReport(callMetaReport);
146
162
  }
147
163
  }
@@ -151,7 +167,7 @@ export function visitClient(
151
167
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
152
168
  type: CallMetaType.CODEC,
153
169
  payload: codec,
154
- });
170
+ }, userId);
155
171
  reports.addCallMetaReport(callMetaReport);
156
172
  }
157
173
  }
@@ -161,7 +177,7 @@ export function visitClient(
161
177
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
162
178
  type: CallMetaType.ICE_SERVER,
163
179
  payload: iceServer,
164
- });
180
+ }, userId);
165
181
  reports.addCallMetaReport(callMetaReport);
166
182
  }
167
183
  }
@@ -171,7 +187,7 @@ export function visitClient(
171
187
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
172
188
  type: CallMetaType.MEDIA_DEVICE,
173
189
  payload: mediaDevice,
174
- });
190
+ }, userId);
175
191
  reports.addCallMetaReport(callMetaReport);
176
192
  }
177
193
  }
@@ -181,7 +197,7 @@ export function visitClient(
181
197
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
182
198
  type: CallMetaType.MEDIA_SOURCE,
183
199
  payload: mediaSource,
184
- });
200
+ }, userId);
185
201
  reports.addCallMetaReport(callMetaReport);
186
202
  }
187
203
  }
@@ -10,9 +10,12 @@ export function visitInboundAudioTrack(
10
10
  storedPeerConnection: Models.PeerConnection,
11
11
  storedInboundTracks: Map<string, Models.InboundTrack>,
12
12
  reports: ReportsCollector,
13
- fetchSamples: boolean
13
+ fetchSamples: boolean,
14
+ remoteTrackId?: string,
15
+ remotePeerConnectionId?: string,
16
+ remoteClientId?: string,
14
17
  ) {
15
- const { trackId } = observedInboundAudioTrack;
18
+ const { trackId, sfuStreamId, sfuSinkId } = observedInboundAudioTrack;
16
19
 
17
20
  const { peerConnectionId } = observedInboundAudioTrack.peerConnection;
18
21
 
@@ -25,7 +28,7 @@ export function visitInboundAudioTrack(
25
28
  } = observedInboundAudioTrack.peerConnection.client;
26
29
 
27
30
  const { serviceId, roomId, callId } = observedInboundAudioTrack.peerConnection.client.call;
28
-
31
+
29
32
  let storedInboundAudioTrack = storedInboundTracks.get(trackId);
30
33
  if (!storedInboundAudioTrack) {
31
34
  storedInboundAudioTrack = new Models.InboundTrack({
@@ -33,10 +36,13 @@ export function visitInboundAudioTrack(
33
36
  roomId,
34
37
  callId,
35
38
  clientId,
39
+ kind: 'audio',
36
40
  peerConnectionId,
37
41
  mediaUnitId,
38
42
  trackId,
39
-
43
+ sfuSinkId,
44
+ sfuStreamId,
45
+
40
46
  userId,
41
47
  marker,
42
48
  });
@@ -58,11 +64,15 @@ export function visitInboundAudioTrack(
58
64
  roomId,
59
65
  callId,
60
66
  clientId,
67
+ userId,
61
68
  mediaUnitId,
62
69
  peerConnectionId,
63
70
  ...inboundAudioSample,
64
71
  timestamp,
65
72
  sampleSeq: -1,
73
+ remoteClientId,
74
+ remotePeerConnectionId,
75
+ remoteTrackId,
66
76
  };
67
77
  reports.addInboundAudioTrackReport(report);
68
78
 
@@ -93,6 +103,6 @@ export function visitInboundAudioTrack(
93
103
  statsMap.set(ssrc, videoStats);
94
104
  }
95
105
  }
96
-
106
+ storedInboundAudioTrack.ssrc = [...statsMap.keys()];
97
107
  storedInboundAudioTrack.videoStats = Array.from(statsMap.values());
98
108
  }
@@ -12,9 +12,12 @@ export function visitInboundVideoTrack(
12
12
  storedPeerConnection: Models.PeerConnection,
13
13
  storedInboundTracks: Map<string, Models.InboundTrack>,
14
14
  reports: ReportsCollector,
15
- fetchSamples: boolean
15
+ fetchSamples: boolean,
16
+ remoteTrackId?: string,
17
+ remotePeerConnectionId?: string,
18
+ remoteClientId?: string,
16
19
  ) {
17
- const { trackId } = observedInboundVideoTrack;
20
+ const { trackId, sfuStreamId, sfuSinkId } = observedInboundVideoTrack;
18
21
 
19
22
  const { peerConnectionId } = observedInboundVideoTrack.peerConnection;
20
23
 
@@ -35,9 +38,13 @@ export function visitInboundVideoTrack(
35
38
  roomId,
36
39
  callId,
37
40
  clientId,
41
+ kind: 'video',
38
42
  peerConnectionId,
39
43
  mediaUnitId,
40
44
  trackId,
45
+
46
+ sfuStreamId,
47
+ sfuSinkId,
41
48
 
42
49
  userId,
43
50
  marker,
@@ -59,11 +66,15 @@ export function visitInboundVideoTrack(
59
66
  roomId,
60
67
  callId,
61
68
  clientId,
69
+ userId,
62
70
  mediaUnitId,
63
71
  peerConnectionId,
64
72
  ...inboundVideoSample,
65
73
  timestamp,
66
74
  sampleSeq: -1,
75
+ remoteClientId,
76
+ remotePeerConnectionId,
77
+ remoteTrackId,
67
78
  };
68
79
  reports.addInboundVideoTrackReport(report);
69
80
 
@@ -96,5 +107,6 @@ export function visitInboundVideoTrack(
96
107
  statsMap.set(ssrc, videoStats);
97
108
  }
98
109
  }
110
+ storedInboundVideoTrack.ssrc = [...statsMap.keys()];
99
111
  storedInboundVideoTrack.videoStats = Array.from(statsMap.values());
100
112
  }