@whereby.com/media 1.17.3 → 1.17.5
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/dist/index.cjs +318 -262
- package/dist/index.d.cts +84 -9
- package/dist/index.d.mts +84 -9
- package/dist/index.d.ts +84 -9
- package/dist/index.mjs +316 -263
- package/dist/legacy-esm.js +316 -263
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var mediasoupClient = require('mediasoup-client');
|
|
4
|
-
var EventEmitter = require('events');
|
|
5
|
-
var socket_ioClient = require('socket.io-client');
|
|
6
3
|
var adapterRaw = require('webrtc-adapter');
|
|
7
4
|
var rtcstats = require('rtcstats');
|
|
8
5
|
var uuid = require('uuid');
|
|
6
|
+
var mediasoupClient = require('mediasoup-client');
|
|
7
|
+
var EventEmitter = require('events');
|
|
8
|
+
var socket_ioClient = require('socket.io-client');
|
|
9
9
|
var SDPUtils = require('sdp');
|
|
10
10
|
var sdpTransform = require('sdp-transform');
|
|
11
11
|
var ipAddress = require('ip-address');
|
|
@@ -118,6 +118,178 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
118
118
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
+
var _a$7;
|
|
122
|
+
(_a$7 = adapterRaw.default) !== null && _a$7 !== void 0 ? _a$7 : adapterRaw;
|
|
123
|
+
const RTCSTATS_PROTOCOL_VERSION = "1.0";
|
|
124
|
+
const GETSTATS_BUFFER_SIZE = 20;
|
|
125
|
+
const clientInfo = {
|
|
126
|
+
id: uuid.v4(),
|
|
127
|
+
connectionNumber: 0,
|
|
128
|
+
};
|
|
129
|
+
const noop = () => { };
|
|
130
|
+
let resetDelta = noop;
|
|
131
|
+
function rtcStatsConnection(wsURL, logger = console) {
|
|
132
|
+
const buffer = [];
|
|
133
|
+
let ws;
|
|
134
|
+
let organizationId;
|
|
135
|
+
let clientId;
|
|
136
|
+
let displayName;
|
|
137
|
+
let userRole;
|
|
138
|
+
let roomSessionId;
|
|
139
|
+
let connectionShouldBeOpen;
|
|
140
|
+
let connectionAttempt = 0;
|
|
141
|
+
let hasPassedOnRoomSessionId = false;
|
|
142
|
+
let getStatsBufferUsed = 0;
|
|
143
|
+
let deviceId;
|
|
144
|
+
let roomProduct;
|
|
145
|
+
let roomMode;
|
|
146
|
+
let sfuServer;
|
|
147
|
+
let featureFlags;
|
|
148
|
+
const connection = {
|
|
149
|
+
connected: false,
|
|
150
|
+
trace: (...args) => {
|
|
151
|
+
args.push(Date.now());
|
|
152
|
+
if (args[0] === "customEvent" && args[2].type === "roomSessionId") {
|
|
153
|
+
const oldRoomSessionIdValue = roomSessionId && roomSessionId[2].value.roomSessionId;
|
|
154
|
+
const newRoomSessionIdValue = args[2].value.roomSessionId;
|
|
155
|
+
roomSessionId = args;
|
|
156
|
+
if (hasPassedOnRoomSessionId &&
|
|
157
|
+
newRoomSessionIdValue &&
|
|
158
|
+
newRoomSessionIdValue !== oldRoomSessionIdValue) {
|
|
159
|
+
ws === null || ws === void 0 ? void 0 : ws.close();
|
|
160
|
+
}
|
|
161
|
+
if (newRoomSessionIdValue)
|
|
162
|
+
hasPassedOnRoomSessionId = true;
|
|
163
|
+
}
|
|
164
|
+
else if (args[0] === "customEvent" && args[2].type === "clientId") {
|
|
165
|
+
clientId = args;
|
|
166
|
+
}
|
|
167
|
+
else if (args[0] === "customEvent" && args[2].type === "organizationId") {
|
|
168
|
+
organizationId = args;
|
|
169
|
+
}
|
|
170
|
+
else if (args[0] === "customEvent" && args[2].type === "displayName") {
|
|
171
|
+
displayName = args;
|
|
172
|
+
}
|
|
173
|
+
else if (args[0] === "customEvent" && args[2].type === "userRole") {
|
|
174
|
+
userRole = args;
|
|
175
|
+
}
|
|
176
|
+
else if (args[0] === "customEvent" && args[2].type === "deviceId") {
|
|
177
|
+
deviceId = args;
|
|
178
|
+
}
|
|
179
|
+
else if (args[0] === "customEvent" && args[2].type === "roomProduct") {
|
|
180
|
+
roomProduct = args;
|
|
181
|
+
}
|
|
182
|
+
else if (args[0] === "customEvent" && args[2].type === "roomMode") {
|
|
183
|
+
roomMode = args;
|
|
184
|
+
}
|
|
185
|
+
else if (args[0] === "customEvent" && args[2].type === "sfuServer") {
|
|
186
|
+
sfuServer = args;
|
|
187
|
+
}
|
|
188
|
+
else if (args[0] === "customEvent" && args[2].type === "featureFlags") {
|
|
189
|
+
featureFlags = args;
|
|
190
|
+
}
|
|
191
|
+
if ((ws === null || ws === void 0 ? void 0 : ws.readyState) === WebSocket.OPEN) {
|
|
192
|
+
connectionAttempt = 0;
|
|
193
|
+
ws.send(JSON.stringify(args));
|
|
194
|
+
}
|
|
195
|
+
else if (args[0] === "getstats") {
|
|
196
|
+
if (getStatsBufferUsed < GETSTATS_BUFFER_SIZE) {
|
|
197
|
+
getStatsBufferUsed++;
|
|
198
|
+
buffer.push(args);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else if (args[0] === "customEvent" && args[2].type === "insightsStats") ;
|
|
202
|
+
else {
|
|
203
|
+
buffer.push(args);
|
|
204
|
+
}
|
|
205
|
+
if ((ws === null || ws === void 0 ? void 0 : ws.readyState) === WebSocket.CLOSED && connectionShouldBeOpen) {
|
|
206
|
+
setTimeout(() => {
|
|
207
|
+
if (ws.readyState === WebSocket.CLOSED && connectionShouldBeOpen) {
|
|
208
|
+
connection.connect();
|
|
209
|
+
}
|
|
210
|
+
}, 1000 * connectionAttempt);
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
close: () => {
|
|
214
|
+
connectionShouldBeOpen = false;
|
|
215
|
+
ws === null || ws === void 0 ? void 0 : ws.close();
|
|
216
|
+
},
|
|
217
|
+
connect: () => {
|
|
218
|
+
connectionShouldBeOpen = true;
|
|
219
|
+
connectionAttempt += 1;
|
|
220
|
+
ws === null || ws === void 0 ? void 0 : ws.close();
|
|
221
|
+
connection.connected = true;
|
|
222
|
+
ws = new WebSocket(wsURL + window.location.pathname, RTCSTATS_PROTOCOL_VERSION);
|
|
223
|
+
ws.onerror = (e) => {
|
|
224
|
+
connection.connected = false;
|
|
225
|
+
logger.warn(`[RTCSTATS] WebSocket error`, e);
|
|
226
|
+
};
|
|
227
|
+
ws.onclose = (e) => {
|
|
228
|
+
connection.connected = false;
|
|
229
|
+
logger.info(`[RTCSTATS] Closed ${e.code}`);
|
|
230
|
+
resetDelta();
|
|
231
|
+
};
|
|
232
|
+
ws.onopen = () => {
|
|
233
|
+
clientInfo.connectionNumber++;
|
|
234
|
+
ws.send(JSON.stringify(["clientInfo", null, clientInfo]));
|
|
235
|
+
if (organizationId) {
|
|
236
|
+
ws.send(JSON.stringify(organizationId));
|
|
237
|
+
}
|
|
238
|
+
if (clientId) {
|
|
239
|
+
ws.send(JSON.stringify(clientId));
|
|
240
|
+
}
|
|
241
|
+
if (roomSessionId) {
|
|
242
|
+
ws.send(JSON.stringify(roomSessionId));
|
|
243
|
+
}
|
|
244
|
+
if (displayName) {
|
|
245
|
+
ws.send(JSON.stringify(displayName));
|
|
246
|
+
}
|
|
247
|
+
if (userRole) {
|
|
248
|
+
ws.send(JSON.stringify(userRole));
|
|
249
|
+
}
|
|
250
|
+
if (deviceId) {
|
|
251
|
+
ws.send(JSON.stringify(deviceId));
|
|
252
|
+
}
|
|
253
|
+
if (roomMode) {
|
|
254
|
+
ws.send(JSON.stringify(roomMode));
|
|
255
|
+
}
|
|
256
|
+
if (roomProduct) {
|
|
257
|
+
ws.send(JSON.stringify(roomProduct));
|
|
258
|
+
}
|
|
259
|
+
if (sfuServer) {
|
|
260
|
+
ws.send(JSON.stringify(sfuServer));
|
|
261
|
+
}
|
|
262
|
+
if (featureFlags) {
|
|
263
|
+
ws.send(JSON.stringify(featureFlags));
|
|
264
|
+
}
|
|
265
|
+
while (buffer.length) {
|
|
266
|
+
ws.send(JSON.stringify(buffer.shift()));
|
|
267
|
+
}
|
|
268
|
+
getStatsBufferUsed = 0;
|
|
269
|
+
};
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
return connection;
|
|
273
|
+
}
|
|
274
|
+
const server = rtcStatsConnection(process.env.RTCSTATS_URL || "wss://rtcstats.srv.whereby.com");
|
|
275
|
+
const stats = rtcstats(server.trace, 10000, [""]);
|
|
276
|
+
resetDelta = (stats === null || stats === void 0 ? void 0 : stats.resetDelta) || noop;
|
|
277
|
+
const rtcStats = {
|
|
278
|
+
sendEvent: (type, value) => {
|
|
279
|
+
server.trace("customEvent", null, {
|
|
280
|
+
type,
|
|
281
|
+
value,
|
|
282
|
+
});
|
|
283
|
+
},
|
|
284
|
+
sendAudioMuted: (muted) => {
|
|
285
|
+
rtcStats.sendEvent("audio_muted", { muted });
|
|
286
|
+
},
|
|
287
|
+
sendVideoMuted: (muted) => {
|
|
288
|
+
rtcStats.sendEvent("video_muted", { muted });
|
|
289
|
+
},
|
|
290
|
+
server,
|
|
291
|
+
};
|
|
292
|
+
|
|
121
293
|
function captureCandidatePairInfoMetrics(cpMetrics, currentCptats, prevCptats, timeDiff, report) {
|
|
122
294
|
const bytesReceivedDiff = currentCptats.bytesReceived - ((prevCptats === null || prevCptats === void 0 ? void 0 : prevCptats.bytesReceived) || 0);
|
|
123
295
|
const bytesSentDiff = currentCptats.bytesSent - ((prevCptats === null || prevCptats === void 0 ? void 0 : prevCptats.bytesSent) || 0);
|
|
@@ -321,6 +493,8 @@ const getPeerConnectionIndex = (pc) => { var _a; return (_a = peerConnectionData
|
|
|
321
493
|
const setPeerConnectionsForTests = (pcs) => (peerConnections = pcs);
|
|
322
494
|
|
|
323
495
|
const pcDataByPc = new WeakMap();
|
|
496
|
+
let numMissingTrackSsrcLookups = 0;
|
|
497
|
+
let numFailedTrackSsrcLookups = 0;
|
|
324
498
|
const getPeerConnectionsWithStatsReports = () => Promise.all(getCurrentPeerConnections().map((pc) => __awaiter(void 0, void 0, void 0, function* () {
|
|
325
499
|
let pcData = pcDataByPc.get(pc);
|
|
326
500
|
if (!pcData) {
|
|
@@ -368,6 +542,7 @@ const getPeerConnectionsWithStatsReports = () => Promise.all(getCurrentPeerConne
|
|
|
368
542
|
});
|
|
369
543
|
});
|
|
370
544
|
missingSsrcs.forEach((ssrc) => {
|
|
545
|
+
numMissingTrackSsrcLookups++;
|
|
371
546
|
if (!pcData.ssrcToTrackId[ssrc]) {
|
|
372
547
|
pcData.ssrcToTrackId[ssrc] = "?" + ssrc;
|
|
373
548
|
}
|
|
@@ -375,7 +550,13 @@ const getPeerConnectionsWithStatsReports = () => Promise.all(getCurrentPeerConne
|
|
|
375
550
|
}
|
|
376
551
|
return [pc, report, pcData];
|
|
377
552
|
}
|
|
378
|
-
catch (
|
|
553
|
+
catch (e) {
|
|
554
|
+
rtcStats.sendEvent("trackSsrcLookupFailed", {
|
|
555
|
+
name: e === null || e === void 0 ? void 0 : e.name,
|
|
556
|
+
cause: e === null || e === void 0 ? void 0 : e.cause,
|
|
557
|
+
message: e === null || e === void 0 ? void 0 : e.message,
|
|
558
|
+
});
|
|
559
|
+
numFailedTrackSsrcLookups++;
|
|
379
560
|
return [pc, [], pcData];
|
|
380
561
|
}
|
|
381
562
|
})));
|
|
@@ -532,7 +713,7 @@ function collectStats(state, { logger, interval }, immediate) {
|
|
|
532
713
|
});
|
|
533
714
|
});
|
|
534
715
|
removeNonUpdatedStats(state.statsByView, state.lastUpdateTime);
|
|
535
|
-
Object.entries(defaultViewStats.candidatePairs).forEach(([cpKey, cp]) => {
|
|
716
|
+
Object.entries((defaultViewStats === null || defaultViewStats === void 0 ? void 0 : defaultViewStats.candidatePairs) || {}).forEach(([cpKey, cp]) => {
|
|
536
717
|
const active = cp.lastRtcStatsTime === state.lastUpdateTime;
|
|
537
718
|
cp.active = active;
|
|
538
719
|
if (!active) {
|
|
@@ -553,8 +734,14 @@ function collectStats(state, { logger, interval }, immediate) {
|
|
|
553
734
|
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients); });
|
|
554
735
|
}
|
|
555
736
|
}
|
|
556
|
-
catch (
|
|
557
|
-
logger.warn(
|
|
737
|
+
catch (e) {
|
|
738
|
+
logger.warn(e);
|
|
739
|
+
state.numFailedStatsReports++;
|
|
740
|
+
rtcStats.sendEvent("collectStatsFailed", {
|
|
741
|
+
name: e === null || e === void 0 ? void 0 : e.name,
|
|
742
|
+
cause: e === null || e === void 0 ? void 0 : e.cause,
|
|
743
|
+
message: e === null || e === void 0 ? void 0 : e.message,
|
|
744
|
+
});
|
|
558
745
|
}
|
|
559
746
|
state.nextTimeout = setTimeout(collectStatsBound, interval);
|
|
560
747
|
});
|
|
@@ -610,6 +797,7 @@ const STATE = {
|
|
|
610
797
|
lastUpdateTime: 0,
|
|
611
798
|
statsByView: {},
|
|
612
799
|
subscriptions: [],
|
|
800
|
+
numFailedStatsReports: 0,
|
|
613
801
|
};
|
|
614
802
|
const OPTIONS = {
|
|
615
803
|
interval: 2000,
|
|
@@ -618,6 +806,11 @@ const OPTIONS = {
|
|
|
618
806
|
const getStats = () => {
|
|
619
807
|
return Object.assign({}, STATE.statsByView);
|
|
620
808
|
};
|
|
809
|
+
const getNumFailedStatsReports = () => {
|
|
810
|
+
return STATE.numFailedStatsReports;
|
|
811
|
+
};
|
|
812
|
+
const getNumMissingTrackSsrcLookups = () => numMissingTrackSsrcLookups;
|
|
813
|
+
const getNumFailedTrackSsrcLookups = () => numFailedTrackSsrcLookups;
|
|
621
814
|
const getUpdatedStats = () => { var _a; return (_a = STATE.currentMonitor) === null || _a === void 0 ? void 0 : _a.getUpdatedStats(); };
|
|
622
815
|
const setClientProvider = (provider) => (STATE.getClients = provider);
|
|
623
816
|
function startStatsMonitor(state, { interval, logger }) {
|
|
@@ -1280,8 +1473,8 @@ class ReconnectManager extends EventEmitter {
|
|
|
1280
1473
|
}
|
|
1281
1474
|
}
|
|
1282
1475
|
|
|
1283
|
-
var _a$
|
|
1284
|
-
const adapter$6 = (_a$
|
|
1476
|
+
var _a$6;
|
|
1477
|
+
const adapter$6 = (_a$6 = adapterRaw.default) !== null && _a$6 !== void 0 ? _a$6 : adapterRaw;
|
|
1285
1478
|
const DEFAULT_SOCKET_PATH = "/protocol/socket.io/v4";
|
|
1286
1479
|
const NOOP_KEEPALIVE_INTERVAL = 2000;
|
|
1287
1480
|
class ServerSocket {
|
|
@@ -1574,9 +1767,15 @@ const packetLossAnalyser = new PacketLossAnalyser();
|
|
|
1574
1767
|
const periodicPacketLossDetector = {
|
|
1575
1768
|
id: "periodic-packet-loss",
|
|
1576
1769
|
enabled: ({ client, hasLiveTrack, ssrc0 }) => {
|
|
1577
|
-
return client.isLocalClient &&
|
|
1770
|
+
return (client.isLocalClient &&
|
|
1771
|
+
hasLiveTrack &&
|
|
1772
|
+
!!(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.ssrc) &&
|
|
1773
|
+
(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.direction) === "out" &&
|
|
1774
|
+
((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.bitrate) || 0) > 0);
|
|
1578
1775
|
},
|
|
1579
1776
|
check: ({ ssrc0 }) => {
|
|
1777
|
+
if (!ssrc0 || !ssrc0.ssrc)
|
|
1778
|
+
return false;
|
|
1580
1779
|
packetLossAnalyser.addPacketLossMeasurement(ssrc0.ssrc, ssrc0.fractionLost || 0, Date.now());
|
|
1581
1780
|
return packetLossAnalyser.hasPeriodicPacketLoss(ssrc0.ssrc, Date.now());
|
|
1582
1781
|
},
|
|
@@ -1585,7 +1784,7 @@ const badNetworkIssueDetector = {
|
|
|
1585
1784
|
id: "bad-network",
|
|
1586
1785
|
enabled: ({ hasLiveTrack, ssrcs }) => hasLiveTrack && ssrcs.length > 0,
|
|
1587
1786
|
check: ({ client, clients, kind, ssrcs }) => {
|
|
1588
|
-
const hasPositiveBitrate = ssrcs.some((ssrc) => ssrc.bitrate > 0);
|
|
1787
|
+
const hasPositiveBitrate = ssrcs.some((ssrc) => ((ssrc === null || ssrc === void 0 ? void 0 : ssrc.bitrate) || 0) > 0);
|
|
1589
1788
|
if (!hasPositiveBitrate && client.isLocalClient && kind === "video") {
|
|
1590
1789
|
const remoteClients = clients.filter((c) => !c.isLocalClient);
|
|
1591
1790
|
if (remoteClients.length > 0) {
|
|
@@ -1597,10 +1796,10 @@ const badNetworkIssueDetector = {
|
|
|
1597
1796
|
return false;
|
|
1598
1797
|
}
|
|
1599
1798
|
return (ssrc0.bitrate === 0 ||
|
|
1600
|
-
ssrc0.lossRatio > 0.03 ||
|
|
1799
|
+
(ssrc0.lossRatio || 0) > 0.03 ||
|
|
1601
1800
|
(ssrc0.fractionLost || 0) > 0.03 ||
|
|
1602
|
-
(!client.isPresentation && kind === "video" && ssrc0.bitrate < 30000) ||
|
|
1603
|
-
(ssrc0.direction === "in" && ssrc0.pliRate > 2));
|
|
1801
|
+
(!client.isPresentation && kind === "video" && !!(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.bitrate) && ssrc0.bitrate < 30000) ||
|
|
1802
|
+
(ssrc0.direction === "in" && !!ssrc0.pliRate && ssrc0.pliRate > 2));
|
|
1604
1803
|
},
|
|
1605
1804
|
};
|
|
1606
1805
|
const dryTrackIssueDetector = {
|
|
@@ -1609,7 +1808,7 @@ const dryTrackIssueDetector = {
|
|
|
1609
1808
|
check: ({ client, clients, ssrcs }) => {
|
|
1610
1809
|
let hasPositiveBitrate = false;
|
|
1611
1810
|
ssrcs.forEach((ssrc) => {
|
|
1612
|
-
hasPositiveBitrate = hasPositiveBitrate || ssrc.bitrate > 0;
|
|
1811
|
+
hasPositiveBitrate = hasPositiveBitrate || ((ssrc === null || ssrc === void 0 ? void 0 : ssrc.bitrate) || 0) > 0;
|
|
1613
1812
|
});
|
|
1614
1813
|
if (!hasPositiveBitrate && client.isLocalClient) {
|
|
1615
1814
|
const remoteClients = clients.filter((c) => !c.isLocalClient);
|
|
@@ -1655,17 +1854,19 @@ const issueDetectors = [
|
|
|
1655
1854
|
typeof (stats === null || stats === void 0 ? void 0 : stats.tracks) === "object" &&
|
|
1656
1855
|
Object.keys(stats.tracks).length > 1);
|
|
1657
1856
|
},
|
|
1658
|
-
check: ({ stats
|
|
1857
|
+
check: ({ stats }) => {
|
|
1858
|
+
if (!stats)
|
|
1859
|
+
return false;
|
|
1659
1860
|
const jitter = {
|
|
1660
1861
|
audio: 0,
|
|
1661
1862
|
video: 0,
|
|
1662
1863
|
};
|
|
1663
|
-
Object.values(tracks)
|
|
1864
|
+
Object.values(stats.tracks)
|
|
1664
1865
|
.flatMap((t) => Object.values(t.ssrcs))
|
|
1665
1866
|
.forEach((ssrc) => {
|
|
1666
|
-
if (ssrc.kind === "audio" && ssrc.jitter > jitter.audio)
|
|
1867
|
+
if (ssrc.kind === "audio" && !!ssrc.jitter && ssrc.jitter > jitter.audio)
|
|
1667
1868
|
jitter.audio = ssrc.jitter;
|
|
1668
|
-
if (ssrc.kind === "video" && ssrc.jitter > jitter.video)
|
|
1869
|
+
if (ssrc.kind === "video" && !!ssrc.jitter && ssrc.jitter > jitter.video)
|
|
1669
1870
|
jitter.video = ssrc.jitter;
|
|
1670
1871
|
});
|
|
1671
1872
|
const diff = Math.abs(jitter.audio * 1000 - jitter.video * 1000);
|
|
@@ -1682,58 +1883,70 @@ const issueDetectors = [
|
|
|
1682
1883
|
dryTrackIssueDetector,
|
|
1683
1884
|
{
|
|
1684
1885
|
id: "low-layer0-bitrate",
|
|
1685
|
-
enabled: ({ hasLiveTrack, ssrc0, kind, client }) => hasLiveTrack && kind === "video" && ssrc0 && ssrc0.height && !client.isPresentation,
|
|
1686
|
-
check: ({ ssrc0 }) =>
|
|
1886
|
+
enabled: ({ hasLiveTrack, ssrc0, kind, client }) => hasLiveTrack && kind === "video" && !!ssrc0 && !!(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.height) && !client.isPresentation,
|
|
1887
|
+
check: ({ ssrc0 }) => {
|
|
1888
|
+
if (!(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.bitrate))
|
|
1889
|
+
return false;
|
|
1890
|
+
return ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.height) || 0) < 200 && ssrc0.bitrate < 30000;
|
|
1891
|
+
},
|
|
1687
1892
|
},
|
|
1688
1893
|
{
|
|
1689
1894
|
id: "quality-limitation-bw",
|
|
1690
|
-
enabled: ({ hasLiveTrack, stats, client, kind }) => hasLiveTrack && client.isLocalClient && kind === "video" && stats,
|
|
1691
|
-
check: ({ stats }) =>
|
|
1895
|
+
enabled: ({ hasLiveTrack, stats, client, kind }) => hasLiveTrack && client.isLocalClient && kind === "video" && !!stats,
|
|
1896
|
+
check: ({ stats }) => {
|
|
1897
|
+
if (!stats)
|
|
1898
|
+
return false;
|
|
1899
|
+
return !!Object.values(stats.tracks).find((track) => Object.values(track.ssrcs).find((ssrc) => ssrc.qualityLimitationReason === "bandwidth"));
|
|
1900
|
+
},
|
|
1692
1901
|
},
|
|
1693
1902
|
{
|
|
1694
1903
|
id: "quality-limitation-cpu",
|
|
1695
|
-
enabled: ({ hasLiveTrack, stats, client, kind }) => hasLiveTrack && client.isLocalClient && kind === "video" && stats,
|
|
1696
|
-
check: ({ stats }) =>
|
|
1904
|
+
enabled: ({ hasLiveTrack, stats, client, kind }) => hasLiveTrack && client.isLocalClient && kind === "video" && !!stats,
|
|
1905
|
+
check: ({ stats }) => {
|
|
1906
|
+
if (!stats)
|
|
1907
|
+
return false;
|
|
1908
|
+
return !!Object.values(stats.tracks).find((track) => Object.values(track.ssrcs).find((ssrc) => ssrc.qualityLimitationReason === "cpu"));
|
|
1909
|
+
},
|
|
1697
1910
|
},
|
|
1698
1911
|
{
|
|
1699
1912
|
id: "high-plirate",
|
|
1700
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.height,
|
|
1701
|
-
check: ({ ssrc0 }) => ssrc0.pliRate > 2,
|
|
1913
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && !!ssrc0.height,
|
|
1914
|
+
check: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.pliRate) || 0) > 2,
|
|
1702
1915
|
},
|
|
1703
1916
|
{
|
|
1704
1917
|
id: "extreme-plirate",
|
|
1705
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.height,
|
|
1706
|
-
check: ({ ssrc0 }) => ssrc0.pliRate > 5,
|
|
1918
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && !!ssrc0.height,
|
|
1919
|
+
check: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.pliRate) || 0) > 5,
|
|
1707
1920
|
},
|
|
1708
1921
|
{
|
|
1709
1922
|
id: "high-packetloss",
|
|
1710
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.direction === "in",
|
|
1711
|
-
check: ({ ssrc0 }) => ssrc0.lossRatio > 0.02,
|
|
1923
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && ssrc0.direction === "in",
|
|
1924
|
+
check: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.lossRatio) || 0) > 0.02,
|
|
1712
1925
|
},
|
|
1713
1926
|
{
|
|
1714
1927
|
id: "extreme-packetloss",
|
|
1715
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.direction === "in",
|
|
1716
|
-
check: ({ ssrc0 }) => ssrc0.lossRatio > 0.1,
|
|
1928
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && ssrc0.direction === "in",
|
|
1929
|
+
check: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.lossRatio) || 0) > 0.1,
|
|
1717
1930
|
},
|
|
1718
1931
|
{
|
|
1719
1932
|
id: "high-packetloss",
|
|
1720
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.direction === "out",
|
|
1721
|
-
check: ({ ssrc0 }) => (ssrc0.fractionLost || 0) > 0.02,
|
|
1933
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && ssrc0.direction === "out",
|
|
1934
|
+
check: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.fractionLost) || 0) > 0.02,
|
|
1722
1935
|
},
|
|
1723
1936
|
{
|
|
1724
1937
|
id: "extreme-packetloss",
|
|
1725
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.direction === "out",
|
|
1726
|
-
check: ({ ssrc0 }) => (ssrc0.fractionLost || 0) > 0.1,
|
|
1938
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && ssrc0.direction === "out",
|
|
1939
|
+
check: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.fractionLost) || 0) > 0.1,
|
|
1727
1940
|
},
|
|
1728
1941
|
{
|
|
1729
1942
|
id: "fps-below-20",
|
|
1730
|
-
enabled: ({ hasLiveTrack, ssrc0, kind, client }) => hasLiveTrack && ssrc0 && ssrc0.height && kind === "video" && !client.isPresentation,
|
|
1731
|
-
check: ({ ssrc0 }) => ssrc0.height > 180 && ssrc0.fps < 20,
|
|
1943
|
+
enabled: ({ hasLiveTrack, ssrc0, kind, client }) => hasLiveTrack && !!ssrc0 && !!ssrc0.height && kind === "video" && !client.isPresentation,
|
|
1944
|
+
check: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.height) || 0) > 180 && ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.fps) || 0) < 20,
|
|
1732
1945
|
},
|
|
1733
1946
|
{
|
|
1734
1947
|
id: "fps-below-10",
|
|
1735
|
-
enabled: ({ hasLiveTrack, ssrc0, kind, client }) => hasLiveTrack && ssrc0 && ssrc0.height && kind === "video" && !client.isPresentation,
|
|
1736
|
-
check: ({ ssrc0 }) => ssrc0.fps < 10,
|
|
1948
|
+
enabled: ({ hasLiveTrack, ssrc0, kind, client }) => hasLiveTrack && !!ssrc0 && !!ssrc0.height && kind === "video" && !client.isPresentation,
|
|
1949
|
+
check: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.fps) || 0) < 10,
|
|
1737
1950
|
},
|
|
1738
1951
|
badNetworkIssueDetector,
|
|
1739
1952
|
periodicPacketLossDetector,
|
|
@@ -1741,28 +1954,37 @@ const issueDetectors = [
|
|
|
1741
1954
|
id: "cpu-pressure-serious",
|
|
1742
1955
|
global: true,
|
|
1743
1956
|
enabled: ({ stats }) => { var _a; return ((_a = stats === null || stats === void 0 ? void 0 : stats.pressure) === null || _a === void 0 ? void 0 : _a.source) === "cpu"; },
|
|
1744
|
-
check: ({ stats }) => stats.pressure.state === "serious",
|
|
1957
|
+
check: ({ stats }) => { var _a; return ((_a = stats === null || stats === void 0 ? void 0 : stats.pressure) === null || _a === void 0 ? void 0 : _a.state) === "serious"; },
|
|
1745
1958
|
},
|
|
1746
1959
|
{
|
|
1747
1960
|
id: "cpu-pressure-critical",
|
|
1748
1961
|
global: true,
|
|
1749
1962
|
enabled: ({ stats }) => { var _a; return ((_a = stats === null || stats === void 0 ? void 0 : stats.pressure) === null || _a === void 0 ? void 0 : _a.source) === "cpu"; },
|
|
1750
|
-
check: ({ stats }) => stats.pressure.state === "critical",
|
|
1963
|
+
check: ({ stats }) => { var _a; return ((_a = stats === null || stats === void 0 ? void 0 : stats.pressure) === null || _a === void 0 ? void 0 : _a.state) === "critical"; },
|
|
1751
1964
|
},
|
|
1752
1965
|
{
|
|
1753
1966
|
id: "concealed",
|
|
1754
|
-
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack && ssrc0 && kind === "audio",
|
|
1755
|
-
check: ({ ssrc0 }) => ssrc0
|
|
1967
|
+
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack && !!ssrc0 && kind === "audio",
|
|
1968
|
+
check: ({ ssrc0 }) => !!(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.bitrate) &&
|
|
1969
|
+
(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.direction) === "in" &&
|
|
1970
|
+
((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.audioLevel) || 0) >= 0.001 &&
|
|
1971
|
+
((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.audioConcealment) || 0) >= 0.1,
|
|
1756
1972
|
},
|
|
1757
1973
|
{
|
|
1758
1974
|
id: "decelerated",
|
|
1759
|
-
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack && ssrc0 && kind === "audio",
|
|
1760
|
-
check: ({ ssrc0 }) => ssrc0
|
|
1975
|
+
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack && !!ssrc0 && kind === "audio",
|
|
1976
|
+
check: ({ ssrc0 }) => !!(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.bitrate) &&
|
|
1977
|
+
ssrc0.direction === "in" &&
|
|
1978
|
+
(ssrc0.audioLevel || 0) >= 0.001 &&
|
|
1979
|
+
((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.audioDeceleration) || 0) >= 0.1,
|
|
1761
1980
|
},
|
|
1762
1981
|
{
|
|
1763
1982
|
id: "accelerated",
|
|
1764
|
-
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack && ssrc0 && kind === "audio",
|
|
1765
|
-
check: ({ ssrc0 }) => ssrc0
|
|
1983
|
+
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack && !!ssrc0 && kind === "audio",
|
|
1984
|
+
check: ({ ssrc0 }) => !!(ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.bitrate) &&
|
|
1985
|
+
ssrc0.direction === "in" &&
|
|
1986
|
+
(ssrc0.audioLevel || 0) >= 0.001 &&
|
|
1987
|
+
(ssrc0.audioAcceleration || 0) >= 0.1,
|
|
1766
1988
|
},
|
|
1767
1989
|
];
|
|
1768
1990
|
|
|
@@ -1771,41 +1993,41 @@ let stopStats = null;
|
|
|
1771
1993
|
const metrics = [
|
|
1772
1994
|
{
|
|
1773
1995
|
id: "bitrate",
|
|
1774
|
-
enabled: ({ hasLiveTrack, track, ssrc0 }) => hasLiveTrack && track && ssrc0,
|
|
1775
|
-
value: ({ trackStats }) => Object.values(trackStats.ssrcs).reduce((sum, ssrc) => sum + ssrc.bitrate, 0),
|
|
1996
|
+
enabled: ({ hasLiveTrack, track, ssrc0 }) => hasLiveTrack && !!track && !!ssrc0,
|
|
1997
|
+
value: ({ trackStats }) => Object.values((trackStats === null || trackStats === void 0 ? void 0 : trackStats.ssrcs) || {}).reduce((sum, ssrc) => sum + ((ssrc === null || ssrc === void 0 ? void 0 : ssrc.bitrate) || 0), 0),
|
|
1776
1998
|
},
|
|
1777
1999
|
{
|
|
1778
2000
|
id: "pixelrate",
|
|
1779
|
-
enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && track && ssrc0 && ssrc0.height,
|
|
1780
|
-
value: ({ trackStats }) => Object.values(trackStats.ssrcs).reduce((sum, ssrc) => sum + (ssrc.fps || 0) * (ssrc.width || 0) * (ssrc.height || 0), 0),
|
|
2001
|
+
enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!track && !!ssrc0 && !!ssrc0.height,
|
|
2002
|
+
value: ({ trackStats }) => Object.values((trackStats === null || trackStats === void 0 ? void 0 : trackStats.ssrcs) || {}).reduce((sum, ssrc) => sum + (ssrc.fps || 0) * (ssrc.width || 0) * (ssrc.height || 0), 0),
|
|
1781
2003
|
},
|
|
1782
2004
|
{
|
|
1783
2005
|
id: "height",
|
|
1784
|
-
enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && track && ssrc0 && ssrc0.height,
|
|
1785
|
-
value: ({ trackStats }) => Object.values(trackStats.ssrcs).reduce((max, ssrc) => Math.max(max, ssrc.fps > 0 ? ssrc.height : 0), 0),
|
|
2006
|
+
enabled: ({ hasLiveTrack, track, trackStats, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!trackStats && !!track && !!ssrc0 && !!ssrc0.height,
|
|
2007
|
+
value: ({ trackStats }) => Object.values((trackStats === null || trackStats === void 0 ? void 0 : trackStats.ssrcs) || {}).reduce((max, ssrc) => Math.max(max, ssrc.fps > 0 ? ssrc.height : 0), 0),
|
|
1786
2008
|
},
|
|
1787
2009
|
{
|
|
1788
2010
|
id: "sourceHeight",
|
|
1789
|
-
enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && track && ssrc0 && ssrc0.sourceHeight && ssrc0.direction === "out",
|
|
1790
|
-
value: ({ ssrc0 }) => ssrc0.sourceHeight,
|
|
2011
|
+
enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!track && !!ssrc0 && !!ssrc0.sourceHeight && ssrc0.direction === "out",
|
|
2012
|
+
value: ({ ssrc0 }) => ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.sourceHeight,
|
|
1791
2013
|
},
|
|
1792
2014
|
{
|
|
1793
2015
|
id: "packetloss",
|
|
1794
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.bitrate,
|
|
1795
|
-
value: ({ ssrc0 }) => (ssrc0.direction === "in" ? ssrc0.lossRatio : ssrc0.fractionLost) || 0,
|
|
2016
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && !!ssrc0.bitrate,
|
|
2017
|
+
value: ({ ssrc0 }) => ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.direction) === "in" ? ssrc0.lossRatio : ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.fractionLost) || 0,
|
|
1796
2018
|
},
|
|
1797
2019
|
{
|
|
1798
2020
|
id: "jitter",
|
|
1799
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.bitrate && ssrc0.direction === "in",
|
|
1800
|
-
value: ({ ssrc0 }) => ssrc0.jitter,
|
|
2021
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && !!ssrc0.bitrate && ssrc0.direction === "in",
|
|
2022
|
+
value: ({ ssrc0 }) => ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.jitter,
|
|
1801
2023
|
},
|
|
1802
2024
|
{
|
|
1803
2025
|
id: "mos",
|
|
1804
|
-
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && ssrc0 && ssrc0.bitrate && ssrc0.direction === "out",
|
|
2026
|
+
enabled: ({ hasLiveTrack, ssrc0 }) => hasLiveTrack && !!ssrc0 && !!ssrc0.bitrate && ssrc0.direction === "out",
|
|
1805
2027
|
value: ({ ssrc0 }) => {
|
|
1806
|
-
const averageLatency = ssrc0.roundTripTime || 0;
|
|
1807
|
-
const jitter = ssrc0.jitter || 0;
|
|
1808
|
-
const packetLoss = (ssrc0.fractionLost || 0) * 100;
|
|
2028
|
+
const averageLatency = (ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.roundTripTime) || 0;
|
|
2029
|
+
const jitter = (ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.jitter) || 0;
|
|
2030
|
+
const packetLoss = ((ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.fractionLost) || 0) * 100;
|
|
1809
2031
|
const effectiveLatency = averageLatency + jitter * 2 + 10;
|
|
1810
2032
|
let r = effectiveLatency < 160 ? 93.2 - effectiveLatency / 40 : 93.2 - (effectiveLatency - 120) / 10;
|
|
1811
2033
|
r = r - packetLoss * 2.5;
|
|
@@ -1825,54 +2047,54 @@ const metrics = [
|
|
|
1825
2047
|
id: "cpu-pressure",
|
|
1826
2048
|
global: true,
|
|
1827
2049
|
enabled: ({ stats }) => { var _a; return ((_a = stats === null || stats === void 0 ? void 0 : stats.pressure) === null || _a === void 0 ? void 0 : _a.source) === "cpu"; },
|
|
1828
|
-
value: ({ stats }) => ({ nominal: 0.25, fair: 0.5, serious: 0.75, critical: 1 })[stats.pressure.state] || 0,
|
|
2050
|
+
value: ({ stats }) => { var _a; return ({ nominal: 0.25, fair: 0.5, serious: 0.75, critical: 1 })[((_a = stats === null || stats === void 0 ? void 0 : stats.pressure) === null || _a === void 0 ? void 0 : _a.state) || ""] || 0; },
|
|
1829
2051
|
},
|
|
1830
2052
|
{
|
|
1831
2053
|
id: "turn-usage",
|
|
1832
2054
|
global: true,
|
|
1833
|
-
enabled: ({ stats }) => !!Object.values(stats.candidatePairs).length,
|
|
1834
|
-
value: ({ stats }) => Object.values(stats.candidatePairs).some((cp) => cp.usingTurn),
|
|
2055
|
+
enabled: ({ stats }) => !!Object.values((stats === null || stats === void 0 ? void 0 : stats.candidatePairs) || {}).length,
|
|
2056
|
+
value: ({ stats }) => Object.values((stats === null || stats === void 0 ? void 0 : stats.candidatePairs) || {}).some((cp) => cp.usingTurn),
|
|
1835
2057
|
},
|
|
1836
2058
|
{
|
|
1837
2059
|
id: "turn-tls-usage",
|
|
1838
2060
|
global: true,
|
|
1839
|
-
enabled: ({ stats }) => !!Object.values(stats.candidatePairs).length,
|
|
1840
|
-
value: ({ stats }) => Object.values(stats.candidatePairs).some((cp) => cp.turnProtocol === "tls"),
|
|
2061
|
+
enabled: ({ stats }) => !!Object.values((stats === null || stats === void 0 ? void 0 : stats.candidatePairs) || {}).length,
|
|
2062
|
+
value: ({ stats }) => Object.values((stats === null || stats === void 0 ? void 0 : stats.candidatePairs) || {}).some((cp) => cp.turnProtocol === "tls"),
|
|
1841
2063
|
},
|
|
1842
2064
|
{
|
|
1843
2065
|
id: "concealment",
|
|
1844
2066
|
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack &&
|
|
1845
|
-
ssrc0 &&
|
|
1846
|
-
ssrc0.bitrate &&
|
|
2067
|
+
!!ssrc0 &&
|
|
2068
|
+
!!ssrc0.bitrate &&
|
|
1847
2069
|
ssrc0.direction === "in" &&
|
|
1848
2070
|
kind === "audio" &&
|
|
1849
|
-
ssrc0.audioLevel >= 0.001,
|
|
1850
|
-
value: ({ ssrc0 }) => ssrc0.audioConcealment,
|
|
2071
|
+
(ssrc0.audioLevel || 0) >= 0.001,
|
|
2072
|
+
value: ({ ssrc0 }) => ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.audioConcealment,
|
|
1851
2073
|
},
|
|
1852
2074
|
{
|
|
1853
2075
|
id: "deceleration",
|
|
1854
2076
|
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack &&
|
|
1855
|
-
ssrc0 &&
|
|
1856
|
-
ssrc0.bitrate &&
|
|
2077
|
+
!!ssrc0 &&
|
|
2078
|
+
!!ssrc0.bitrate &&
|
|
1857
2079
|
ssrc0.direction === "in" &&
|
|
1858
2080
|
kind === "audio" &&
|
|
1859
|
-
ssrc0.audioLevel >= 0.001,
|
|
1860
|
-
value: ({ ssrc0 }) => ssrc0.audioDeceleration,
|
|
2081
|
+
(ssrc0.audioLevel || 0) >= 0.001,
|
|
2082
|
+
value: ({ ssrc0 }) => ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.audioDeceleration,
|
|
1861
2083
|
},
|
|
1862
2084
|
{
|
|
1863
2085
|
id: "acceleration",
|
|
1864
2086
|
enabled: ({ hasLiveTrack, ssrc0, kind }) => hasLiveTrack &&
|
|
1865
|
-
ssrc0 &&
|
|
1866
|
-
ssrc0.bitrate &&
|
|
2087
|
+
!!ssrc0 &&
|
|
2088
|
+
!!ssrc0.bitrate &&
|
|
1867
2089
|
ssrc0.direction === "in" &&
|
|
1868
2090
|
kind === "audio" &&
|
|
1869
|
-
ssrc0.audioLevel >= 0.001,
|
|
1870
|
-
value: ({ ssrc0 }) => ssrc0.audioAcceleration,
|
|
2091
|
+
(ssrc0.audioLevel || 0) >= 0.001,
|
|
2092
|
+
value: ({ ssrc0 }) => ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.audioAcceleration,
|
|
1871
2093
|
},
|
|
1872
2094
|
{
|
|
1873
2095
|
id: "qpf",
|
|
1874
|
-
enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && track && ssrc0 && ssrc0.height,
|
|
1875
|
-
value: ({ trackStats }) => Object.values(trackStats.ssrcs).reduce((sum, ssrc) => sum + (ssrc.qpf || 0), 0),
|
|
2096
|
+
enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!track && !!ssrc0 && !!ssrc0.height,
|
|
2097
|
+
value: ({ trackStats }) => Object.values((trackStats === null || trackStats === void 0 ? void 0 : trackStats.ssrcs) || {}).reduce((sum, ssrc) => sum + (ssrc.qpf || 0), 0),
|
|
1876
2098
|
},
|
|
1877
2099
|
];
|
|
1878
2100
|
let aggregatedMetrics;
|
|
@@ -2776,8 +2998,8 @@ class BandwidthTester extends EventEmitter {
|
|
|
2776
2998
|
}
|
|
2777
2999
|
}
|
|
2778
3000
|
|
|
2779
|
-
var _a$
|
|
2780
|
-
const adapter$5 = (_a$
|
|
3001
|
+
var _a$5;
|
|
3002
|
+
const adapter$5 = (_a$5 = adapterRaw.default) !== null && _a$5 !== void 0 ? _a$5 : adapterRaw;
|
|
2781
3003
|
function detectMicrophoneNotWorking(pc) {
|
|
2782
3004
|
if (adapter$5.browserDetails.browser !== "chrome" ||
|
|
2783
3005
|
adapter$5.browserDetails.browser < 58 ||
|
|
@@ -2812,8 +3034,8 @@ const MAXIMUM_TURN_BANDWIDTH = 1280;
|
|
|
2812
3034
|
const MAXIMUM_TURN_BANDWIDTH_UNLIMITED = -1;
|
|
2813
3035
|
const MEDIA_JITTER_BUFFER_TARGET = 400;
|
|
2814
3036
|
|
|
2815
|
-
var _a$
|
|
2816
|
-
const adapter$4 = (_a$
|
|
3037
|
+
var _a$4;
|
|
3038
|
+
const adapter$4 = (_a$4 = adapterRaw.default) !== null && _a$4 !== void 0 ? _a$4 : adapterRaw;
|
|
2817
3039
|
const isSafari = adapter$4.browserDetails.browser === "safari";
|
|
2818
3040
|
const parseResolution = (res) => res.split(/[^\d]/g).map((n) => parseInt(n, 10));
|
|
2819
3041
|
function getMediaConstraints({ disableAEC, disableAGC, hd, lax, lowDataMode, preferredDeviceIds, resolution, simulcast, widescreen, }) {
|
|
@@ -3192,178 +3414,6 @@ function getUpdatedDevices({ oldDevices, newDevices, currentAudioId, currentVide
|
|
|
3192
3414
|
return { addedDevices, changedDevices };
|
|
3193
3415
|
}
|
|
3194
3416
|
|
|
3195
|
-
var _a$4;
|
|
3196
|
-
(_a$4 = adapterRaw.default) !== null && _a$4 !== void 0 ? _a$4 : adapterRaw;
|
|
3197
|
-
const RTCSTATS_PROTOCOL_VERSION = "1.0";
|
|
3198
|
-
const GETSTATS_BUFFER_SIZE = 20;
|
|
3199
|
-
const clientInfo = {
|
|
3200
|
-
id: uuid.v4(),
|
|
3201
|
-
connectionNumber: 0,
|
|
3202
|
-
};
|
|
3203
|
-
const noop = () => { };
|
|
3204
|
-
let resetDelta = noop;
|
|
3205
|
-
function rtcStatsConnection(wsURL, logger = console) {
|
|
3206
|
-
const buffer = [];
|
|
3207
|
-
let ws;
|
|
3208
|
-
let organizationId;
|
|
3209
|
-
let clientId;
|
|
3210
|
-
let displayName;
|
|
3211
|
-
let userRole;
|
|
3212
|
-
let roomSessionId;
|
|
3213
|
-
let connectionShouldBeOpen;
|
|
3214
|
-
let connectionAttempt = 0;
|
|
3215
|
-
let hasPassedOnRoomSessionId = false;
|
|
3216
|
-
let getStatsBufferUsed = 0;
|
|
3217
|
-
let deviceId;
|
|
3218
|
-
let roomProduct;
|
|
3219
|
-
let roomMode;
|
|
3220
|
-
let sfuServer;
|
|
3221
|
-
let featureFlags;
|
|
3222
|
-
const connection = {
|
|
3223
|
-
connected: false,
|
|
3224
|
-
trace: (...args) => {
|
|
3225
|
-
args.push(Date.now());
|
|
3226
|
-
if (args[0] === "customEvent" && args[2].type === "roomSessionId") {
|
|
3227
|
-
const oldRoomSessionIdValue = roomSessionId && roomSessionId[2].value.roomSessionId;
|
|
3228
|
-
const newRoomSessionIdValue = args[2].value.roomSessionId;
|
|
3229
|
-
roomSessionId = args;
|
|
3230
|
-
if (hasPassedOnRoomSessionId &&
|
|
3231
|
-
newRoomSessionIdValue &&
|
|
3232
|
-
newRoomSessionIdValue !== oldRoomSessionIdValue) {
|
|
3233
|
-
ws === null || ws === void 0 ? void 0 : ws.close();
|
|
3234
|
-
}
|
|
3235
|
-
if (newRoomSessionIdValue)
|
|
3236
|
-
hasPassedOnRoomSessionId = true;
|
|
3237
|
-
}
|
|
3238
|
-
else if (args[0] === "customEvent" && args[2].type === "clientId") {
|
|
3239
|
-
clientId = args;
|
|
3240
|
-
}
|
|
3241
|
-
else if (args[0] === "customEvent" && args[2].type === "organizationId") {
|
|
3242
|
-
organizationId = args;
|
|
3243
|
-
}
|
|
3244
|
-
else if (args[0] === "customEvent" && args[2].type === "displayName") {
|
|
3245
|
-
displayName = args;
|
|
3246
|
-
}
|
|
3247
|
-
else if (args[0] === "customEvent" && args[2].type === "userRole") {
|
|
3248
|
-
userRole = args;
|
|
3249
|
-
}
|
|
3250
|
-
else if (args[0] === "customEvent" && args[2].type === "deviceId") {
|
|
3251
|
-
deviceId = args;
|
|
3252
|
-
}
|
|
3253
|
-
else if (args[0] === "customEvent" && args[2].type === "roomProduct") {
|
|
3254
|
-
roomProduct = args;
|
|
3255
|
-
}
|
|
3256
|
-
else if (args[0] === "customEvent" && args[2].type === "roomMode") {
|
|
3257
|
-
roomMode = args;
|
|
3258
|
-
}
|
|
3259
|
-
else if (args[0] === "customEvent" && args[2].type === "sfuServer") {
|
|
3260
|
-
sfuServer = args;
|
|
3261
|
-
}
|
|
3262
|
-
else if (args[0] === "customEvent" && args[2].type === "featureFlags") {
|
|
3263
|
-
featureFlags = args;
|
|
3264
|
-
}
|
|
3265
|
-
if ((ws === null || ws === void 0 ? void 0 : ws.readyState) === WebSocket.OPEN) {
|
|
3266
|
-
connectionAttempt = 0;
|
|
3267
|
-
ws.send(JSON.stringify(args));
|
|
3268
|
-
}
|
|
3269
|
-
else if (args[0] === "getstats") {
|
|
3270
|
-
if (getStatsBufferUsed < GETSTATS_BUFFER_SIZE) {
|
|
3271
|
-
getStatsBufferUsed++;
|
|
3272
|
-
buffer.push(args);
|
|
3273
|
-
}
|
|
3274
|
-
}
|
|
3275
|
-
else if (args[0] === "customEvent" && args[2].type === "insightsStats") ;
|
|
3276
|
-
else {
|
|
3277
|
-
buffer.push(args);
|
|
3278
|
-
}
|
|
3279
|
-
if ((ws === null || ws === void 0 ? void 0 : ws.readyState) === WebSocket.CLOSED && connectionShouldBeOpen) {
|
|
3280
|
-
setTimeout(() => {
|
|
3281
|
-
if (ws.readyState === WebSocket.CLOSED && connectionShouldBeOpen) {
|
|
3282
|
-
connection.connect();
|
|
3283
|
-
}
|
|
3284
|
-
}, 1000 * connectionAttempt);
|
|
3285
|
-
}
|
|
3286
|
-
},
|
|
3287
|
-
close: () => {
|
|
3288
|
-
connectionShouldBeOpen = false;
|
|
3289
|
-
ws === null || ws === void 0 ? void 0 : ws.close();
|
|
3290
|
-
},
|
|
3291
|
-
connect: () => {
|
|
3292
|
-
connectionShouldBeOpen = true;
|
|
3293
|
-
connectionAttempt += 1;
|
|
3294
|
-
ws === null || ws === void 0 ? void 0 : ws.close();
|
|
3295
|
-
connection.connected = true;
|
|
3296
|
-
ws = new WebSocket(wsURL + window.location.pathname, RTCSTATS_PROTOCOL_VERSION);
|
|
3297
|
-
ws.onerror = (e) => {
|
|
3298
|
-
connection.connected = false;
|
|
3299
|
-
logger.warn(`[RTCSTATS] WebSocket error`, e);
|
|
3300
|
-
};
|
|
3301
|
-
ws.onclose = (e) => {
|
|
3302
|
-
connection.connected = false;
|
|
3303
|
-
logger.info(`[RTCSTATS] Closed ${e.code}`);
|
|
3304
|
-
resetDelta();
|
|
3305
|
-
};
|
|
3306
|
-
ws.onopen = () => {
|
|
3307
|
-
clientInfo.connectionNumber++;
|
|
3308
|
-
ws.send(JSON.stringify(["clientInfo", null, clientInfo]));
|
|
3309
|
-
if (organizationId) {
|
|
3310
|
-
ws.send(JSON.stringify(organizationId));
|
|
3311
|
-
}
|
|
3312
|
-
if (clientId) {
|
|
3313
|
-
ws.send(JSON.stringify(clientId));
|
|
3314
|
-
}
|
|
3315
|
-
if (roomSessionId) {
|
|
3316
|
-
ws.send(JSON.stringify(roomSessionId));
|
|
3317
|
-
}
|
|
3318
|
-
if (displayName) {
|
|
3319
|
-
ws.send(JSON.stringify(displayName));
|
|
3320
|
-
}
|
|
3321
|
-
if (userRole) {
|
|
3322
|
-
ws.send(JSON.stringify(userRole));
|
|
3323
|
-
}
|
|
3324
|
-
if (deviceId) {
|
|
3325
|
-
ws.send(JSON.stringify(deviceId));
|
|
3326
|
-
}
|
|
3327
|
-
if (roomMode) {
|
|
3328
|
-
ws.send(JSON.stringify(roomMode));
|
|
3329
|
-
}
|
|
3330
|
-
if (roomProduct) {
|
|
3331
|
-
ws.send(JSON.stringify(roomProduct));
|
|
3332
|
-
}
|
|
3333
|
-
if (sfuServer) {
|
|
3334
|
-
ws.send(JSON.stringify(sfuServer));
|
|
3335
|
-
}
|
|
3336
|
-
if (featureFlags) {
|
|
3337
|
-
ws.send(JSON.stringify(featureFlags));
|
|
3338
|
-
}
|
|
3339
|
-
while (buffer.length) {
|
|
3340
|
-
ws.send(JSON.stringify(buffer.shift()));
|
|
3341
|
-
}
|
|
3342
|
-
getStatsBufferUsed = 0;
|
|
3343
|
-
};
|
|
3344
|
-
},
|
|
3345
|
-
};
|
|
3346
|
-
return connection;
|
|
3347
|
-
}
|
|
3348
|
-
const server = rtcStatsConnection(process.env.RTCSTATS_URL || "wss://rtcstats.srv.whereby.com");
|
|
3349
|
-
const stats = rtcstats(server.trace, 10000, [""]);
|
|
3350
|
-
resetDelta = (stats === null || stats === void 0 ? void 0 : stats.resetDelta) || noop;
|
|
3351
|
-
const rtcStats = {
|
|
3352
|
-
sendEvent: (type, value) => {
|
|
3353
|
-
server.trace("customEvent", null, {
|
|
3354
|
-
type,
|
|
3355
|
-
value,
|
|
3356
|
-
});
|
|
3357
|
-
},
|
|
3358
|
-
sendAudioMuted: (muted) => {
|
|
3359
|
-
rtcStats.sendEvent("audio_muted", { muted });
|
|
3360
|
-
},
|
|
3361
|
-
sendVideoMuted: (muted) => {
|
|
3362
|
-
rtcStats.sendEvent("video_muted", { muted });
|
|
3363
|
-
},
|
|
3364
|
-
server,
|
|
3365
|
-
};
|
|
3366
|
-
|
|
3367
3417
|
var _a$3;
|
|
3368
3418
|
const adapter$3 = (_a$3 = adapterRaw.default) !== null && _a$3 !== void 0 ? _a$3 : adapterRaw;
|
|
3369
3419
|
const logger$5 = new Logger();
|
|
@@ -4896,7 +4946,8 @@ class P2pRtcManager {
|
|
|
4896
4946
|
if (!session.publicHostCandidateSeen &&
|
|
4897
4947
|
!session.relayCandidateSeen &&
|
|
4898
4948
|
!session.serverReflexiveCandidateSeen) {
|
|
4899
|
-
|
|
4949
|
+
if (pc.iceConnectionState !== "connected" || pc.iceConnectionState !== "completed")
|
|
4950
|
+
this._emit(rtcManagerEvents.ICE_NO_PUBLIC_IP_GATHERED_3SEC);
|
|
4900
4951
|
}
|
|
4901
4952
|
}, ICE_PUBLIC_IP_GATHERING_TIMEOUT);
|
|
4902
4953
|
break;
|
|
@@ -4966,7 +5017,9 @@ class P2pRtcManager {
|
|
|
4966
5017
|
});
|
|
4967
5018
|
if (!session.publicHostCandidateSeen &&
|
|
4968
5019
|
!session.relayCandidateSeen &&
|
|
4969
|
-
!session.serverReflexiveCandidateSeen
|
|
5020
|
+
!session.serverReflexiveCandidateSeen &&
|
|
5021
|
+
pc.iceConnectionState !== "connected" &&
|
|
5022
|
+
pc.iceConnectionState !== "completed") {
|
|
4970
5023
|
this._emit(rtcManagerEvents.ICE_NO_PUBLIC_IP_GATHERED);
|
|
4971
5024
|
}
|
|
4972
5025
|
if (session.ipv6HostCandidateSeen) {
|
|
@@ -6976,6 +7029,9 @@ exports.getHandler = getHandler;
|
|
|
6976
7029
|
exports.getIssuesAndMetrics = getIssuesAndMetrics;
|
|
6977
7030
|
exports.getMediaConstraints = getMediaConstraints;
|
|
6978
7031
|
exports.getMediaSettings = getMediaSettings;
|
|
7032
|
+
exports.getNumFailedStatsReports = getNumFailedStatsReports;
|
|
7033
|
+
exports.getNumFailedTrackSsrcLookups = getNumFailedTrackSsrcLookups;
|
|
7034
|
+
exports.getNumMissingTrackSsrcLookups = getNumMissingTrackSsrcLookups;
|
|
6979
7035
|
exports.getOptimalBitrate = getOptimalBitrate;
|
|
6980
7036
|
exports.getPeerConnectionIndex = getPeerConnectionIndex;
|
|
6981
7037
|
exports.getStats = getStats;
|