@observertc/observer-js 1.0.0-beta.5 → 1.0.0-beta.7
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/README.md +100 -51
- package/dist/index.d.mts +102 -126
- package/dist/index.d.ts +102 -126
- package/dist/index.js +188 -288
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +185 -288
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -55,10 +55,13 @@ __export(src_exports, {
|
|
|
55
55
|
ObservedRemoteInboundRtp: () => ObservedRemoteInboundRtp,
|
|
56
56
|
ObservedRemoteOutboundRtp: () => ObservedRemoteOutboundRtp,
|
|
57
57
|
Observer: () => Observer,
|
|
58
|
+
RemoteTrackResolver: () => RemoteTrackResolver,
|
|
59
|
+
createDefaultMediasoupRemoteTrackResolverFactory: () => createDefaultMediasoupRemoteTrackResolverFactory,
|
|
58
60
|
createInMemorySink: () => createInMemorySink,
|
|
59
61
|
createJsonlFileSink: () => createJsonlFileSink,
|
|
60
62
|
createJsonlFileSinkFactory: () => createJsonlFileSinkFactory,
|
|
61
63
|
createLogger: () => createLogger,
|
|
64
|
+
createP2pRemoteTrackResolverFactory: () => createP2pRemoteTrackResolverFactory,
|
|
62
65
|
setObserverLogger: () => setObserverLogger
|
|
63
66
|
});
|
|
64
67
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -1128,20 +1131,6 @@ var ObservedInboundTrack = class {
|
|
|
1128
1131
|
this._peerConnection = _peerConnection;
|
|
1129
1132
|
this._inboundRtp = _inboundRtp;
|
|
1130
1133
|
this._mediaPlayout = _mediaPlayout;
|
|
1131
|
-
this.report = {
|
|
1132
|
-
trackId: this.id,
|
|
1133
|
-
kind: this.kind,
|
|
1134
|
-
fractionLostDistribution: {
|
|
1135
|
-
gtOrEq050: 0,
|
|
1136
|
-
lt001: 0,
|
|
1137
|
-
lt005: 0,
|
|
1138
|
-
lt010: 0,
|
|
1139
|
-
lt020: 0,
|
|
1140
|
-
lt050: 0,
|
|
1141
|
-
count: 0,
|
|
1142
|
-
sum: 0
|
|
1143
|
-
}
|
|
1144
|
-
};
|
|
1145
1134
|
}
|
|
1146
1135
|
timestamp;
|
|
1147
1136
|
id;
|
|
@@ -1154,7 +1143,7 @@ var ObservedInboundTrack = class {
|
|
|
1154
1143
|
value: void 0
|
|
1155
1144
|
};
|
|
1156
1145
|
appData;
|
|
1157
|
-
|
|
1146
|
+
remoteOutboundTrack;
|
|
1158
1147
|
_visited = false;
|
|
1159
1148
|
addedAt;
|
|
1160
1149
|
removedAt;
|
|
@@ -1177,25 +1166,11 @@ var ObservedInboundTrack = class {
|
|
|
1177
1166
|
getMediaPlayout() {
|
|
1178
1167
|
return this._mediaPlayout;
|
|
1179
1168
|
}
|
|
1180
|
-
getRemoteOutboundTrack() {
|
|
1181
|
-
return this._peerConnection.client.call.remoteTrackResolver?.resolveRemoteOutboundTrack(this);
|
|
1182
|
-
}
|
|
1183
1169
|
update(stats) {
|
|
1184
1170
|
this._visited = true;
|
|
1185
1171
|
this.timestamp = stats.timestamp;
|
|
1186
1172
|
this.calculatedScore.value = stats.score;
|
|
1187
1173
|
this.attachments = stats.attachments;
|
|
1188
|
-
const fl = this._inboundRtp?.fractionLost;
|
|
1189
|
-
if (fl !== void 0) {
|
|
1190
|
-
if (fl < 0.01) this.report.fractionLostDistribution.lt001 += 1;
|
|
1191
|
-
else if (fl < 0.05) this.report.fractionLostDistribution.lt005 += 1;
|
|
1192
|
-
else if (fl < 0.1) this.report.fractionLostDistribution.lt010 += 1;
|
|
1193
|
-
else if (fl < 0.2) this.report.fractionLostDistribution.lt020 += 1;
|
|
1194
|
-
else if (fl < 0.5) this.report.fractionLostDistribution.lt050 += 1;
|
|
1195
|
-
else this.report.fractionLostDistribution.gtOrEq050 += 1;
|
|
1196
|
-
this.report.fractionLostDistribution.count += 1;
|
|
1197
|
-
this.report.fractionLostDistribution.sum += fl;
|
|
1198
|
-
}
|
|
1199
1174
|
}
|
|
1200
1175
|
};
|
|
1201
1176
|
|
|
@@ -1208,10 +1183,6 @@ var ObservedOutboundTrack = class {
|
|
|
1208
1183
|
this._peerConnection = _peerConnection;
|
|
1209
1184
|
this._outboundRtps = _outboundRtps;
|
|
1210
1185
|
this._mediaSource = _mediaSource;
|
|
1211
|
-
this.report = {
|
|
1212
|
-
trackId: this.id,
|
|
1213
|
-
kind: this.kind
|
|
1214
|
-
};
|
|
1215
1186
|
}
|
|
1216
1187
|
timestamp;
|
|
1217
1188
|
id;
|
|
@@ -1221,7 +1192,7 @@ var ObservedOutboundTrack = class {
|
|
|
1221
1192
|
_mediaSource;
|
|
1222
1193
|
_visited = false;
|
|
1223
1194
|
appData;
|
|
1224
|
-
|
|
1195
|
+
remoteInboundTracks = /* @__PURE__ */ new Set();
|
|
1225
1196
|
calculatedScore = {
|
|
1226
1197
|
weight: 1,
|
|
1227
1198
|
value: void 0
|
|
@@ -1247,9 +1218,6 @@ var ObservedOutboundTrack = class {
|
|
|
1247
1218
|
getMediaSource() {
|
|
1248
1219
|
return this._mediaSource;
|
|
1249
1220
|
}
|
|
1250
|
-
getRemoteInboundTracks() {
|
|
1251
|
-
return this._peerConnection.client.call.remoteTrackResolver?.resolveRemoteInboundTracks(this);
|
|
1252
|
-
}
|
|
1253
1221
|
update(stats) {
|
|
1254
1222
|
this._visited = true;
|
|
1255
1223
|
this.timestamp = stats.timestamp;
|
|
@@ -2209,43 +2177,6 @@ var ObservedClient = class extends import_events2.EventEmitter {
|
|
|
2209
2177
|
this.settings = {
|
|
2210
2178
|
closeClientIfIdleForMs: settings.closeClientIfIdleForMs
|
|
2211
2179
|
};
|
|
2212
|
-
this.report = {
|
|
2213
|
-
callId: this.call.callId,
|
|
2214
|
-
clientId: this.clientId,
|
|
2215
|
-
rttDistribution: {
|
|
2216
|
-
gtOrEq300ms: 0,
|
|
2217
|
-
lt50ms: 0,
|
|
2218
|
-
lt150ms: 0,
|
|
2219
|
-
lt300ms: 0,
|
|
2220
|
-
count: 0,
|
|
2221
|
-
sum: 0
|
|
2222
|
-
},
|
|
2223
|
-
scoreDistribution: {
|
|
2224
|
-
"0": 0,
|
|
2225
|
-
"1": 0,
|
|
2226
|
-
"2": 0,
|
|
2227
|
-
"3": 0,
|
|
2228
|
-
"4": 0,
|
|
2229
|
-
"5": 0,
|
|
2230
|
-
count: 0,
|
|
2231
|
-
sum: 0
|
|
2232
|
-
},
|
|
2233
|
-
issues: {},
|
|
2234
|
-
totalAudioBytesReceived: 0,
|
|
2235
|
-
totalVideoBytesReceived: 0,
|
|
2236
|
-
totalAudioBytesSent: 0,
|
|
2237
|
-
totalVideoBytesSent: 0,
|
|
2238
|
-
totalDataChannelBytesReceived: 0,
|
|
2239
|
-
totalDataChannelBytesSent: 0,
|
|
2240
|
-
totalDataChannelMessagesReceived: 0,
|
|
2241
|
-
totalDataChannelMessagesSent: 0,
|
|
2242
|
-
totalInboundRtpBytesReceived: 0,
|
|
2243
|
-
totalInboundRtpPacketsLost: 0,
|
|
2244
|
-
totalInboundRtpPacketsReceived: 0,
|
|
2245
|
-
totalOutboundRtpBytesSent: 0,
|
|
2246
|
-
totalOutboundRtpPacketsSent: 0,
|
|
2247
|
-
totalNumberOfIssues: 0
|
|
2248
|
-
};
|
|
2249
2180
|
if (this.sink) {
|
|
2250
2181
|
const onError = (err) => logger2.warn("ClientSampleSink error for client %s: %o", this.clientId, err);
|
|
2251
2182
|
this.sink.once("close", () => this.sink?.off("error", onError));
|
|
@@ -2316,7 +2247,6 @@ var ObservedClient = class extends import_events2.EventEmitter {
|
|
|
2316
2247
|
totalScoreSum = 0;
|
|
2317
2248
|
numberOfScoreMeasurements = 0;
|
|
2318
2249
|
// public totalNumberOfIssues = 0;
|
|
2319
|
-
report;
|
|
2320
2250
|
mediaDevices = [];
|
|
2321
2251
|
issues = [];
|
|
2322
2252
|
_injections = {};
|
|
@@ -2449,19 +2379,13 @@ var ObservedClient = class extends import_events2.EventEmitter {
|
|
|
2449
2379
|
}
|
|
2450
2380
|
if (observedPeerConnection.currentRttInMs < 50) {
|
|
2451
2381
|
this.deltaRttLt50Measurements += 1;
|
|
2452
|
-
this.report.rttDistribution.lt50ms += 1;
|
|
2453
2382
|
} else if (observedPeerConnection.currentRttInMs < 150) {
|
|
2454
2383
|
this.deltaRttLt150Measurements += 1;
|
|
2455
|
-
this.report.rttDistribution.lt150ms += 1;
|
|
2456
2384
|
} else if (observedPeerConnection.currentRttInMs < 300) {
|
|
2457
2385
|
this.deltaRttLt300Measurements += 1;
|
|
2458
|
-
this.report.rttDistribution.lt300ms += 1;
|
|
2459
2386
|
} else if (300 <= observedPeerConnection.currentRttInMs) {
|
|
2460
2387
|
this.deltaRttGtOrEq300Measurements += 1;
|
|
2461
|
-
this.report.rttDistribution.gtOrEq300ms += 1;
|
|
2462
2388
|
}
|
|
2463
|
-
this.report.rttDistribution.count += 1;
|
|
2464
|
-
this.report.rttDistribution.sum += observedPeerConnection.currentRttInMs;
|
|
2465
2389
|
sumOfRtts += observedPeerConnection.currentRttInMs;
|
|
2466
2390
|
++numberOfRttMeasurements;
|
|
2467
2391
|
}
|
|
@@ -2470,32 +2394,12 @@ var ObservedClient = class extends import_events2.EventEmitter {
|
|
|
2470
2394
|
this._processClientEvent(clientEvent);
|
|
2471
2395
|
}
|
|
2472
2396
|
this.attachments = sample.attachments;
|
|
2473
|
-
this.report.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
|
|
2474
|
-
this.report.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
|
|
2475
|
-
this.report.totalDataChannelMessagesReceived += this.deltaDataChannelMessagesReceived;
|
|
2476
|
-
this.report.totalDataChannelMessagesSent += this.deltaDataChannelMessagesSent;
|
|
2477
|
-
this.report.totalInboundRtpPacketsLost += this.deltaInboundPacketsLost;
|
|
2478
|
-
this.report.totalInboundRtpPacketsReceived += this.deltaInboundPacketsReceived;
|
|
2479
|
-
this.report.totalOutboundRtpPacketsSent += this.deltaOutboundPacketsSent;
|
|
2480
|
-
this.report.totalAudioBytesReceived += this.deltaReceivedAudioBytes;
|
|
2481
|
-
this.report.totalVideoBytesReceived += this.deltaReceivedVideoBytes;
|
|
2482
|
-
this.report.totalAudioBytesSent += this.deltaSentAudioBytes;
|
|
2483
|
-
this.report.totalVideoBytesSent += this.deltaSentVideoBytes;
|
|
2484
|
-
this.report.totalInboundRtpBytesReceived += this.deltaTransportReceivedBytes;
|
|
2485
|
-
this.report.totalOutboundRtpBytesSent += this.deltaTransportSentBytes;
|
|
2486
|
-
this.report.totalNumberOfIssues += this.deltaNumberOfIssues;
|
|
2487
2397
|
this.receivingAudioBitrate = this.deltaReceivedAudioBytes * 8 / elapsedInSeconds;
|
|
2488
2398
|
this.receivingVideoBitrate = this.deltaReceivedVideoBytes * 8 / elapsedInSeconds;
|
|
2489
2399
|
this.sendingAudioBitrate = this.deltaSentAudioBytes * 8 / elapsedInSeconds;
|
|
2490
2400
|
this.sendingVideoBitrate = this.deltaSentVideoBytes * 8 / elapsedInSeconds;
|
|
2491
2401
|
this.currentAvgRttInMs = 0 < numberOfRttMeasurements ? sumOfRtts / numberOfRttMeasurements : void 0;
|
|
2492
2402
|
this.calculatedScore.value = sample.score;
|
|
2493
|
-
if (sample.score !== void 0) {
|
|
2494
|
-
const bucket = Math.floor(sample.score).toString();
|
|
2495
|
-
this.report.scoreDistribution[bucket] = (this.report.scoreDistribution[bucket] ?? 0) + 1;
|
|
2496
|
-
this.report.scoreDistribution.count += 1;
|
|
2497
|
-
this.report.scoreDistribution.sum += sample.score;
|
|
2498
|
-
}
|
|
2499
2403
|
this.lastSampleTimestamp = sample.timestamp;
|
|
2500
2404
|
const elapsedTimeInMs = now - this.updated;
|
|
2501
2405
|
this.emit("update", sample, elapsedTimeInMs, context);
|
|
@@ -2560,7 +2464,6 @@ var ObservedClient = class extends import_events2.EventEmitter {
|
|
|
2560
2464
|
}
|
|
2561
2465
|
addIssue(issue) {
|
|
2562
2466
|
if (this.closed) return;
|
|
2563
|
-
this.report.issues[issue.type] = (this.report.issues[issue.type] ?? 0) + 1;
|
|
2564
2467
|
this._notify("client-issue", { ...this.eventScope, issue });
|
|
2565
2468
|
}
|
|
2566
2469
|
addExtensionStats(stats) {
|
|
@@ -2787,31 +2690,9 @@ var ObservedClient = class extends import_events2.EventEmitter {
|
|
|
2787
2690
|
), void 0;
|
|
2788
2691
|
}
|
|
2789
2692
|
const newObservedPeerConnection = new ObservedPeerConnection(sample.peerConnectionId, this);
|
|
2790
|
-
const onInboundTrackRemoved = (track) => {
|
|
2791
|
-
this._notify("client-track-report", {
|
|
2792
|
-
...this.eventScope,
|
|
2793
|
-
report: {
|
|
2794
|
-
direction: "inbound",
|
|
2795
|
-
...track.report
|
|
2796
|
-
}
|
|
2797
|
-
});
|
|
2798
|
-
};
|
|
2799
|
-
const onOutboundTrackRemoved = (track) => {
|
|
2800
|
-
this._notify("client-track-report", {
|
|
2801
|
-
...this.eventScope,
|
|
2802
|
-
report: {
|
|
2803
|
-
direction: "outbound",
|
|
2804
|
-
...track.report
|
|
2805
|
-
}
|
|
2806
|
-
});
|
|
2807
|
-
};
|
|
2808
2693
|
newObservedPeerConnection.once("close", () => {
|
|
2809
|
-
newObservedPeerConnection?.off("removed-inbound-track", onInboundTrackRemoved);
|
|
2810
|
-
newObservedPeerConnection?.off("removed-outbound-track", onOutboundTrackRemoved);
|
|
2811
2694
|
this.observedPeerConnections.delete(sample.peerConnectionId);
|
|
2812
2695
|
});
|
|
2813
|
-
newObservedPeerConnection.on("removed-inbound-track", onInboundTrackRemoved);
|
|
2814
|
-
newObservedPeerConnection.on("removed-outbound-track", onOutboundTrackRemoved);
|
|
2815
2696
|
this.observedPeerConnections.set(sample.peerConnectionId, newObservedPeerConnection);
|
|
2816
2697
|
this._notify("peer-connection-added", { ...this.eventScope, observedPeerConnection: newObservedPeerConnection });
|
|
2817
2698
|
observedPeerConnection = newObservedPeerConnection;
|
|
@@ -2918,21 +2799,6 @@ var OnAllClientCallUpdater = class {
|
|
|
2918
2799
|
}
|
|
2919
2800
|
};
|
|
2920
2801
|
|
|
2921
|
-
// src/updaters/OnIntervalUpdater.ts
|
|
2922
|
-
var OnIntervalUpdater = class {
|
|
2923
|
-
constructor(intervalInMs, _update) {
|
|
2924
|
-
this._update = _update;
|
|
2925
|
-
this.timer = setInterval(() => this._update(), intervalInMs);
|
|
2926
|
-
}
|
|
2927
|
-
_update;
|
|
2928
|
-
name = "OnIntervalUpdater";
|
|
2929
|
-
description = "Call the update() method given in the constructor once the interval elapsed";
|
|
2930
|
-
timer;
|
|
2931
|
-
close() {
|
|
2932
|
-
clearInterval(this.timer);
|
|
2933
|
-
}
|
|
2934
|
-
};
|
|
2935
|
-
|
|
2936
2802
|
// src/updaters/OnAnyClientCallUpdater.ts
|
|
2937
2803
|
var OnAnyClientCallUpdater = class {
|
|
2938
2804
|
constructor(_observedCall) {
|
|
@@ -3006,9 +2872,6 @@ var ObservedCall = class extends import_events3.EventEmitter {
|
|
|
3006
2872
|
this.appData = settings.appData ?? {};
|
|
3007
2873
|
this.scoreCalculator = new DefaultCallScoreCalculator(this);
|
|
3008
2874
|
this.detectors = new Detectors();
|
|
3009
|
-
if (settings.updateIntervalInMs && settings.updatePolicy !== "update-on-interval") {
|
|
3010
|
-
logger4.warn('updateIntervalInMs is ignored unless updatePolicy is "update-on-interval" (callId: %s)', settings.callId);
|
|
3011
|
-
}
|
|
3012
2875
|
switch (settings.updatePolicy) {
|
|
3013
2876
|
case "update-on-any-client-updated":
|
|
3014
2877
|
this.updater = new OnAnyClientCallUpdater(this);
|
|
@@ -3016,17 +2879,6 @@ var ObservedCall = class extends import_events3.EventEmitter {
|
|
|
3016
2879
|
case "update-when-all-client-updated":
|
|
3017
2880
|
this.updater = new OnAllClientCallUpdater(this);
|
|
3018
2881
|
break;
|
|
3019
|
-
case "update-on-interval":
|
|
3020
|
-
if (!settings.updateIntervalInMs) {
|
|
3021
|
-
logger4.warn('updateIntervalInMs must be set when updatePolicy is "update-on-interval"; falling back to "update-when-all-client-updated" (callId: %s)', settings.callId);
|
|
3022
|
-
this.updater = new OnAllClientCallUpdater(this);
|
|
3023
|
-
} else {
|
|
3024
|
-
this.updater = new OnIntervalUpdater(
|
|
3025
|
-
settings.updateIntervalInMs,
|
|
3026
|
-
this.update.bind(this)
|
|
3027
|
-
);
|
|
3028
|
-
}
|
|
3029
|
-
break;
|
|
3030
2882
|
}
|
|
3031
2883
|
this.settings = {
|
|
3032
2884
|
closeCallIfEmptyForMs: settings.closeCallIfEmptyForMs
|
|
@@ -3388,122 +3240,60 @@ var OnAnyCallObserverUpdater = class {
|
|
|
3388
3240
|
}
|
|
3389
3241
|
};
|
|
3390
3242
|
|
|
3391
|
-
// src/
|
|
3392
|
-
var
|
|
3393
|
-
constructor(
|
|
3394
|
-
this.
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
});
|
|
3418
|
-
}
|
|
3419
|
-
observedCall;
|
|
3420
|
-
_consumerIdToProducerId = /* @__PURE__ */ new Map();
|
|
3421
|
-
_producerIdToOutboundTrack = /* @__PURE__ */ new Map();
|
|
3422
|
-
_consumerIdToInboundTrack = /* @__PURE__ */ new Map();
|
|
3423
|
-
// private _producerIdToOutboundTrack = new Map<string, ObservedOutboundTrack>();
|
|
3424
|
-
_inboundTrackToConsumerId = /* @__PURE__ */ new Map();
|
|
3425
|
-
_producerIdToConsumerIds = /* @__PURE__ */ new Map();
|
|
3426
|
-
_outboundTrackToProducerId = /* @__PURE__ */ new Map();
|
|
3427
|
-
resolveRemoteOutboundTrack(inboundTrack) {
|
|
3428
|
-
const consumerId = this._inboundTrackToConsumerId.get(inboundTrack.id);
|
|
3429
|
-
if (!consumerId) return;
|
|
3430
|
-
const producerId = this._consumerIdToProducerId.get(consumerId);
|
|
3431
|
-
if (!producerId) return;
|
|
3432
|
-
return this._producerIdToOutboundTrack.get(producerId);
|
|
3243
|
+
// src/common/Middleware.ts
|
|
3244
|
+
var Executor = class {
|
|
3245
|
+
constructor(stack, finalCallback) {
|
|
3246
|
+
this.stack = stack;
|
|
3247
|
+
this.finalCallback = finalCallback;
|
|
3248
|
+
}
|
|
3249
|
+
stack;
|
|
3250
|
+
finalCallback;
|
|
3251
|
+
done = false;
|
|
3252
|
+
index = 0;
|
|
3253
|
+
prevIndex = -1;
|
|
3254
|
+
// Executes the middleware stack
|
|
3255
|
+
execute(input) {
|
|
3256
|
+
if (this.index <= this.prevIndex) {
|
|
3257
|
+
throw new Error("Middleware must call next() only once!");
|
|
3258
|
+
} else if (this.done) {
|
|
3259
|
+
throw new Error("Middleware stack has already been executed!");
|
|
3260
|
+
}
|
|
3261
|
+
this.prevIndex = this.index;
|
|
3262
|
+
const middleware = this.stack[this.index];
|
|
3263
|
+
this.index++;
|
|
3264
|
+
if (middleware) {
|
|
3265
|
+
return middleware(input, (nextInput) => this.execute(nextInput));
|
|
3266
|
+
}
|
|
3267
|
+
this.done = true;
|
|
3268
|
+
this.finalCallback?.(input);
|
|
3433
3269
|
}
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
if (!producerConsumers) {
|
|
3453
|
-
producerConsumers = [];
|
|
3454
|
-
this._producerIdToConsumerIds.set(producerId, producerConsumers);
|
|
3455
|
-
}
|
|
3456
|
-
producerConsumers.push(consumerId);
|
|
3457
|
-
}
|
|
3458
|
-
_removeInboundTrack(inboundTrack) {
|
|
3459
|
-
const consumerId = this._inboundTrackToConsumerId.get(inboundTrack.id);
|
|
3460
|
-
if (!consumerId) return;
|
|
3461
|
-
this._inboundTrackToConsumerId.delete(inboundTrack.id);
|
|
3462
|
-
this._consumerIdToProducerId.delete(consumerId);
|
|
3463
|
-
this._consumerIdToInboundTrack.delete(consumerId);
|
|
3464
|
-
const producerConsumers = this._producerIdToConsumerIds.get(consumerId);
|
|
3465
|
-
if (!producerConsumers) return;
|
|
3466
|
-
const filteredProducerConsumers = producerConsumers.filter((id) => id !== consumerId);
|
|
3467
|
-
if (filteredProducerConsumers.length === 0) {
|
|
3468
|
-
this._producerIdToConsumerIds.delete(consumerId);
|
|
3469
|
-
} else {
|
|
3470
|
-
this._producerIdToConsumerIds.set(consumerId, filteredProducerConsumers);
|
|
3270
|
+
};
|
|
3271
|
+
var MiddlewareProcessor = class {
|
|
3272
|
+
stack = [];
|
|
3273
|
+
finalCallback;
|
|
3274
|
+
addMiddleware(...middlewares) {
|
|
3275
|
+
if (middlewares && middlewares.length > 0) {
|
|
3276
|
+
this.stack.push(...middlewares);
|
|
3277
|
+
}
|
|
3278
|
+
return this;
|
|
3279
|
+
}
|
|
3280
|
+
removeMiddleware(...middlewares) {
|
|
3281
|
+
if (middlewares && middlewares.length > 0) {
|
|
3282
|
+
for (const middleware of middlewares) {
|
|
3283
|
+
const index = this.stack.indexOf(middleware);
|
|
3284
|
+
if (index >= 0) {
|
|
3285
|
+
this.stack.splice(index, 1);
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3471
3288
|
}
|
|
3289
|
+
return this;
|
|
3472
3290
|
}
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
this._producerIdToOutboundTrack.set(producerId, outboundTrack);
|
|
3480
|
-
this._outboundTrackToProducerId.set(outboundTrack.id, producerId);
|
|
3481
|
-
}
|
|
3482
|
-
_removeOutboundTrack(outboundTrack) {
|
|
3483
|
-
const producerId = this._outboundTrackToProducerId.get(outboundTrack.id);
|
|
3484
|
-
if (!producerId) return;
|
|
3485
|
-
this._producerIdToOutboundTrack.delete(producerId);
|
|
3486
|
-
this._outboundTrackToProducerId.delete(outboundTrack.id);
|
|
3487
|
-
}
|
|
3488
|
-
_getInboundTrackAttachments(inboundTrack) {
|
|
3489
|
-
const {
|
|
3490
|
-
producerId,
|
|
3491
|
-
consumerId
|
|
3492
|
-
} = inboundTrack.attachments ?? {};
|
|
3493
|
-
if (!producerId || !consumerId || typeof producerId !== "string" || typeof consumerId !== "string") return;
|
|
3494
|
-
return {
|
|
3495
|
-
producerId,
|
|
3496
|
-
consumerId
|
|
3497
|
-
};
|
|
3498
|
-
}
|
|
3499
|
-
_getOutboundTrackAttachments(outboundTrack) {
|
|
3500
|
-
const {
|
|
3501
|
-
producerId
|
|
3502
|
-
} = outboundTrack.attachments ?? {};
|
|
3503
|
-
if (!producerId || typeof producerId !== "string") return;
|
|
3504
|
-
return {
|
|
3505
|
-
producerId
|
|
3506
|
-
};
|
|
3291
|
+
process(value) {
|
|
3292
|
+
if (this.stack.length === 0) {
|
|
3293
|
+
return this.finalCallback?.(value);
|
|
3294
|
+
}
|
|
3295
|
+
const executor = new Executor(this.stack, this.finalCallback);
|
|
3296
|
+
executor.execute(value);
|
|
3507
3297
|
}
|
|
3508
3298
|
};
|
|
3509
3299
|
|
|
@@ -3526,19 +3316,6 @@ var Observer = class extends import_events5.EventEmitter {
|
|
|
3526
3316
|
case "update-when-all-call-updated":
|
|
3527
3317
|
this.updater = new OnAllCallObserverUpdater(this);
|
|
3528
3318
|
break;
|
|
3529
|
-
case "update-on-interval": {
|
|
3530
|
-
const interval = config?.updateIntervalInMs;
|
|
3531
|
-
if (!interval) {
|
|
3532
|
-
logger6.warn('updateIntervalInMs must be set when updatePolicy is "update-on-interval"; falling back to "update-when-all-call-updated"');
|
|
3533
|
-
this.updater = new OnAllCallObserverUpdater(this);
|
|
3534
|
-
} else {
|
|
3535
|
-
this.updater = new OnIntervalUpdater(
|
|
3536
|
-
interval,
|
|
3537
|
-
this.update.bind(this)
|
|
3538
|
-
);
|
|
3539
|
-
}
|
|
3540
|
-
break;
|
|
3541
|
-
}
|
|
3542
3319
|
}
|
|
3543
3320
|
}
|
|
3544
3321
|
config;
|
|
@@ -3556,7 +3333,8 @@ var Observer = class extends import_events5.EventEmitter {
|
|
|
3556
3333
|
numberOfOutboundRtpStreams = 0;
|
|
3557
3334
|
numberOfDataChannels = 0;
|
|
3558
3335
|
numberOfPeerConnections = 0;
|
|
3559
|
-
|
|
3336
|
+
/** Global, pre-dispatch middleware chain run on every accepted sample. */
|
|
3337
|
+
acceptMiddlewares = new MiddlewareProcessor();
|
|
3560
3338
|
get numberOfCalls() {
|
|
3561
3339
|
return this.observedCalls.size;
|
|
3562
3340
|
}
|
|
@@ -3579,14 +3357,11 @@ var Observer = class extends import_events5.EventEmitter {
|
|
|
3579
3357
|
const callSettings = {
|
|
3580
3358
|
...settings,
|
|
3581
3359
|
updatePolicy: settings.updatePolicy ?? this.config.defaultCallUpdatePolicy,
|
|
3582
|
-
updateIntervalInMs: settings.updateIntervalInMs ?? this.config.defaultCallUpdateIntervalInMs,
|
|
3583
3360
|
closeCallIfEmptyForMs: settings.closeCallIfEmptyForMs ?? this.config.closeCallIfEmptyForMs,
|
|
3584
3361
|
appData: settings.appData ?? this.config.createCallAppData?.({ callId: settings.callId, observer: this })
|
|
3585
3362
|
};
|
|
3586
3363
|
const observedCall = new ObservedCall(callSettings, this);
|
|
3587
|
-
|
|
3588
|
-
observedCall.remoteTrackResolver = new MediasoupRemoteTrackResolver(observedCall);
|
|
3589
|
-
}
|
|
3364
|
+
observedCall.remoteTrackResolver = this.config.createTrackResolver?.(observedCall);
|
|
3590
3365
|
observedCall.once("close", () => {
|
|
3591
3366
|
this.observedCalls.delete(observedCall.callId);
|
|
3592
3367
|
++this.totalRemovedCall;
|
|
@@ -3604,15 +3379,17 @@ var Observer = class extends import_events5.EventEmitter {
|
|
|
3604
3379
|
return logger6.debug("Attempted to close twice");
|
|
3605
3380
|
}
|
|
3606
3381
|
this.closed = true;
|
|
3607
|
-
clearInterval(this._timer);
|
|
3608
|
-
this._timer = void 0;
|
|
3609
3382
|
this.observedCalls.forEach((call) => call.close());
|
|
3610
3383
|
this._notify("observer-closed", { ...this.eventScope });
|
|
3611
3384
|
}
|
|
3612
3385
|
accept(sample, context) {
|
|
3613
3386
|
if (this.closed) {
|
|
3614
|
-
this._notify("sample-rejected", { ...this.eventScope, reason: "observer-closed", sample });
|
|
3615
|
-
|
|
3387
|
+
return this._notify("sample-rejected", { ...this.eventScope, reason: "observer-closed", sample });
|
|
3388
|
+
}
|
|
3389
|
+
try {
|
|
3390
|
+
this.acceptMiddlewares.process({ sample, context });
|
|
3391
|
+
} catch (err) {
|
|
3392
|
+
logger6.warn("An accept middleware threw; dropping the sample. %o", err);
|
|
3616
3393
|
}
|
|
3617
3394
|
if (!sample.callId) {
|
|
3618
3395
|
this._notify("sample-rejected", { ...this.eventScope, reason: "missing-callId", sample });
|
|
@@ -3729,6 +3506,126 @@ var InMemorySink = class extends ClientSampleSink {
|
|
|
3729
3506
|
function createInMemorySink(samples) {
|
|
3730
3507
|
return new InMemorySink(samples);
|
|
3731
3508
|
}
|
|
3509
|
+
|
|
3510
|
+
// src/utils/RemoteTrackResolver.ts
|
|
3511
|
+
var RemoteTrackResolver = class {
|
|
3512
|
+
constructor(observedCall, resolvers) {
|
|
3513
|
+
this.observedCall = observedCall;
|
|
3514
|
+
this.resolvers = resolvers;
|
|
3515
|
+
const observer = observedCall.observer;
|
|
3516
|
+
const onInboundAdded = (p) => {
|
|
3517
|
+
if (p.observedCall === this.observedCall) this._addInboundTrack(p.observedInboundTrack);
|
|
3518
|
+
};
|
|
3519
|
+
const onInboundRemoved = (p) => {
|
|
3520
|
+
if (p.observedCall === this.observedCall) this._removeInboundTrack(p.observedInboundTrack);
|
|
3521
|
+
};
|
|
3522
|
+
const onOutboundAdded = (p) => {
|
|
3523
|
+
if (p.observedCall === this.observedCall) this._addOutboundTrack(p.observedOutboundTrack);
|
|
3524
|
+
};
|
|
3525
|
+
const onOutboundRemoved = (p) => {
|
|
3526
|
+
if (p.observedCall === this.observedCall) this._removeOutboundTrack(p.observedOutboundTrack);
|
|
3527
|
+
};
|
|
3528
|
+
observedCall.once("close", () => {
|
|
3529
|
+
observer.off("inbound-track-added", onInboundAdded);
|
|
3530
|
+
observer.off("inbound-track-removed", onInboundRemoved);
|
|
3531
|
+
observer.off("outbound-track-added", onOutboundAdded);
|
|
3532
|
+
observer.off("outbound-track-removed", onOutboundRemoved);
|
|
3533
|
+
});
|
|
3534
|
+
observer.on("inbound-track-added", onInboundAdded);
|
|
3535
|
+
observer.on("inbound-track-removed", onInboundRemoved);
|
|
3536
|
+
observer.on("outbound-track-added", onOutboundAdded);
|
|
3537
|
+
observer.on("outbound-track-removed", onOutboundRemoved);
|
|
3538
|
+
}
|
|
3539
|
+
observedCall;
|
|
3540
|
+
resolvers;
|
|
3541
|
+
_publisherIdToOutboundTrack = /* @__PURE__ */ new Map();
|
|
3542
|
+
_subscriberIdToInboundTrack = /* @__PURE__ */ new Map();
|
|
3543
|
+
/** The published (outbound) track for a publisher id, if any. */
|
|
3544
|
+
getOutboundTrackByPublisherId(publisherId) {
|
|
3545
|
+
return this._publisherIdToOutboundTrack.get(publisherId);
|
|
3546
|
+
}
|
|
3547
|
+
/** The subscribed (inbound) track for a subscriber id, if the strategy resolves subscriber ids. */
|
|
3548
|
+
getInboundTrackBySubscriberId(subscriberId) {
|
|
3549
|
+
return this._subscriberIdToInboundTrack.get(subscriberId);
|
|
3550
|
+
}
|
|
3551
|
+
// RemoteTrackResolver interface — thin readers over the links maintained on the tracks.
|
|
3552
|
+
resolveRemoteOutboundTrack(inboundTrack) {
|
|
3553
|
+
return inboundTrack.remoteOutboundTrack;
|
|
3554
|
+
}
|
|
3555
|
+
resolveRemoteInboundTracks(outboundTrack) {
|
|
3556
|
+
return [...outboundTrack.remoteInboundTracks];
|
|
3557
|
+
}
|
|
3558
|
+
_addInboundTrack(inboundTrack) {
|
|
3559
|
+
const publisherId = this.resolvers.resolveInboundTrackPublisherId(inboundTrack);
|
|
3560
|
+
if (!publisherId) return;
|
|
3561
|
+
const subscriberId = this.resolvers.resolveInboundTrackSubscriberId?.(inboundTrack);
|
|
3562
|
+
if (subscriberId) {
|
|
3563
|
+
this._subscriberIdToInboundTrack.set(subscriberId, inboundTrack);
|
|
3564
|
+
}
|
|
3565
|
+
const outboundTrack = this._publisherIdToOutboundTrack.get(publisherId);
|
|
3566
|
+
if (!outboundTrack) return;
|
|
3567
|
+
outboundTrack.remoteInboundTracks.add(inboundTrack);
|
|
3568
|
+
inboundTrack.remoteOutboundTrack = outboundTrack;
|
|
3569
|
+
}
|
|
3570
|
+
_removeInboundTrack(inboundTrack) {
|
|
3571
|
+
inboundTrack.remoteOutboundTrack?.remoteInboundTracks.delete(inboundTrack);
|
|
3572
|
+
inboundTrack.remoteOutboundTrack = void 0;
|
|
3573
|
+
const subscriberId = this.resolvers.resolveInboundTrackSubscriberId?.(inboundTrack);
|
|
3574
|
+
if (subscriberId) {
|
|
3575
|
+
this._subscriberIdToInboundTrack.delete(subscriberId);
|
|
3576
|
+
}
|
|
3577
|
+
}
|
|
3578
|
+
_addOutboundTrack(outboundTrack) {
|
|
3579
|
+
const publisherId = this.resolvers.resolveOutboundTrackPublisherId(outboundTrack);
|
|
3580
|
+
if (!publisherId) return;
|
|
3581
|
+
this._publisherIdToOutboundTrack.set(publisherId, outboundTrack);
|
|
3582
|
+
for (const observedClient of this.observedCall.observedClients.values()) {
|
|
3583
|
+
for (const observedPeerConnection of observedClient.observedPeerConnections.values()) {
|
|
3584
|
+
for (const inboundTrack of observedPeerConnection.observedInboundTracks.values()) {
|
|
3585
|
+
if (this.resolvers.resolveInboundTrackPublisherId(inboundTrack) !== publisherId) continue;
|
|
3586
|
+
outboundTrack.remoteInboundTracks.add(inboundTrack);
|
|
3587
|
+
inboundTrack.remoteOutboundTrack = outboundTrack;
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
_removeOutboundTrack(outboundTrack) {
|
|
3593
|
+
const publisherId = this.resolvers.resolveOutboundTrackPublisherId(outboundTrack);
|
|
3594
|
+
if (publisherId && this._publisherIdToOutboundTrack.get(publisherId) === outboundTrack) {
|
|
3595
|
+
this._publisherIdToOutboundTrack.delete(publisherId);
|
|
3596
|
+
}
|
|
3597
|
+
for (const inboundTrack of outboundTrack.remoteInboundTracks) {
|
|
3598
|
+
inboundTrack.remoteOutboundTrack = void 0;
|
|
3599
|
+
}
|
|
3600
|
+
outboundTrack.remoteInboundTracks.clear();
|
|
3601
|
+
}
|
|
3602
|
+
};
|
|
3603
|
+
|
|
3604
|
+
// src/utils/RemoteTrackResolverFactories.ts
|
|
3605
|
+
function createDefaultMediasoupRemoteTrackResolverFactory() {
|
|
3606
|
+
return (observedCall) => new RemoteTrackResolver(observedCall, {
|
|
3607
|
+
resolveInboundTrackPublisherId: (inboundTrack) => inboundTrack.attachments?.producerId,
|
|
3608
|
+
resolveInboundTrackSubscriberId: (inboundTrack) => inboundTrack.attachments?.consumerId,
|
|
3609
|
+
resolveOutboundTrackPublisherId: (outboundTrack) => outboundTrack.attachments?.producerId
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3612
|
+
function createP2pRemoteTrackResolverFactory() {
|
|
3613
|
+
return (observedCall) => new RemoteTrackResolver(observedCall, {
|
|
3614
|
+
resolveInboundTrackPublisherId: (inboundTrack) => {
|
|
3615
|
+
const ssrc = inboundTrack.getInboundRtp()?.ssrc;
|
|
3616
|
+
return ssrc ? `${ssrc}` : void 0;
|
|
3617
|
+
},
|
|
3618
|
+
resolveInboundTrackSubscriberId: (inboundTrack) => {
|
|
3619
|
+
const ssrc = inboundTrack.getInboundRtp()?.ssrc;
|
|
3620
|
+
return ssrc ? `${ssrc}` : void 0;
|
|
3621
|
+
},
|
|
3622
|
+
resolveOutboundTrackPublisherId: (outboundTrack) => {
|
|
3623
|
+
const rtps = outboundTrack.getOutboundRtps();
|
|
3624
|
+
if (!rtps || rtps.length === 0) return void 0;
|
|
3625
|
+
return rtps.map((rtp) => rtp.ssrc).join(",");
|
|
3626
|
+
}
|
|
3627
|
+
});
|
|
3628
|
+
}
|
|
3732
3629
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3733
3630
|
0 && (module.exports = {
|
|
3734
3631
|
ClientEventTypes,
|
|
@@ -3756,10 +3653,13 @@ function createInMemorySink(samples) {
|
|
|
3756
3653
|
ObservedRemoteInboundRtp,
|
|
3757
3654
|
ObservedRemoteOutboundRtp,
|
|
3758
3655
|
Observer,
|
|
3656
|
+
RemoteTrackResolver,
|
|
3657
|
+
createDefaultMediasoupRemoteTrackResolverFactory,
|
|
3759
3658
|
createInMemorySink,
|
|
3760
3659
|
createJsonlFileSink,
|
|
3761
3660
|
createJsonlFileSinkFactory,
|
|
3762
3661
|
createLogger,
|
|
3662
|
+
createP2pRemoteTrackResolverFactory,
|
|
3763
3663
|
setObserverLogger
|
|
3764
3664
|
});
|
|
3765
3665
|
//# sourceMappingURL=index.js.map
|