@observertc/observer-js 1.0.1-72a904d.0 → 1.0.1-9341fcd.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.
- package/lib/ObservedCall.d.ts +4 -8
- package/lib/ObservedCall.d.ts.map +1 -1
- package/lib/ObservedCall.js +16 -72
- package/lib/ObservedCallEventMonitor.d.ts +104 -0
- package/lib/ObservedCallEventMonitor.d.ts.map +1 -0
- package/lib/ObservedCallEventMonitor.js +314 -0
- package/lib/ObservedClient.d.ts +16 -8
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +257 -99
- package/lib/ObservedClientEventMonitor.d.ts +89 -0
- package/lib/ObservedClientEventMonitor.d.ts.map +1 -0
- package/lib/ObservedClientEventMonitor.js +247 -0
- package/lib/ObservedDataChannel.d.ts +2 -0
- package/lib/ObservedDataChannel.d.ts.map +1 -1
- package/lib/ObservedDataChannel.js +2 -0
- package/lib/ObservedIceCandidatePair.d.ts +2 -1
- package/lib/ObservedIceCandidatePair.d.ts.map +1 -1
- package/lib/ObservedIceCandidatePair.js +17 -1
- package/lib/ObservedInboundTrack.d.ts +2 -0
- package/lib/ObservedInboundTrack.d.ts.map +1 -1
- package/lib/ObservedInboundTrack.js +2 -0
- package/lib/ObservedOutboundTrack.d.ts +2 -0
- package/lib/ObservedOutboundTrack.d.ts.map +1 -1
- package/lib/ObservedOutboundTrack.js +2 -0
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/ObservedPeerConnection.js +22 -6
- package/lib/Observer.d.ts +9 -7
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +16 -22
- package/lib/ObserverEventMonitor.d.ts +106 -0
- package/lib/ObserverEventMonitor.d.ts.map +1 -0
- package/lib/ObserverEventMonitor.js +320 -0
- package/lib/ObserverSummary.d.ts +2 -0
- package/lib/ObserverSummary.d.ts.map +1 -1
- package/lib/common/utils.d.ts +1 -0
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +7 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -1
- package/lib/schema/ClientEventTypes.d.ts +60 -0
- package/lib/schema/ClientEventTypes.d.ts.map +1 -1
- package/lib/schema/ClientSample.d.ts +1 -1
- package/lib/schema/ClientSample.d.ts.map +1 -1
- package/lib/updaters/{OnAllCallObserverUpdater_.d.ts → OnAllCallObserverUpdater.d.ts} +3 -1
- package/lib/updaters/OnAllCallObserverUpdater.d.ts.map +1 -0
- package/lib/updaters/{OnAllCallObserverUpdater_.js → OnAllCallObserverUpdater.js} +13 -1
- package/lib/updaters/OnAllClientCallUpdater.d.ts +2 -0
- package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -1
- package/lib/updaters/OnAllClientCallUpdater.js +16 -0
- package/lib/updaters/{OnAnyCallObserverUpdater_.d.ts → OnAnyCallObserverUpdater.d.ts} +2 -1
- package/lib/updaters/OnAnyCallObserverUpdater.d.ts.map +1 -0
- package/lib/updaters/{OnAnyCallObserverUpdater_.js → OnAnyCallObserverUpdater.js} +11 -1
- package/lib/updaters/OnAnyClientCallUpdater.d.ts +1 -0
- package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -1
- package/lib/updaters/OnAnyClientCallUpdater.js +11 -2
- package/lib/utils/MediasoupRemoteTrackResolver.d.ts +25 -0
- package/lib/utils/MediasoupRemoteTrackResolver.d.ts.map +1 -0
- package/lib/utils/MediasoupRemoteTrackResolver.js +110 -0
- package/package.json +1 -1
- package/src/ObservedCall.ts +56 -82
- package/src/ObservedCallEventMonitor.ts +392 -0
- package/src/ObservedClient.ts +335 -114
- package/src/ObservedClientEventMonitor.ts +301 -0
- package/src/ObservedDataChannel.ts +3 -0
- package/src/ObservedIceCandidatePair.ts +18 -2
- package/src/ObservedInboundTrack.ts +3 -0
- package/src/ObservedOutboundTrack.ts +3 -0
- package/src/ObservedPeerConnection.ts +25 -10
- package/src/Observer.ts +47 -29
- package/src/ObserverEventMonitor.ts +398 -0
- package/src/ObserverSummary.ts +3 -1
- package/src/common/utils.ts +6 -0
- package/src/index.ts +2 -0
- package/src/schema/ClientEventTypes.ts +64 -0
- package/src/schema/ClientSample.ts +1 -1
- package/src/updaters/{OnAllCallObserverUpdater_.ts → OnAllCallObserverUpdater.ts} +14 -1
- package/src/updaters/OnAllClientCallUpdater.ts +15 -0
- package/src/updaters/{OnAnyCallObserverUpdater_.ts → OnAnyCallObserverUpdater.ts} +11 -2
- package/src/updaters/OnAnyClientCallUpdater.ts +9 -2
- package/src/utils/MediasoupRemoteTrackResolver.ts +155 -0
- package/lib/updaters/OnAllCallObserverUpdater_.d.ts.map +0 -1
- package/lib/updaters/OnAnyCallObserverUpdater_.d.ts.map +0 -1
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { ObservedCertificate } from './ObservedCertificate';
|
|
2
|
+
import { ObservedClient } from './ObservedClient';
|
|
3
|
+
import { ObservedCodec } from './ObservedCodec';
|
|
4
|
+
import { ObservedDataChannel } from './ObservedDataChannel';
|
|
5
|
+
import { ObservedIceCandidate } from './ObservedIceCandidate';
|
|
6
|
+
import { ObservedIceCandidatePair } from './ObservedIceCandidatePair';
|
|
7
|
+
import { ObservedIceTransport } from './ObservedIceTransport';
|
|
8
|
+
import { ObservedInboundRtp } from './ObservedInboundRtp';
|
|
9
|
+
import { ObservedInboundTrack } from './ObservedInboundTrack';
|
|
10
|
+
import { ObservedMediaPlayout } from './ObservedMediaPlayout';
|
|
11
|
+
import { ObservedMediaSource } from './ObservedMediaSource';
|
|
12
|
+
import { ObservedOutboundRtp } from './ObservedOutboundRtp';
|
|
13
|
+
import { ObservedOutboundTrack } from './ObservedOutboundTrack';
|
|
14
|
+
import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
15
|
+
import { ClientIssue, ClientMetaData, ExtensionStat } from './schema/ClientSample';
|
|
16
|
+
|
|
17
|
+
export class ObservedClientEventMonitor<Context> {
|
|
18
|
+
public constructor(
|
|
19
|
+
public readonly observedClient: ObservedClient,
|
|
20
|
+
public readonly context: Context,
|
|
21
|
+
) {
|
|
22
|
+
this._onPeerConnconnectionAdded = this._onPeerConnconnectionAdded.bind(this);
|
|
23
|
+
this._onPeerConnectionRemoved = this._onPeerConnectionRemoved.bind(this);
|
|
24
|
+
this._onCertificateAdded = this._onCertificateAdded.bind(this);
|
|
25
|
+
this._onCertificateRemoved = this._onCertificateRemoved.bind(this);
|
|
26
|
+
this._onInboundTrackAdded = this._onInboundTrackAdded.bind(this);
|
|
27
|
+
this._onInboundTrackRemoved = this._onInboundTrackRemoved.bind(this);
|
|
28
|
+
this._onOutboundTrackAdded = this._onOutboundTrackAdded.bind(this);
|
|
29
|
+
this._onOutboundTrackRemoved = this._onOutboundTrackRemoved.bind(this);
|
|
30
|
+
this._onInboundRtpAdded = this._onInboundRtpAdded.bind(this);
|
|
31
|
+
this._onInboundRtpRemoved = this._onInboundRtpRemoved.bind(this);
|
|
32
|
+
this._onOutboundRtpAdded = this._onOutboundRtpAdded.bind(this);
|
|
33
|
+
this._onOutboundRtpRemoved = this._onOutboundRtpRemoved.bind(this);
|
|
34
|
+
this._onDataChannelAdded = this._onDataChannelAdded.bind(this);
|
|
35
|
+
this._onDataChannelRemoved = this._onDataChannelRemoved.bind(this);
|
|
36
|
+
this._onAddedIceTransport = this._onAddedIceTransport.bind(this);
|
|
37
|
+
this._onRemovedIceTransport = this._onRemovedIceTransport.bind(this);
|
|
38
|
+
this._onIceCandidateAdded = this._onIceCandidateAdded.bind(this);
|
|
39
|
+
this._onIceCandidateRemoved = this._onIceCandidateRemoved.bind(this);
|
|
40
|
+
this._onAddedIceCandidatePair = this._onAddedIceCandidatePair.bind(this);
|
|
41
|
+
this._onRemovedIceCandidatePair = this._onRemovedIceCandidatePair.bind(this);
|
|
42
|
+
this._onAddedMediaCodec = this._onAddedMediaCodec.bind(this);
|
|
43
|
+
this._onRemovedMediaCodec = this._onRemovedMediaCodec.bind(this);
|
|
44
|
+
this._onAddedMediaPlayout = this._onAddedMediaPlayout.bind(this);
|
|
45
|
+
this._onRemovedMediaPlayout = this._onRemovedMediaPlayout.bind(this);
|
|
46
|
+
this._onMediaSourceAdded = this._onMediaSourceAdded.bind(this);
|
|
47
|
+
this._onMediaSourceRemoved = this._onMediaSourceRemoved.bind(this);
|
|
48
|
+
this._onClientClosed = this._onClientClosed.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
|
+
|
|
56
|
+
this.observedClient.on('newpeerconnection', this._onPeerConnconnectionAdded);
|
|
57
|
+
this.observedClient.on('issue', this._onClientIssue);
|
|
58
|
+
this.observedClient.on('metaData', this._onClientMetadata);
|
|
59
|
+
this.observedClient.on('joined', this._onClientJoined);
|
|
60
|
+
this.observedClient.on('left', this._onClientLeft);
|
|
61
|
+
this.observedClient.on('rejoined', this._onClientJoined);
|
|
62
|
+
this.observedClient.on('usermediaerror', this._onUserMediaError);
|
|
63
|
+
this.observedClient.on('usingturn', this._onUsingTurn);
|
|
64
|
+
|
|
65
|
+
this.observedClient.once('close', this._onClientClosed);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public onClientClosed?: (client: ObservedClient, ctx: Context) => void;
|
|
69
|
+
private _onClientClosed() {
|
|
70
|
+
this.onClientClosed?.(this.observedClient, this.context);
|
|
71
|
+
|
|
72
|
+
this.observedClient.off('newpeerconnection', this._onPeerConnconnectionAdded);
|
|
73
|
+
this.observedClient.off('issue', this._onClientIssue);
|
|
74
|
+
this.observedClient.off('metaData', this._onClientMetadata);
|
|
75
|
+
this.observedClient.off('joined', this._onClientJoined);
|
|
76
|
+
this.observedClient.off('left', this._onClientLeft);
|
|
77
|
+
this.observedClient.off('rejoined', this._onClientJoined);
|
|
78
|
+
this.observedClient.off('usermediaerror', this._onUserMediaError);
|
|
79
|
+
this.observedClient.off('usingturn', this._onUsingTurn);
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public onPeerConnectionAdded?: (peerConnection: ObservedPeerConnection, ctx: Context) => void;
|
|
84
|
+
private _onPeerConnconnectionAdded(peerConnection: ObservedPeerConnection) {
|
|
85
|
+
this.onPeerConnectionAdded?.(peerConnection, this.context);
|
|
86
|
+
|
|
87
|
+
peerConnection.once('close', () => this._onPeerConnectionRemoved(peerConnection));
|
|
88
|
+
|
|
89
|
+
peerConnection.on('added-certificate', this._onCertificateAdded);
|
|
90
|
+
peerConnection.on('removed-certificate', this._onCertificateRemoved);
|
|
91
|
+
peerConnection.on('added-inbound-track', this._onInboundTrackAdded);
|
|
92
|
+
peerConnection.on('removed-inbound-track', this._onInboundTrackRemoved);
|
|
93
|
+
peerConnection.on('added-outbound-track', this._onOutboundTrackAdded);
|
|
94
|
+
peerConnection.on('removed-outbound-track', this._onOutboundTrackRemoved);
|
|
95
|
+
peerConnection.on('added-inbound-rtp', this._onInboundRtpAdded);
|
|
96
|
+
peerConnection.on('removed-inbound-rtp', this._onInboundRtpRemoved);
|
|
97
|
+
peerConnection.on('added-outbound-rtp', this._onOutboundRtpAdded);
|
|
98
|
+
peerConnection.on('removed-outbound-rtp', this._onOutboundRtpRemoved);
|
|
99
|
+
peerConnection.on('added-data-channel', this._onDataChannelAdded);
|
|
100
|
+
peerConnection.on('removed-data-channel', this._onDataChannelRemoved);
|
|
101
|
+
peerConnection.on('added-ice-transport', this._onAddedIceTransport);
|
|
102
|
+
peerConnection.on('removed-ice-transport', this._onRemovedIceTransport);
|
|
103
|
+
peerConnection.on('added-ice-candidate', this._onIceCandidateAdded);
|
|
104
|
+
peerConnection.on('removed-ice-candidate', this._onIceCandidateRemoved);
|
|
105
|
+
peerConnection.on('added-ice-candidate-pair', this._onAddedIceCandidatePair);
|
|
106
|
+
peerConnection.on('removed-ice-candidate-pair', this._onRemovedIceCandidatePair);
|
|
107
|
+
peerConnection.on('added-codec', this._onAddedMediaCodec);
|
|
108
|
+
peerConnection.on('removed-codec', this._onRemovedMediaCodec);
|
|
109
|
+
peerConnection.on('added-media-playout', this._onAddedMediaPlayout);
|
|
110
|
+
peerConnection.on('removed-media-playout', this._onRemovedMediaPlayout);
|
|
111
|
+
peerConnection.on('added-media-source', this._onMediaSourceAdded);
|
|
112
|
+
peerConnection.on('removed-media-source', this._onMediaSourceRemoved);
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public onPeerConnectionRemoved?: (peerConnection: ObservedPeerConnection, ctx: Context) => void;
|
|
117
|
+
private _onPeerConnectionRemoved(peerConnection: ObservedPeerConnection) {
|
|
118
|
+
this.onPeerConnectionRemoved?.(peerConnection, this.context);
|
|
119
|
+
|
|
120
|
+
peerConnection.off('added-certificate', this._onCertificateAdded);
|
|
121
|
+
peerConnection.off('removed-certificate', this._onCertificateRemoved);
|
|
122
|
+
peerConnection.off('added-inbound-track', this._onInboundTrackAdded);
|
|
123
|
+
peerConnection.off('removed-inbound-track', this._onInboundTrackRemoved);
|
|
124
|
+
peerConnection.off('added-outbound-track', this._onOutboundTrackAdded);
|
|
125
|
+
peerConnection.off('removed-outbound-track', this._onOutboundTrackRemoved);
|
|
126
|
+
peerConnection.off('added-inbound-rtp', this._onInboundRtpAdded);
|
|
127
|
+
peerConnection.off('removed-inbound-rtp', this._onInboundRtpRemoved);
|
|
128
|
+
peerConnection.off('added-outbound-rtp', this._onOutboundRtpAdded);
|
|
129
|
+
peerConnection.off('removed-outbound-rtp', this._onOutboundRtpRemoved);
|
|
130
|
+
peerConnection.off('added-data-channel', this._onDataChannelAdded);
|
|
131
|
+
peerConnection.off('removed-data-channel', this._onDataChannelRemoved);
|
|
132
|
+
peerConnection.off('added-ice-transport', this._onAddedIceTransport);
|
|
133
|
+
peerConnection.off('removed-ice-transport', this._onRemovedIceTransport);
|
|
134
|
+
peerConnection.off('added-ice-candidate', this._onIceCandidateAdded);
|
|
135
|
+
peerConnection.off('removed-ice-candidate', this._onIceCandidateRemoved);
|
|
136
|
+
peerConnection.off('added-ice-candidate-pair', this._onAddedIceCandidatePair);
|
|
137
|
+
peerConnection.off('removed-ice-candidate-pair', this._onRemovedIceCandidatePair);
|
|
138
|
+
peerConnection.off('added-codec', this._onAddedMediaCodec);
|
|
139
|
+
peerConnection.off('removed-codec', this._onRemovedMediaCodec);
|
|
140
|
+
peerConnection.off('added-media-playout', this._onAddedMediaPlayout);
|
|
141
|
+
peerConnection.off('removed-media-playout', this._onRemovedMediaPlayout);
|
|
142
|
+
peerConnection.off('added-media-source', this._onMediaSourceAdded);
|
|
143
|
+
peerConnection.off('removed-media-source', this._onMediaSourceRemoved);
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public onCertificateAdded?: (certificate: ObservedCertificate, ctx: Context) => void;
|
|
148
|
+
private _onCertificateAdded(certificate: ObservedCertificate) {
|
|
149
|
+
this.onCertificateAdded?.(certificate, this.context);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public onCertificateRemoved?: (certificate: ObservedCertificate, ctx: Context) => void;
|
|
153
|
+
private _onCertificateRemoved(certificate: ObservedCertificate) {
|
|
154
|
+
this.onCertificateRemoved?.(certificate, this.context);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public onInboundTrackAdded?: (inboundTrack: ObservedInboundTrack, ctx: Context) => void;
|
|
158
|
+
private _onInboundTrackAdded(inboundTrack: ObservedInboundTrack) {
|
|
159
|
+
this.onInboundTrackAdded?.(inboundTrack, this.context);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public onInboundTrackRemoved?: (inboundTrack: ObservedInboundTrack, ctx: Context) => void;
|
|
163
|
+
private _onInboundTrackRemoved(inboundTrack: ObservedInboundTrack) {
|
|
164
|
+
this.onInboundTrackRemoved?.(inboundTrack, this.context);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public onOutboundTrackAdded?: (outboundTrack: ObservedOutboundTrack, ctx: Context) => void;
|
|
168
|
+
private _onOutboundTrackAdded(outboundTrack: ObservedOutboundTrack) {
|
|
169
|
+
this.onOutboundTrackAdded?.(outboundTrack, this.context);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public onOutboundTrackRemoved?: (outboundTrack: ObservedOutboundTrack, ctx: Context) => void;
|
|
173
|
+
private _onOutboundTrackRemoved(outboundTrack: ObservedOutboundTrack) {
|
|
174
|
+
this.onOutboundTrackRemoved?.(outboundTrack, this.context);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public onInboundRtpAdded?: (inboundRtp: ObservedInboundRtp, ctx: Context) => void;
|
|
178
|
+
private _onInboundRtpAdded(inboundRtp: ObservedInboundRtp) {
|
|
179
|
+
this.onInboundRtpAdded?.(inboundRtp, this.context);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public onInboundRtpRemoved?: (inboundRtp: ObservedInboundRtp, ctx: Context) => void;
|
|
183
|
+
private _onInboundRtpRemoved(inboundRtp: ObservedInboundRtp) {
|
|
184
|
+
this.onInboundRtpRemoved?.(inboundRtp, this.context);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public onOutboundRtpAdded?: (outboundRtp: ObservedOutboundRtp, ctx: Context) => void;
|
|
188
|
+
private _onOutboundRtpAdded(outboundRtp: ObservedOutboundRtp) {
|
|
189
|
+
this.onOutboundRtpAdded?.(outboundRtp, this.context);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
public onOutboundRtpRemoved?: (outboundRtp: ObservedOutboundRtp, ctx: Context) => void;
|
|
193
|
+
private _onOutboundRtpRemoved(outboundRtp: ObservedOutboundRtp) {
|
|
194
|
+
this.onOutboundRtpRemoved?.(outboundRtp, this.context);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
public onDataChannelAdded?: (dataChannel: ObservedDataChannel, ctx: Context) => void;
|
|
198
|
+
private _onDataChannelAdded(dataChannel: ObservedDataChannel) {
|
|
199
|
+
this.onDataChannelAdded?.(dataChannel, this.context);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public onDataChannelRemoved?: (dataChannel: ObservedDataChannel, ctx: Context) => void;
|
|
203
|
+
private _onDataChannelRemoved(dataChannel: ObservedDataChannel) {
|
|
204
|
+
this.onDataChannelRemoved?.(dataChannel, this.context);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public onAddedIceTransport?: (iceTransport: ObservedIceTransport, ctx: Context) => void;
|
|
208
|
+
private _onAddedIceTransport(iceTransport: ObservedIceTransport) {
|
|
209
|
+
this.onAddedIceTransport?.(iceTransport, this.context);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public onRemovedIceTransport?: (iceTransport: ObservedIceTransport, ctx: Context) => void;
|
|
213
|
+
private _onRemovedIceTransport(iceTransport: ObservedIceTransport) {
|
|
214
|
+
this.onRemovedIceTransport?.(iceTransport, this.context);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
public onIceCandidateAdded?: (iceCandidate: ObservedIceCandidate, ctx: Context) => void;
|
|
218
|
+
private _onIceCandidateAdded(iceCandidate: ObservedIceCandidate) {
|
|
219
|
+
this.onIceCandidateAdded?.(iceCandidate, this.context);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
public onIceCandidateRemoved?: (iceCandidate: ObservedIceCandidate, ctx: Context) => void;
|
|
223
|
+
private _onIceCandidateRemoved(iceCandidate: ObservedIceCandidate) {
|
|
224
|
+
this.onIceCandidateRemoved?.(iceCandidate, this.context);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
public onAddedIceCandidatePair?: (candidatePair: ObservedIceCandidatePair, ctx: Context) => void;
|
|
228
|
+
private _onAddedIceCandidatePair(candidatePair: ObservedIceCandidatePair) {
|
|
229
|
+
this.onAddedIceCandidatePair?.(candidatePair, this.context);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
public onRemovedIceCandidatePair?: (candidatePair: ObservedIceCandidatePair, ctx: Context) => void;
|
|
233
|
+
private _onRemovedIceCandidatePair(candidatePair: ObservedIceCandidatePair) {
|
|
234
|
+
this.onRemovedIceCandidatePair?.(candidatePair, this.context);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
public onAddedMediaCodec?: (codec: ObservedCodec, ctx: Context) => void;
|
|
238
|
+
private _onAddedMediaCodec(codec: ObservedCodec) {
|
|
239
|
+
this.onAddedMediaCodec?.(codec, this.context);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public onRemovedMediaCodec?: (codec: ObservedCodec, ctx: Context) => void;
|
|
243
|
+
private _onRemovedMediaCodec(codec: ObservedCodec) {
|
|
244
|
+
this.onRemovedMediaCodec?.(codec, this.context);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
public onAddedMediaPlayout?: (mediaPlayout: ObservedMediaPlayout, ctx: Context) => void;
|
|
248
|
+
private _onAddedMediaPlayout(mediaPlayout: ObservedMediaPlayout) {
|
|
249
|
+
this.onAddedMediaPlayout?.(mediaPlayout, this.context);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
public onRemovedMediaPlayout?: (mediaPlayout: ObservedMediaPlayout, ctx: Context) => void;
|
|
253
|
+
private _onRemovedMediaPlayout(mediaPlayout: ObservedMediaPlayout) {
|
|
254
|
+
this.onRemovedMediaPlayout?.(mediaPlayout, this.context);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
public onMediaSourceAdded?: (mediaSource: ObservedMediaSource, ctx: Context) => void;
|
|
258
|
+
private _onMediaSourceAdded(mediaSource: ObservedMediaSource) {
|
|
259
|
+
this.onMediaSourceAdded?.(mediaSource, this.context);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
public onMediaSourceRemoved?: (mediaSource: ObservedMediaSource, ctx: Context) => void;
|
|
263
|
+
private _onMediaSourceRemoved(mediaSource: ObservedMediaSource) {
|
|
264
|
+
this.onMediaSourceRemoved?.(mediaSource, this.context);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
public onClientIssue?: (issue: ClientIssue, ctx: Context) => void;
|
|
268
|
+
private _onClientIssue(issue: ClientIssue) {
|
|
269
|
+
this.onClientIssue?.(issue, this.context);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
public onClientMetadata?: (metadata: ClientMetaData, ctx: Context) => void;
|
|
273
|
+
private _onClientMetadata(metadata: ClientMetaData) {
|
|
274
|
+
this.onClientMetadata?.(metadata, this.context);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
public onClientExtensionStats?: (extensionStats: ExtensionStat, ctx: Context) => void;
|
|
278
|
+
private _onClientExtensionStats(extensionStats: ExtensionStat) {
|
|
279
|
+
this.onClientExtensionStats?.(extensionStats, this.context);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
public onClientJoined?: (client: ObservedClient, ctx: Context) => void;
|
|
283
|
+
private _onClientJoined() {
|
|
284
|
+
this.onClientJoined?.(this.observedClient, this.context);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
public onClientLeft?: (client: ObservedClient, ctx: Context) => void;
|
|
288
|
+
private _onClientLeft() {
|
|
289
|
+
this.onClientLeft?.(this.observedClient, this.context);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
public onUserMediaError?: (error: string, observedClient: ObservedClient, ctx: Context) => void;
|
|
293
|
+
private _onUserMediaError(error: string) {
|
|
294
|
+
this.onUserMediaError?.(error, this.observedClient, this.context);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
public onUsingTurn?: (client: ObservedClient, ctx: Context) => void;
|
|
298
|
+
private _onUsingTurn() {
|
|
299
|
+
this.onUsingTurn?.(this.observedClient, this.context);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
@@ -16,6 +16,9 @@ export class ObservedDataChannel implements DataChannelStats {
|
|
|
16
16
|
bytesReceived?: number | undefined;
|
|
17
17
|
attachments?: Record<string, unknown> | undefined;
|
|
18
18
|
|
|
19
|
+
public addedAt?: number | undefined;
|
|
20
|
+
public removedAt?: number | undefined;
|
|
21
|
+
|
|
19
22
|
public deltaBytesSent = 0;
|
|
20
23
|
public deltaBytesReceived = 0;
|
|
21
24
|
public deltaMessagesSent = 0;
|
|
@@ -8,7 +8,7 @@ export class ObservedIceCandidatePair implements IceCandidatePairStats {
|
|
|
8
8
|
transportId?: string | undefined;
|
|
9
9
|
localCandidateId?: string | undefined;
|
|
10
10
|
remoteCandidateId?: string | undefined;
|
|
11
|
-
state?: 'new' | '
|
|
11
|
+
state?: 'new' | 'in-progress' | 'waiting' | 'failed' | 'succeeded' | undefined;
|
|
12
12
|
nominated?: boolean | undefined;
|
|
13
13
|
packetsSent?: number | undefined;
|
|
14
14
|
packetsReceived?: number | undefined;
|
|
@@ -93,7 +93,7 @@ export class ObservedIceCandidatePair implements IceCandidatePairStats {
|
|
|
93
93
|
this.transportId = stats.transportId;
|
|
94
94
|
this.localCandidateId = stats.localCandidateId;
|
|
95
95
|
this.remoteCandidateId = stats.remoteCandidateId;
|
|
96
|
-
this.state = stats.state;
|
|
96
|
+
this.state = this._convertState(stats.state);
|
|
97
97
|
this.nominated = stats.nominated;
|
|
98
98
|
this.packetsSent = stats.packetsSent;
|
|
99
99
|
this.packetsReceived = stats.packetsReceived;
|
|
@@ -115,4 +115,20 @@ export class ObservedIceCandidatePair implements IceCandidatePairStats {
|
|
|
115
115
|
this.attachments = stats.attachments;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
private _convertState(state: string | undefined) {
|
|
119
|
+
switch (state) {
|
|
120
|
+
case 'new':
|
|
121
|
+
case 'in-progress':
|
|
122
|
+
case 'waiting':
|
|
123
|
+
case 'failed':
|
|
124
|
+
case 'succeeded':
|
|
125
|
+
return state;
|
|
126
|
+
case 'cancelled':
|
|
127
|
+
return 'failed';
|
|
128
|
+
case 'inprogress':
|
|
129
|
+
return 'in-progress';
|
|
130
|
+
default:
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
118
134
|
}
|
|
@@ -16,6 +16,9 @@ export class ObservedInboundTrack implements InboundTrackSample {
|
|
|
16
16
|
|
|
17
17
|
private _visited = false;
|
|
18
18
|
|
|
19
|
+
public addedAt?: number | undefined;
|
|
20
|
+
public removedAt?: number | undefined;
|
|
21
|
+
|
|
19
22
|
attachments?: Record<string, unknown> | undefined;
|
|
20
23
|
|
|
21
24
|
constructor(
|
|
@@ -280,6 +280,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
280
280
|
|
|
281
281
|
this.client.call.observer.observedTURN.removePeerConnection(this);
|
|
282
282
|
|
|
283
|
+
if (!this.closedAt) this.closedAt = Date.now();
|
|
284
|
+
|
|
283
285
|
this.emit('close');
|
|
284
286
|
}
|
|
285
287
|
|
|
@@ -302,7 +304,9 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
302
304
|
this.deltaReceivedVideoPackets = 0;
|
|
303
305
|
this.deltaSentAudioBytes = 0;
|
|
304
306
|
this.deltaSentVideoBytes = 0;
|
|
305
|
-
|
|
307
|
+
this.deltaTransportReceivedBytes = 0;
|
|
308
|
+
this.deltaTransportSentBytes = 0;
|
|
309
|
+
|
|
306
310
|
this.sendingAudioBitrate = 0;
|
|
307
311
|
this.sendingVideoBitrate = 0;
|
|
308
312
|
this.receivingAudioBitrate = 0;
|
|
@@ -428,7 +432,10 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
428
432
|
}
|
|
429
433
|
if (sample.peerConnectionTransports) {
|
|
430
434
|
for (const peerConnectionTransport of sample.peerConnectionTransports) {
|
|
431
|
-
this._updatePeerConnectionTransportStats(peerConnectionTransport);
|
|
435
|
+
const observedTransport = this._updatePeerConnectionTransportStats(peerConnectionTransport);
|
|
436
|
+
|
|
437
|
+
if (!observedTransport) continue;
|
|
438
|
+
|
|
432
439
|
}
|
|
433
440
|
}
|
|
434
441
|
if (sample.remoteInboundRtps) {
|
|
@@ -496,16 +503,24 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
496
503
|
} else {
|
|
497
504
|
this.currentJitter = undefined;
|
|
498
505
|
}
|
|
499
|
-
|
|
500
|
-
const selectedIceCandidatePairs = this.selectedIceCandidatePairs;
|
|
501
|
-
const selectedCandidatePairForTurn = selectedIceCandidatePairs.filter((pair) =>
|
|
502
|
-
pair.getLocalCandidate()?.candidateType === 'relay' &&
|
|
503
|
-
pair.getRemoteCandidate()?.url?.startsWith('turn:')
|
|
504
|
-
);
|
|
505
506
|
const wasUsingTURN = this.usingTURN;
|
|
507
|
+
const selectedIceCandidatePairs = this.selectedIceCandidatePairs;
|
|
508
|
+
const selectedCandidatePairForTurn: ObservedIceCandidatePair[] = [];
|
|
509
|
+
|
|
510
|
+
this.usingTCP = false;
|
|
511
|
+
this.usingTURN = false;
|
|
506
512
|
|
|
507
|
-
|
|
508
|
-
|
|
513
|
+
for (const selectedCandidatePair of selectedIceCandidatePairs) {
|
|
514
|
+
if (selectedCandidatePair.getLocalCandidate()?.protocol === 'tcp') {
|
|
515
|
+
this.usingTCP = true;
|
|
516
|
+
}
|
|
517
|
+
if (selectedCandidatePair.getLocalCandidate()?.candidateType === 'relay' && selectedCandidatePair.getRemoteCandidate()?.url?.startsWith('turn:')) {
|
|
518
|
+
selectedCandidatePairForTurn.push(selectedCandidatePair);
|
|
519
|
+
this.usingTURN = true;
|
|
520
|
+
}
|
|
521
|
+
this.deltaTransportReceivedBytes += selectedCandidatePair.deltaBytesReceived;
|
|
522
|
+
this.deltaTransportSentBytes += selectedCandidatePair.deltaBytesSent;
|
|
523
|
+
}
|
|
509
524
|
|
|
510
525
|
if (this.usingTURN) {
|
|
511
526
|
if (!this.observedTurnServer) {
|
package/src/Observer.ts
CHANGED
|
@@ -7,9 +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/
|
|
11
|
-
import { OnAnyCallObserverUpdater } from './updaters/
|
|
12
|
-
import {
|
|
10
|
+
import { OnAllCallObserverUpdater } from './updaters/OnAllCallObserverUpdater';
|
|
11
|
+
import { OnAnyCallObserverUpdater } from './updaters/OnAnyCallObserverUpdater';
|
|
12
|
+
import { ObserverEventMonitor } from './ObserverEventMonitor';
|
|
13
|
+
import { MediasoupRemoteTrackResolver } from './utils/MediasoupRemoteTrackResolver';
|
|
13
14
|
|
|
14
15
|
const logger = createLogger('Observer');
|
|
15
16
|
|
|
@@ -24,11 +25,12 @@ export type ObserverEvents = {
|
|
|
24
25
|
'close': [],
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
export type ObserverConfig = {
|
|
28
|
+
export type ObserverConfig<AppData extends Record<string, unknown> = Record<string, unknown>> = {
|
|
28
29
|
updatePolicy?: 'update-on-any-call-updated' | 'update-when-all-call-updated' | 'update-on-interval',
|
|
29
30
|
updateIntervalInMs?: number,
|
|
30
31
|
defaultCallUpdatePolicy?: ObservedCallSettings['updatePolicy'],
|
|
31
32
|
defaultCallUpdateIntervalInMs?: number,
|
|
33
|
+
appData?: AppData,
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
export declare interface Observer {
|
|
@@ -38,7 +40,7 @@ export declare interface Observer {
|
|
|
38
40
|
emit<U extends keyof ObserverEvents>(event: U, ...args: ObserverEvents[U]): boolean;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
export class Observer extends EventEmitter {
|
|
43
|
+
export class Observer<AppData extends Record<string, unknown> = Record<string, unknown>> extends EventEmitter {
|
|
42
44
|
public readonly detectors: Detectors;
|
|
43
45
|
|
|
44
46
|
public readonly observedTURN = new ObservedTURN();
|
|
@@ -55,6 +57,7 @@ export class Observer extends EventEmitter {
|
|
|
55
57
|
public totalRttGtOrEq300Measurements = 0;
|
|
56
58
|
public totalClientIssues = 0;
|
|
57
59
|
|
|
60
|
+
public numberOfClientsUsingTurn = 0;
|
|
58
61
|
public numberOfClients = 0;
|
|
59
62
|
public numberOfInboundRtpStreams = 0;
|
|
60
63
|
public numberOfOutboundRtpStreams = 0;
|
|
@@ -67,9 +70,10 @@ export class Observer extends EventEmitter {
|
|
|
67
70
|
|
|
68
71
|
private _timer?: ReturnType<typeof setInterval>;
|
|
69
72
|
|
|
70
|
-
public constructor(public readonly config: ObserverConfig = {
|
|
73
|
+
public constructor(public readonly config: ObserverConfig<AppData> = {
|
|
71
74
|
updatePolicy: 'update-when-all-call-updated',
|
|
72
75
|
updateIntervalInMs: undefined,
|
|
76
|
+
appData: {} as AppData,
|
|
73
77
|
}) {
|
|
74
78
|
super();
|
|
75
79
|
this.setMaxListeners(Infinity);
|
|
@@ -108,6 +112,10 @@ export class Observer extends EventEmitter {
|
|
|
108
112
|
this.detectors = new Detectors();
|
|
109
113
|
}
|
|
110
114
|
|
|
115
|
+
public get appData() {
|
|
116
|
+
return this.config.appData;
|
|
117
|
+
}
|
|
118
|
+
|
|
111
119
|
public getObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(callId: string): ObservedCall<T> | undefined {
|
|
112
120
|
if (this.closed || !this.observedCalls.has(callId)) return;
|
|
113
121
|
|
|
@@ -124,12 +132,15 @@ export class Observer extends EventEmitter {
|
|
|
124
132
|
settings.updatePolicy = this.config.defaultCallUpdatePolicy;
|
|
125
133
|
settings.updateIntervalInMs = this.config.defaultCallUpdateIntervalInMs;
|
|
126
134
|
}
|
|
127
|
-
|
|
128
135
|
const observedCall = new ObservedCall(settings, this);
|
|
129
136
|
const onCallUpdated = () => this._onObservedCallUpdated(observedCall);
|
|
130
137
|
|
|
131
138
|
if (this.observedCalls.has(observedCall.callId)) throw new Error(`Observed Call with id ${observedCall.callId} already exists`);
|
|
132
139
|
|
|
140
|
+
if (settings.remoteTrackResolvePolicy === 'mediasoup-sfu') {
|
|
141
|
+
observedCall.remoteTrackResolver = new MediasoupRemoteTrackResolver(observedCall);
|
|
142
|
+
}
|
|
143
|
+
|
|
133
144
|
observedCall.once('close', () => {
|
|
134
145
|
this.observedCalls.delete(observedCall.callId);
|
|
135
146
|
observedCall.off('update', onCallUpdated);
|
|
@@ -186,6 +197,7 @@ export class Observer extends EventEmitter {
|
|
|
186
197
|
this.numberOfPeerConnections = 0;
|
|
187
198
|
this.numberOfDataChannels = 0;
|
|
188
199
|
this.numberOfClients = 0;
|
|
200
|
+
this.numberOfClientsUsingTurn = 0;
|
|
189
201
|
|
|
190
202
|
for (const call of this.observedCalls.values()) {
|
|
191
203
|
this.numberOfInboundRtpStreams += call.numberOfInboundRtpStreams;
|
|
@@ -193,6 +205,7 @@ export class Observer extends EventEmitter {
|
|
|
193
205
|
this.numberOfPeerConnections += call.numberOfPeerConnections;
|
|
194
206
|
this.numberOfDataChannels += call.numberOfDataChannels;
|
|
195
207
|
this.numberOfClients += call.numberOfClients;
|
|
208
|
+
this.numberOfClientsUsingTurn += call.clientsUsedTurn.size;
|
|
196
209
|
}
|
|
197
210
|
|
|
198
211
|
this.observedTURN.update();
|
|
@@ -208,29 +221,34 @@ export class Observer extends EventEmitter {
|
|
|
208
221
|
this.totalClientIssues += call.deltaNumberOfIssues;
|
|
209
222
|
}
|
|
210
223
|
|
|
211
|
-
public
|
|
212
|
-
this
|
|
213
|
-
this.totalRemovedCall = 0;
|
|
214
|
-
this.totalRttLt50Measurements = 0;
|
|
215
|
-
this.totalRttLt150Measurements = 0;
|
|
216
|
-
this.totalRttLt300Measurements = 0;
|
|
217
|
-
this.totalRttGtOrEq300Measurements = 0;
|
|
218
|
-
this.totalClientIssues = 0;
|
|
224
|
+
public createEventMonitor<CTX = unknown>(ctx?: CTX): ObserverEventMonitor<CTX> {
|
|
225
|
+
return new ObserverEventMonitor<CTX>(this, ctx ?? {} as CTX);
|
|
219
226
|
}
|
|
220
227
|
|
|
221
|
-
public
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
228
|
+
// public resetSummaryMetrics() {
|
|
229
|
+
// this.totalAddedCall = 0;
|
|
230
|
+
// this.totalRemovedCall = 0;
|
|
231
|
+
// this.totalRttLt50Measurements = 0;
|
|
232
|
+
// this.totalRttLt150Measurements = 0;
|
|
233
|
+
// this.totalRttLt300Measurements = 0;
|
|
234
|
+
// this.totalRttGtOrEq300Measurements = 0;
|
|
235
|
+
// this.totalClientIssues = 0;
|
|
236
|
+
// }
|
|
237
|
+
|
|
238
|
+
// public createSummary(): ObserverSummary {
|
|
239
|
+
// return {
|
|
240
|
+
// totalAddedCall: this.totalAddedCall,
|
|
241
|
+
// totalRemovedCall: this.totalRemovedCall,
|
|
242
|
+
// totalRttLt50Measurements: this.totalRttLt50Measurements,
|
|
243
|
+
// totalRttLt150Measurements: this.totalRttLt150Measurements,
|
|
244
|
+
// totalRttLt300Measurements: this.totalRttLt300Measurements,
|
|
245
|
+
// totalRttGtOrEq300Measurements: this.totalRttGtOrEq300Measurements,
|
|
246
|
+
|
|
247
|
+
// totalClientIssues: this.totalClientIssues,
|
|
248
|
+
// currentActiveCalls: this.observedCalls.size,
|
|
249
|
+
// currentNumberOfClients: this.numberOfClients,
|
|
250
|
+
// currentNumberOfClientsUsingTURN: this.numberOfClientsUsedTurn,
|
|
251
|
+
// };
|
|
252
|
+
// }
|
|
235
253
|
|
|
236
254
|
}
|