@observertc/observer-js 1.0.1-4416b1e.0 → 1.0.1-4daea92.0

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 (50) hide show
  1. package/lib/ObservedCall.d.ts +2 -0
  2. package/lib/ObservedCall.d.ts.map +1 -1
  3. package/lib/ObservedCall.js +4 -0
  4. package/lib/ObservedCallEventMonitor.d.ts +103 -0
  5. package/lib/ObservedCallEventMonitor.d.ts.map +1 -0
  6. package/lib/ObservedCallEventMonitor.js +312 -0
  7. package/lib/ObservedClient.d.ts +10 -3
  8. package/lib/ObservedClient.d.ts.map +1 -1
  9. package/lib/ObservedClient.js +73 -3
  10. package/lib/Observer.d.ts +2 -0
  11. package/lib/Observer.d.ts.map +1 -1
  12. package/lib/Observer.js +10 -2
  13. package/lib/ObserverEventMonitor.d.ts +106 -0
  14. package/lib/ObserverEventMonitor.d.ts.map +1 -0
  15. package/lib/ObserverEventMonitor.js +320 -0
  16. package/lib/index.d.ts +1 -0
  17. package/lib/index.d.ts.map +1 -1
  18. package/lib/index.js +3 -1
  19. package/lib/schema/ClientEventTypes.d.ts +60 -0
  20. package/lib/schema/ClientEventTypes.d.ts.map +1 -1
  21. package/lib/updaters/{OnAllCallObserverUpdater_.d.ts → OnAllCallObserverUpdater.d.ts} +3 -1
  22. package/lib/updaters/OnAllCallObserverUpdater.d.ts.map +1 -0
  23. package/lib/updaters/{OnAllCallObserverUpdater_.js → OnAllCallObserverUpdater.js} +13 -1
  24. package/lib/updaters/OnAllClientCallUpdater.d.ts +2 -0
  25. package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -1
  26. package/lib/updaters/OnAllClientCallUpdater.js +16 -0
  27. package/lib/updaters/{OnAnyCallObserverUpdater_.d.ts → OnAnyCallObserverUpdater.d.ts} +2 -1
  28. package/lib/updaters/OnAnyCallObserverUpdater.d.ts.map +1 -0
  29. package/lib/updaters/{OnAnyCallObserverUpdater_.js → OnAnyCallObserverUpdater.js} +11 -1
  30. package/lib/updaters/OnAnyClientCallUpdater.d.ts +1 -0
  31. package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -1
  32. package/lib/updaters/OnAnyClientCallUpdater.js +11 -2
  33. package/lib/utils/MediasoupRemoteTrackResolver.d.ts +25 -0
  34. package/lib/utils/MediasoupRemoteTrackResolver.d.ts.map +1 -0
  35. package/lib/utils/MediasoupRemoteTrackResolver.js +110 -0
  36. package/package.json +1 -1
  37. package/src/ObservedCall.ts +5 -0
  38. package/src/ObservedCallEventMonitor.ts +389 -0
  39. package/src/ObservedClient.ts +88 -5
  40. package/src/Observer.ts +12 -3
  41. package/src/ObserverEventMonitor.ts +398 -0
  42. package/src/index.ts +1 -0
  43. package/src/schema/ClientEventTypes.ts +64 -0
  44. package/src/updaters/{OnAllCallObserverUpdater_.ts → OnAllCallObserverUpdater.ts} +14 -1
  45. package/src/updaters/OnAllClientCallUpdater.ts +15 -0
  46. package/src/updaters/{OnAnyCallObserverUpdater_.ts → OnAnyCallObserverUpdater.ts} +11 -2
  47. package/src/updaters/OnAnyClientCallUpdater.ts +9 -2
  48. package/src/utils/MediasoupRemoteTrackResolver.ts +155 -0
  49. package/lib/updaters/OnAllCallObserverUpdater_.d.ts.map +0 -1
  50. package/lib/updaters/OnAnyCallObserverUpdater_.d.ts.map +0 -1
@@ -0,0 +1,389 @@
1
+ import { ObservedCall } from './ObservedCall';
2
+ import { ObservedCertificate } from './ObservedCertificate';
3
+ import { ObservedClient, ObservedClientEvents } from './ObservedClient';
4
+ import { ObservedCodec } from './ObservedCodec';
5
+ import { ObservedDataChannel } from './ObservedDataChannel';
6
+ import { ObservedIceCandidate } from './ObservedIceCandidate';
7
+ import { ObservedIceCandidatePair } from './ObservedIceCandidatePair';
8
+ import { ObservedIceTransport } from './ObservedIceTransport';
9
+ import { ObservedInboundRtp } from './ObservedInboundRtp';
10
+ import { ObservedInboundTrack } from './ObservedInboundTrack';
11
+ import { ObservedMediaPlayout } from './ObservedMediaPlayout';
12
+ import { ObservedMediaSource } from './ObservedMediaSource';
13
+ import { ObservedOutboundRtp } from './ObservedOutboundRtp';
14
+ import { ObservedOutboundTrack } from './ObservedOutboundTrack';
15
+ import { ObservedPeerConnection } from './ObservedPeerConnection';
16
+ import { ClientEvent, ClientIssue, ClientMetaData, ClientSample, ExtensionStat } from './schema/ClientSample';
17
+
18
+ export class ObservedCallEventMonitor<Context> {
19
+ public constructor(
20
+ public readonly call: ObservedCall,
21
+ public readonly context: Context,
22
+ ) {
23
+ this._onPeerConnconnectionAdded = this._onPeerConnconnectionAdded.bind(this);
24
+ this._onPeerConnectionRemoved = this._onPeerConnectionRemoved.bind(this);
25
+ this._onCertificateAdded = this._onCertificateAdded.bind(this);
26
+ this._onCertificateRemoved = this._onCertificateRemoved.bind(this);
27
+ this._onInboundTrackAdded = this._onInboundTrackAdded.bind(this);
28
+ this._onInboundTrackRemoved = this._onInboundTrackRemoved.bind(this);
29
+ this._onOutboundTrackAdded = this._onOutboundTrackAdded.bind(this);
30
+ this._onOutboundTrackRemoved = this._onOutboundTrackRemoved.bind(this);
31
+ this._onInboundRtpAdded = this._onInboundRtpAdded.bind(this);
32
+ this._onInboundRtpRemoved = this._onInboundRtpRemoved.bind(this);
33
+ this._onOutboundRtpAdded = this._onOutboundRtpAdded.bind(this);
34
+ this._onOutboundRtpRemoved = this._onOutboundRtpRemoved.bind(this);
35
+ this._onDataChannelAdded = this._onDataChannelAdded.bind(this);
36
+ this._onDataChannelRemoved = this._onDataChannelRemoved.bind(this);
37
+ this._onAddedIceTransport = this._onAddedIceTransport.bind(this);
38
+ this._onRemovedIceTransport = this._onRemovedIceTransport.bind(this);
39
+ this._onIceCandidateAdded = this._onIceCandidateAdded.bind(this);
40
+ this._onIceCandidateRemoved = this._onIceCandidateRemoved.bind(this);
41
+ this._onAddedIceCandidatePair = this._onAddedIceCandidatePair.bind(this);
42
+ this._onRemovedIceCandidatePair = this._onRemovedIceCandidatePair.bind(this);
43
+ this._onAddedMediaCodec = this._onAddedMediaCodec.bind(this);
44
+ this._onRemovedMediaCodec = this._onRemovedMediaCodec.bind(this);
45
+ this._onAddedMediaPlayout = this._onAddedMediaPlayout.bind(this);
46
+ this._onRemovedMediaPlayout = this._onRemovedMediaPlayout.bind(this);
47
+ this._onMediaSourceAdded = this._onMediaSourceAdded.bind(this);
48
+ this._onMediaSourceRemoved = this._onMediaSourceRemoved.bind(this);
49
+ this._onClientIssue = this._onClientIssue.bind(this);
50
+ this._onClientMetadata = this._onClientMetadata.bind(this);
51
+ this._onClientJoined = this._onClientJoined.bind(this);
52
+ this._onClientLeft = this._onClientLeft.bind(this);
53
+ this._onUserMediaError = this._onUserMediaError.bind(this);
54
+ this._onUsingTurn = this._onUsingTurn.bind(this);
55
+ this._onClientAdded = this._onClientAdded.bind(this);
56
+ this._onCallAdded = this._onCallAdded.bind(this);
57
+ this._onClientRejoined = this._onClientRejoined.bind(this);
58
+ this._onClientExtensionStats = this._onClientExtensionStats.bind(this);
59
+
60
+ this._onCallAdded(call);
61
+ }
62
+
63
+ // Public event handlers
64
+ public onCallEmpty?: (call: ObservedCall, ctx: Context) => void;
65
+ public onCallNotEmpty?: (call: ObservedCall, ctx: Context) => void;
66
+ public onCallUpdated?: (call: ObservedCall, ctx: Context) => void;
67
+
68
+ public onClientAdded?: (client: ObservedClient, ctx: Context) => void;
69
+ public onClientClosed?: (client: ObservedClient, ctx: Context) => void;
70
+ public onClientRejoined?: (client: ObservedClient, ctx: Context) => void;
71
+ public onClientIssue?: (observedClent: ObservedClient, issue: ClientIssue, ctx: Context) => void;
72
+ public onClientMetadata?: (observedClient: ObservedClient, metadata: ClientMetaData, ctx: Context) => void;
73
+ public onClientExtensionStats?: (observedClient: ObservedClient, extensionStats: ExtensionStat, ctx: Context) => void;
74
+ public onClientJoined?: (client: ObservedClient, ctx: Context) => void;
75
+ public onClientLeft?: (client: ObservedClient, ctx: Context) => void;
76
+ public onClientUserMediaError?: (observedClient: ObservedClient, error: string, ctx: Context) => void;
77
+ public onClientUsingTurn?: (client: ObservedClient, usingTurn: boolean, ctx: Context) => void;
78
+ public onClientUpdated?: (client: ObservedClient, sample: ClientSample, ctx: Context) => void;
79
+ public onClientEvent?: (client: ObservedClient, event: ClientEvent, ctx: Context) => void;
80
+
81
+ public onPeerConnectionAdded?: (peerConnection: ObservedPeerConnection, ctx: Context) => void;
82
+ public onPeerConnectionRemoved?: (peerConnection: ObservedPeerConnection, ctx: Context) => void;
83
+ public onSelectedCandidatePairChanged?: (peerConnection: ObservedPeerConnection, ctx: Context) => void;
84
+ public onIceGatheringStateChange?: (peerConnection: ObservedPeerConnection, ctx: Context) => void;
85
+ public onIceConnectionStateChange?: (peerConnection: ObservedPeerConnection, ctx: Context) => void;
86
+ public onConnectionStateChange?: (peerConnection: ObservedPeerConnection, ctx: Context) => void;
87
+
88
+ public onCertificateAdded?: (certificate: ObservedCertificate, ctx: Context) => void;
89
+ public onCertificateRemoved?: (certificate: ObservedCertificate, ctx: Context) => void;
90
+
91
+ public onInboundTrackAdded?: (inboundTrack: ObservedInboundTrack, ctx: Context) => void;
92
+ public onInboundTrackRemoved?: (inboundTrack: ObservedInboundTrack, ctx: Context) => void;
93
+
94
+ public onOutboundTrackAdded?: (outboundTrack: ObservedOutboundTrack, ctx: Context) => void;
95
+ public onOutboundTrackRemoved?: (outboundTrack: ObservedOutboundTrack, ctx: Context) => void;
96
+
97
+ public onInboundRtpAdded?: (inboundRtp: ObservedInboundRtp, ctx: Context) => void;
98
+ public onInboundRtpRemoved?: (inboundRtp: ObservedInboundRtp, ctx: Context) => void;
99
+
100
+ public onOutboundRtpAdded?: (outboundRtp: ObservedOutboundRtp, ctx: Context) => void;
101
+ public onOutboundRtpRemoved?: (outboundRtp: ObservedOutboundRtp, ctx: Context) => void;
102
+
103
+ public onDataChannelAdded?: (dataChannel: ObservedDataChannel, ctx: Context) => void;
104
+ public onDataChannelRemoved?: (dataChannel: ObservedDataChannel, ctx: Context) => void;
105
+
106
+ public onAddedIceTransport?: (iceTransport: ObservedIceTransport, ctx: Context) => void;
107
+ public onRemovedIceTransport?: (iceTransport: ObservedIceTransport, ctx: Context) => void;
108
+
109
+ public onIceCandidateAdded?: (iceCandidate: ObservedIceCandidate, ctx: Context) => void;
110
+ public onIceCandidateRemoved?: (iceCandidate: ObservedIceCandidate, ctx: Context) => void;
111
+
112
+ public onAddedIceCandidatePair?: (candidatePair: ObservedIceCandidatePair, ctx: Context) => void;
113
+ public onRemovedIceCandidatePair?: (candidatePair: ObservedIceCandidatePair, ctx: Context) => void;
114
+
115
+ public onAddedMediaCodec?: (codec: ObservedCodec, ctx: Context) => void;
116
+ public onRemovedMediaCodec?: (codec: ObservedCodec, ctx: Context) => void;
117
+
118
+ public onAddedMediaPlayout?: (mediaPlayout: ObservedMediaPlayout, ctx: Context) => void;
119
+ public onRemovedMediaPlayout?: (mediaPlayout: ObservedMediaPlayout, ctx: Context) => void;
120
+
121
+ public onMediaSourceAdded?: (mediaSource: ObservedMediaSource, ctx: Context) => void;
122
+ public onMediaSourceRemoved?: (mediaSource: ObservedMediaSource, ctx: Context) => void;
123
+
124
+ private _onCallAdded(call: ObservedCall) {
125
+ const onCallEmpty = () => this.onCallEmpty?.(call, this.context);
126
+ const onCallNotEmpty = () => this.onCallNotEmpty?.(call, this.context);
127
+ const onCallUpdated = () => this.onCallUpdated?.(call, this.context);
128
+
129
+ call.once('close', () => {
130
+ call.off('newclient', this._onClientAdded);
131
+ call.off('empty', onCallEmpty);
132
+ call.off('not-empty', onCallNotEmpty);
133
+ call.off('update', onCallUpdated);
134
+
135
+ });
136
+ call.on('newclient', this._onClientAdded);
137
+ call.on('empty', onCallEmpty);
138
+ call.on('not-empty', onCallNotEmpty);
139
+ call.on('update', onCallUpdated);
140
+
141
+ }
142
+
143
+ private _onClientAdded(observedClient: ObservedClient) {
144
+ const onClientIssue = (issue: ClientIssue) => this._onClientIssue(observedClient, issue);
145
+ const onClientMetadata = (metaData: ClientMetaData) => this._onClientMetadata(observedClient, metaData);
146
+ const onClientJoined = () => this._onClientJoined(observedClient);
147
+ const onClientLeft = () => this._onClientLeft(observedClient);
148
+ const onClientRejoined = () => this._onClientRejoined(observedClient);
149
+ const onClientExtensionStats = (extensionStats: ExtensionStat) => this._onClientExtensionStats(observedClient, extensionStats);
150
+ const onUsingTurn = (usingTurn: boolean) => this._onUsingTurn(observedClient, usingTurn);
151
+ const onUserMediaError = (error: string) => this._onUserMediaError(observedClient, error);
152
+ const onClientUpdated = (...args: ObservedClientEvents['update']) => this.onClientUpdated?.(observedClient, args[0].sample, this.context);
153
+ const onClientEvent = (event: ClientEvent) => this.onClientEvent?.(observedClient, event, this.context);
154
+
155
+ observedClient.once('close', () => {
156
+ observedClient.off('newpeerconnection', this._onPeerConnconnectionAdded);
157
+ observedClient.off('issue', onClientIssue);
158
+ observedClient.off('metaData', onClientMetadata);
159
+ observedClient.off('joined', onClientJoined);
160
+ observedClient.off('left', onClientLeft);
161
+ observedClient.off('rejoined', onClientJoined);
162
+ observedClient.off('usermediaerror', onUserMediaError);
163
+ observedClient.off('usingturn', onUsingTurn);
164
+ observedClient.off('update', onClientUpdated);
165
+ observedClient.off('clientEvent', onClientEvent);
166
+
167
+ this.onClientClosed?.(observedClient, this.context);
168
+ });
169
+
170
+ observedClient.on('newpeerconnection', this._onPeerConnconnectionAdded);
171
+ observedClient.on('issue', onClientIssue);
172
+ observedClient.on('metaData', onClientMetadata);
173
+ observedClient.on('joined', onClientJoined);
174
+ observedClient.on('left', onClientLeft);
175
+ observedClient.on('rejoined', onClientRejoined);
176
+ observedClient.on('usermediaerror', onUserMediaError);
177
+ observedClient.on('usingturn', onUsingTurn);
178
+ observedClient.on('extensionStats', onClientExtensionStats);
179
+ observedClient.on('update', onClientUpdated);
180
+ observedClient.on('clientEvent', onClientEvent);
181
+
182
+ this.onClientAdded?.(observedClient, this.context);
183
+ }
184
+
185
+ private _onClientRejoined(observedClient: ObservedClient) {
186
+ this.onClientRejoined?.(observedClient, this.context);
187
+ }
188
+
189
+ private _onPeerConnconnectionAdded(peerConnection: ObservedPeerConnection) {
190
+ const onSelectedCandidatePairChanged = () => this.onSelectedCandidatePairChanged?.(peerConnection, this.context);
191
+ const onIceGatheringStateChange = () => this.onIceGatheringStateChange?.(peerConnection, this.context);
192
+ const onIceConnectionStateChange = () => this.onIceConnectionStateChange?.(peerConnection, this.context);
193
+ const onConnectionStateChange = () => this.onConnectionStateChange?.(peerConnection, this.context);
194
+
195
+ peerConnection.once('close', () => {
196
+ peerConnection.off('added-certificate', this._onCertificateAdded);
197
+ peerConnection.off('removed-certificate', this._onCertificateRemoved);
198
+ peerConnection.off('added-inbound-track', this._onInboundTrackAdded);
199
+ peerConnection.off('removed-inbound-track', this._onInboundTrackRemoved);
200
+ peerConnection.off('added-outbound-track', this._onOutboundTrackAdded);
201
+ peerConnection.off('removed-outbound-track', this._onOutboundTrackRemoved);
202
+ peerConnection.off('added-inbound-rtp', this._onInboundRtpAdded);
203
+ peerConnection.off('removed-inbound-rtp', this._onInboundRtpRemoved);
204
+ peerConnection.off('added-outbound-rtp', this._onOutboundRtpAdded);
205
+ peerConnection.off('removed-outbound-rtp', this._onOutboundRtpRemoved);
206
+ peerConnection.off('added-data-channel', this._onDataChannelAdded);
207
+ peerConnection.off('removed-data-channel', this._onDataChannelRemoved);
208
+ peerConnection.off('added-ice-transport', this._onAddedIceTransport);
209
+ peerConnection.off('removed-ice-transport', this._onRemovedIceTransport);
210
+ peerConnection.off('added-ice-candidate', this._onIceCandidateAdded);
211
+ peerConnection.off('removed-ice-candidate', this._onIceCandidateRemoved);
212
+ peerConnection.off('added-ice-candidate-pair', this._onAddedIceCandidatePair);
213
+ peerConnection.off('removed-ice-candidate-pair', this._onRemovedIceCandidatePair);
214
+ peerConnection.off('added-codec', this._onAddedMediaCodec);
215
+ peerConnection.off('removed-codec', this._onRemovedMediaCodec);
216
+ peerConnection.off('added-media-playout', this._onAddedMediaPlayout);
217
+ peerConnection.off('removed-media-playout', this._onRemovedMediaPlayout);
218
+ peerConnection.off('added-media-source', this._onMediaSourceAdded);
219
+ peerConnection.off('removed-media-source', this._onMediaSourceRemoved);
220
+ peerConnection.off('selectedcandidatepair', onSelectedCandidatePairChanged);
221
+ peerConnection.off('icegatheringstatechange', onIceGatheringStateChange);
222
+ peerConnection.off('iceconnectionstatechange', onIceConnectionStateChange);
223
+ peerConnection.off('connectionstatechange', onConnectionStateChange);
224
+
225
+ this.onPeerConnectionRemoved?.(peerConnection, this.context);
226
+ });
227
+
228
+ peerConnection.on('added-certificate', this._onCertificateAdded);
229
+ peerConnection.on('removed-certificate', this._onCertificateRemoved);
230
+ peerConnection.on('added-inbound-track', this._onInboundTrackAdded);
231
+ peerConnection.on('removed-inbound-track', this._onInboundTrackRemoved);
232
+ peerConnection.on('added-outbound-track', this._onOutboundTrackAdded);
233
+ peerConnection.on('removed-outbound-track', this._onOutboundTrackRemoved);
234
+ peerConnection.on('added-inbound-rtp', this._onInboundRtpAdded);
235
+ peerConnection.on('removed-inbound-rtp', this._onInboundRtpRemoved);
236
+ peerConnection.on('added-outbound-rtp', this._onOutboundRtpAdded);
237
+ peerConnection.on('removed-outbound-rtp', this._onOutboundRtpRemoved);
238
+ peerConnection.on('added-data-channel', this._onDataChannelAdded);
239
+ peerConnection.on('removed-data-channel', this._onDataChannelRemoved);
240
+ peerConnection.on('added-ice-transport', this._onAddedIceTransport);
241
+ peerConnection.on('removed-ice-transport', this._onRemovedIceTransport);
242
+ peerConnection.on('added-ice-candidate', this._onIceCandidateAdded);
243
+ peerConnection.on('removed-ice-candidate', this._onIceCandidateRemoved);
244
+ peerConnection.on('added-ice-candidate-pair', this._onAddedIceCandidatePair);
245
+ peerConnection.on('removed-ice-candidate-pair', this._onRemovedIceCandidatePair);
246
+ peerConnection.on('added-codec', this._onAddedMediaCodec);
247
+ peerConnection.on('removed-codec', this._onRemovedMediaCodec);
248
+ peerConnection.on('added-media-playout', this._onAddedMediaPlayout);
249
+ peerConnection.on('removed-media-playout', this._onRemovedMediaPlayout);
250
+ peerConnection.on('added-media-source', this._onMediaSourceAdded);
251
+ peerConnection.on('removed-media-source', this._onMediaSourceRemoved);
252
+ peerConnection.on('selectedcandidatepair', onSelectedCandidatePairChanged);
253
+ peerConnection.on('icegatheringstatechange', onIceGatheringStateChange);
254
+ peerConnection.on('iceconnectionstatechange', onIceConnectionStateChange);
255
+ peerConnection.on('connectionstatechange', onConnectionStateChange);
256
+
257
+ this.onPeerConnectionAdded?.(peerConnection, this.context);
258
+
259
+ }
260
+
261
+ private _onPeerConnectionRemoved(peerConnection: ObservedPeerConnection) {
262
+ this.onPeerConnectionRemoved?.(peerConnection, this.context);
263
+
264
+ }
265
+
266
+ private _onCertificateAdded(certificate: ObservedCertificate) {
267
+ this.onCertificateAdded?.(certificate, this.context);
268
+ }
269
+
270
+ private _onCertificateRemoved(certificate: ObservedCertificate) {
271
+ this.onCertificateRemoved?.(certificate, this.context);
272
+ }
273
+
274
+ private _onInboundTrackAdded(inboundTrack: ObservedInboundTrack) {
275
+ this.onInboundTrackAdded?.(inboundTrack, this.context);
276
+ }
277
+
278
+ private _onInboundTrackRemoved(inboundTrack: ObservedInboundTrack) {
279
+ this.onInboundTrackRemoved?.(inboundTrack, this.context);
280
+ }
281
+
282
+ private _onOutboundTrackAdded(outboundTrack: ObservedOutboundTrack) {
283
+ this.onOutboundTrackAdded?.(outboundTrack, this.context);
284
+ }
285
+
286
+ private _onOutboundTrackRemoved(outboundTrack: ObservedOutboundTrack) {
287
+ this.onOutboundTrackRemoved?.(outboundTrack, this.context);
288
+ }
289
+
290
+ private _onInboundRtpAdded(inboundRtp: ObservedInboundRtp) {
291
+ this.onInboundRtpAdded?.(inboundRtp, this.context);
292
+ }
293
+
294
+ private _onInboundRtpRemoved(inboundRtp: ObservedInboundRtp) {
295
+ this.onInboundRtpRemoved?.(inboundRtp, this.context);
296
+ }
297
+
298
+ private _onOutboundRtpAdded(outboundRtp: ObservedOutboundRtp) {
299
+ this.onOutboundRtpAdded?.(outboundRtp, this.context);
300
+ }
301
+
302
+ private _onOutboundRtpRemoved(outboundRtp: ObservedOutboundRtp) {
303
+ this.onOutboundRtpRemoved?.(outboundRtp, this.context);
304
+ }
305
+
306
+ private _onDataChannelAdded(dataChannel: ObservedDataChannel) {
307
+ this.onDataChannelAdded?.(dataChannel, this.context);
308
+ }
309
+
310
+ private _onDataChannelRemoved(dataChannel: ObservedDataChannel) {
311
+ this.onDataChannelRemoved?.(dataChannel, this.context);
312
+ }
313
+
314
+ private _onAddedIceTransport(iceTransport: ObservedIceTransport) {
315
+ this.onAddedIceTransport?.(iceTransport, this.context);
316
+ }
317
+
318
+ private _onRemovedIceTransport(iceTransport: ObservedIceTransport) {
319
+ this.onRemovedIceTransport?.(iceTransport, this.context);
320
+ }
321
+
322
+ private _onIceCandidateAdded(iceCandidate: ObservedIceCandidate) {
323
+ this.onIceCandidateAdded?.(iceCandidate, this.context);
324
+ }
325
+
326
+ private _onIceCandidateRemoved(iceCandidate: ObservedIceCandidate) {
327
+ this.onIceCandidateRemoved?.(iceCandidate, this.context);
328
+ }
329
+
330
+ private _onAddedIceCandidatePair(candidatePair: ObservedIceCandidatePair) {
331
+ this.onAddedIceCandidatePair?.(candidatePair, this.context);
332
+ }
333
+
334
+ private _onRemovedIceCandidatePair(candidatePair: ObservedIceCandidatePair) {
335
+ this.onRemovedIceCandidatePair?.(candidatePair, this.context);
336
+ }
337
+
338
+ private _onAddedMediaCodec(codec: ObservedCodec) {
339
+ this.onAddedMediaCodec?.(codec, this.context);
340
+ }
341
+
342
+ private _onRemovedMediaCodec(codec: ObservedCodec) {
343
+ this.onRemovedMediaCodec?.(codec, this.context);
344
+ }
345
+
346
+ private _onAddedMediaPlayout(mediaPlayout: ObservedMediaPlayout) {
347
+ this.onAddedMediaPlayout?.(mediaPlayout, this.context);
348
+ }
349
+
350
+ private _onRemovedMediaPlayout(mediaPlayout: ObservedMediaPlayout) {
351
+ this.onRemovedMediaPlayout?.(mediaPlayout, this.context);
352
+ }
353
+
354
+ private _onMediaSourceAdded(mediaSource: ObservedMediaSource) {
355
+ this.onMediaSourceAdded?.(mediaSource, this.context);
356
+ }
357
+
358
+ private _onMediaSourceRemoved(mediaSource: ObservedMediaSource) {
359
+ this.onMediaSourceRemoved?.(mediaSource, this.context);
360
+ }
361
+
362
+ private _onClientIssue(observedClent: ObservedClient, issue: ClientIssue) {
363
+ this.onClientIssue?.(observedClent, issue, this.context);
364
+ }
365
+
366
+ private _onClientMetadata(observedClient: ObservedClient, metadata: ClientMetaData) {
367
+ this.onClientMetadata?.(observedClient, metadata, this.context);
368
+ }
369
+
370
+ private _onClientExtensionStats(observedClient: ObservedClient, extensionStats: ExtensionStat) {
371
+ this.onClientExtensionStats?.(observedClient, extensionStats, this.context);
372
+ }
373
+
374
+ private _onClientJoined(observedClient: ObservedClient) {
375
+ this.onClientJoined?.(observedClient, this.context);
376
+ }
377
+
378
+ private _onClientLeft(observedClient: ObservedClient) {
379
+ this.onClientLeft?.(observedClient, this.context);
380
+ }
381
+
382
+ private _onUserMediaError(observedClient: ObservedClient, error: string) {
383
+ this.onClientUserMediaError?.(observedClient, error, this.context);
384
+ }
385
+
386
+ private _onUsingTurn(observedClient: ObservedClient, usingTurn: boolean) {
387
+ this.onClientUsingTurn?.(observedClient, usingTurn, this.context);
388
+ }
389
+ }
@@ -10,7 +10,6 @@ import { ClientMetaTypes } from './schema/ClientMetaTypes';
10
10
  import { parseJsonAs } from './common/utils';
11
11
  import { CalculatedScore } from './scores/CalculatedScore';
12
12
  import { Detectors } from './detectors/Detectors';
13
- import { ObservedClientEventMonitor } from './ObservedClientEventMonitor';
14
13
 
15
14
  const logger = createLogger('ObservedClient');
16
15
 
@@ -34,8 +33,9 @@ export type ObservedClientEvents = {
34
33
  left: [];
35
34
  usingturn: [boolean];
36
35
  usermediaerror: [string];
36
+ extensionStats: [ExtensionStat];
37
+ clientEvent: [ClientEvent];
37
38
 
38
- // do we need this?
39
39
  newpeerconnection: [ObservedPeerConnection];
40
40
  };
41
41
 
@@ -138,6 +138,8 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
138
138
  public readonly mediaDevices: MetaData.MediaDeviceInfo[] = [];
139
139
  public issues: ClientIssue[] = [];
140
140
 
141
+ private _injections: Pick<ClientSample, 'clientEvents' | 'clientIssues' | 'extensionStats' | 'attachments' | 'clientMetaItems'> = {};
142
+
141
143
  public constructor(settings: ObservedClientSettings<AppData>, public readonly call: ObservedCall) {
142
144
  super();
143
145
  this.setMaxListeners(Infinity);
@@ -209,6 +211,8 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
209
211
  this.currentMinRttInMs = undefined;
210
212
  this.currentMaxRttInMs = undefined;
211
213
 
214
+ this._mergeInjections(sample);
215
+
212
216
  const clientEventsPostBuffer: ClientEvent[] = [];
213
217
 
214
218
  for (const clientEvent of sample.clientEvents ?? []) {
@@ -467,8 +471,49 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
467
471
  }
468
472
  break;
469
473
  }
470
-
471
474
  }
475
+ this.emit('clientEvent', event);
476
+ }
477
+
478
+ public injectMetaData(metaData: ClientMetaData) {
479
+ if (this.closed) return;
480
+
481
+ if (!this._injections.clientMetaItems) this._injections.clientMetaItems = [];
482
+
483
+ this._injections.clientMetaItems.push(metaData);
484
+ }
485
+
486
+ public injectEvent(event: ClientEvent) {
487
+ if (this.closed) return;
488
+
489
+ if (!this._injections.clientEvents) this._injections.clientEvents = [];
490
+
491
+ this._injections.clientEvents.push(event);
492
+ }
493
+
494
+ public injectIssue(issue: ClientIssue) {
495
+ if (this.closed) return;
496
+
497
+ if (!this._injections.clientIssues) this._injections.clientIssues = [];
498
+
499
+ this._injections.clientIssues.push(issue);
500
+ }
501
+
502
+ public injectExtensionStat(stat: ExtensionStat) {
503
+ if (this.closed) return;
504
+
505
+ if (!this._injections.extensionStats) this._injections.extensionStats = [];
506
+
507
+ this._injections.extensionStats.push(stat);
508
+ }
509
+
510
+ public injectAttachment(key: string, value: unknown) {
511
+ if (this.closed) return;
512
+
513
+ if (!this._injections.attachments) this._injections.attachments = {};
514
+
515
+ this._injections.attachments[key] = value;
516
+
472
517
  }
473
518
 
474
519
  public addMetadata(metadata: ClientMetaData) {
@@ -505,6 +550,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
505
550
 
506
551
  public addExtensionStats(stats: ExtensionStat) {
507
552
  this.call.observer.emit('client-extension-stats', this, stats);
553
+ this.emit('extensionStats', stats);
508
554
  }
509
555
 
510
556
  private _updatePeerConnection(sample: PeerConnectionSample): ObservedPeerConnection | undefined {
@@ -533,8 +579,45 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
533
579
  return observedPeerConnection;
534
580
  }
535
581
 
536
- public createEventMonitor<CTX = unknown>(ctx?: CTX): ObservedClientEventMonitor<CTX> {
537
- return new ObservedClientEventMonitor<CTX>(this, ctx ?? {} as CTX);
582
+ private _mergeInjections(sample: ClientSample): ClientSample {
583
+ if (this.closed) return sample;
584
+
585
+ if (this._injections.clientEvents) {
586
+ if (!sample.clientEvents) sample.clientEvents = [];
587
+ sample.clientEvents.push(...this._injections.clientEvents);
588
+
589
+ this._injections.clientEvents = undefined;
590
+ }
591
+
592
+ if (this._injections.clientIssues) {
593
+ if (!sample.clientIssues) sample.clientIssues = [];
594
+ sample.clientIssues.push(...this._injections.clientIssues);
595
+
596
+ this._injections.clientIssues = undefined;
597
+ }
598
+
599
+ if (this._injections.extensionStats) {
600
+ if (!sample.extensionStats) sample.extensionStats = [];
601
+ sample.extensionStats.push(...this._injections.extensionStats);
602
+
603
+ this._injections.extensionStats = undefined;
604
+ }
605
+
606
+ if (this._injections.attachments) {
607
+ if (!sample.attachments) sample.attachments = {};
608
+ Object.assign(sample.attachments, this._injections.attachments);
609
+
610
+ this._injections.attachments = undefined;
611
+ }
612
+
613
+ if (this._injections.clientMetaItems) {
614
+ if (!sample.clientMetaItems) sample.clientMetaItems = [];
615
+ sample.clientMetaItems.push(...this._injections.clientMetaItems);
616
+
617
+ this._injections.clientMetaItems = undefined;
618
+ }
619
+
620
+ return sample;
538
621
  }
539
622
 
540
623
  // public resetSummaryMetrics() {
package/src/Observer.ts CHANGED
@@ -7,8 +7,10 @@ import { ObservedTURN } from './ObservedTURN';
7
7
  import { Detectors } from './detectors/Detectors';
8
8
  import { Updater } from './updaters/Updater';
9
9
  import { OnIntervalUpdater } from './updaters/OnIntervalUpdater';
10
- import { OnAllCallObserverUpdater } from './updaters/OnAllCallObserverUpdater_';
11
- import { OnAnyCallObserverUpdater } from './updaters/OnAnyCallObserverUpdater_';
10
+ import { OnAllCallObserverUpdater } from './updaters/OnAllCallObserverUpdater';
11
+ import { OnAnyCallObserverUpdater } from './updaters/OnAnyCallObserverUpdater';
12
+ import { ObserverEventMonitor } from './ObserverEventMonitor';
13
+ import { MediasoupRemoteTrackResolver } from './utils/MediasoupRemoteTrackResolver';
12
14
 
13
15
  const logger = createLogger('Observer');
14
16
 
@@ -124,12 +126,15 @@ export class Observer extends EventEmitter {
124
126
  settings.updatePolicy = this.config.defaultCallUpdatePolicy;
125
127
  settings.updateIntervalInMs = this.config.defaultCallUpdateIntervalInMs;
126
128
  }
127
-
128
129
  const observedCall = new ObservedCall(settings, this);
129
130
  const onCallUpdated = () => this._onObservedCallUpdated(observedCall);
130
131
 
131
132
  if (this.observedCalls.has(observedCall.callId)) throw new Error(`Observed Call with id ${observedCall.callId} already exists`);
132
133
 
134
+ if (settings.remoteTrackResolvePolicy === 'mediasoup-sfu') {
135
+ observedCall.remoteTrackResolver = new MediasoupRemoteTrackResolver(observedCall);
136
+ }
137
+
133
138
  observedCall.once('close', () => {
134
139
  this.observedCalls.delete(observedCall.callId);
135
140
  observedCall.off('update', onCallUpdated);
@@ -210,6 +215,10 @@ export class Observer extends EventEmitter {
210
215
  this.totalClientIssues += call.deltaNumberOfIssues;
211
216
  }
212
217
 
218
+ public createEventMonitor<CTX = unknown>(ctx?: CTX): ObserverEventMonitor<CTX> {
219
+ return new ObserverEventMonitor<CTX>(this, ctx ?? {} as CTX);
220
+ }
221
+
213
222
  // public resetSummaryMetrics() {
214
223
  // this.totalAddedCall = 0;
215
224
  // this.totalRemovedCall = 0;