@whereby.com/media 9.2.7 → 9.3.1
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 +137 -18
- package/dist/index.d.cts +23 -3
- package/dist/index.d.mts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.mjs +137 -19
- package/dist/legacy-esm.js +137 -19
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -221,9 +221,22 @@ function rtcStatsConnection(wsURL, logger = console) {
|
|
|
221
221
|
return connection;
|
|
222
222
|
}
|
|
223
223
|
const RTCSTATS_URL = "wss://rtcstats.srv.whereby.com";
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
const noopServer = {
|
|
225
|
+
connected: false,
|
|
226
|
+
attemptedConnectedAtLeastOnce: false,
|
|
227
|
+
trace: noop,
|
|
228
|
+
close: noop,
|
|
229
|
+
connect: noop,
|
|
230
|
+
};
|
|
231
|
+
let server;
|
|
232
|
+
if (typeof window !== "undefined") {
|
|
233
|
+
server = rtcStatsConnection(RTCSTATS_URL);
|
|
234
|
+
const stats = rtcstats(server.trace, 10000, [""]);
|
|
235
|
+
resetDelta = (stats === null || stats === void 0 ? void 0 : stats.resetDelta) || noop;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
server = noopServer;
|
|
239
|
+
}
|
|
227
240
|
const rtcStats = {
|
|
228
241
|
sendEvent: (type, value) => {
|
|
229
242
|
server.trace("customEvent", null, {
|
|
@@ -240,7 +253,7 @@ const rtcStats = {
|
|
|
240
253
|
server,
|
|
241
254
|
};
|
|
242
255
|
|
|
243
|
-
const debugOn = new URLSearchParams(window.location.search).has("debug");
|
|
256
|
+
const debugOn = (typeof window !== "undefined" && new URLSearchParams(window.location.search).has("debug"));
|
|
244
257
|
class Logger {
|
|
245
258
|
constructor() {
|
|
246
259
|
this._isEnabled = false;
|
|
@@ -1442,6 +1455,8 @@ function captureVideoSsrcMetrics(ssrcMetrics, currentSsrcStats, prevSsrcStats, t
|
|
|
1442
1455
|
const qpsumDiff = currentSsrcStats.qpSum - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.qpSum) || 0);
|
|
1443
1456
|
ssrcMetrics.qpf = qpsumDiff / frameCountDiff;
|
|
1444
1457
|
ssrcMetrics.fps = (frameCountDiff * 1000) / timeDiff;
|
|
1458
|
+
const freezeCountDiff = (currentSsrcStats.freezeCount || 0) - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.freezeCount) || 0);
|
|
1459
|
+
ssrcMetrics.freezeRate = (freezeCountDiff * 1000) / timeDiff;
|
|
1445
1460
|
}
|
|
1446
1461
|
else {
|
|
1447
1462
|
const kfCountDiff = currentSsrcStats.keyFramesEncoded - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.keyFramesEncoded) || 0);
|
|
@@ -1471,7 +1486,7 @@ const peerConnectionData = new WeakMap();
|
|
|
1471
1486
|
const removePeerConnection = (pc) => {
|
|
1472
1487
|
peerConnections = peerConnections.filter((old) => old !== pc);
|
|
1473
1488
|
};
|
|
1474
|
-
if (window.RTCPeerConnection) {
|
|
1489
|
+
if (typeof window !== "undefined" && window.RTCPeerConnection) {
|
|
1475
1490
|
const OriginalRTCPeerConnection = window.RTCPeerConnection;
|
|
1476
1491
|
function PatchedRTCPeerConnection(rtcConfig) {
|
|
1477
1492
|
const pc = new OriginalRTCPeerConnection(rtcConfig);
|
|
@@ -1587,15 +1602,17 @@ const getOrCreateSsrcMetricsContainer = (statsByView, time, pcIndex, clientId, t
|
|
|
1587
1602
|
ssrcStats.updated = time;
|
|
1588
1603
|
return ssrcStats;
|
|
1589
1604
|
};
|
|
1590
|
-
const removeNonUpdatedStats = (statsByView, time) => {
|
|
1605
|
+
const removeNonUpdatedStats = (statsByView, time, renderedDimensionsByTrack) => {
|
|
1591
1606
|
Object.entries(statsByView).forEach(([viewId, viewStats]) => {
|
|
1592
1607
|
if (viewStats.updated !== undefined && viewStats.updated < time) {
|
|
1608
|
+
Object.keys(viewStats.tracks).forEach((trackId) => delete renderedDimensionsByTrack[trackId]);
|
|
1593
1609
|
delete statsByView[viewId];
|
|
1594
1610
|
}
|
|
1595
1611
|
else {
|
|
1596
1612
|
Object.entries(viewStats.tracks).forEach(([trackId, trackStats]) => {
|
|
1597
1613
|
if (trackStats.updated < time) {
|
|
1598
1614
|
delete viewStats.tracks[trackId];
|
|
1615
|
+
delete renderedDimensionsByTrack[trackId];
|
|
1599
1616
|
}
|
|
1600
1617
|
else {
|
|
1601
1618
|
Object.entries(trackStats.ssrcs).forEach(([ssrc, ssrcStats]) => {
|
|
@@ -1633,7 +1650,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1633
1650
|
if (timeSinceLastUpdate < 400) {
|
|
1634
1651
|
if (immediate)
|
|
1635
1652
|
return state.statsByView;
|
|
1636
|
-
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients); });
|
|
1653
|
+
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients, state.renderedDimensionsByTrack); });
|
|
1637
1654
|
state.nextTimeout = setTimeout(collectStatsBound, interval);
|
|
1638
1655
|
return;
|
|
1639
1656
|
}
|
|
@@ -1726,7 +1743,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1726
1743
|
}
|
|
1727
1744
|
});
|
|
1728
1745
|
});
|
|
1729
|
-
removeNonUpdatedStats(state.statsByView, state.lastUpdateTime);
|
|
1746
|
+
removeNonUpdatedStats(state.statsByView, state.lastUpdateTime, state.renderedDimensionsByTrack);
|
|
1730
1747
|
Object.entries((defaultViewStats === null || defaultViewStats === void 0 ? void 0 : defaultViewStats.candidatePairs) || {}).forEach(([cpKey, cp]) => {
|
|
1731
1748
|
const active = cp.lastRtcStatsTime === state.lastUpdateTime;
|
|
1732
1749
|
cp.active = active;
|
|
@@ -1745,7 +1762,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1745
1762
|
return state.statsByView;
|
|
1746
1763
|
}
|
|
1747
1764
|
else {
|
|
1748
|
-
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients); });
|
|
1765
|
+
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients, state.renderedDimensionsByTrack); });
|
|
1749
1766
|
}
|
|
1750
1767
|
}
|
|
1751
1768
|
catch (e) {
|
|
@@ -1784,6 +1801,7 @@ const STATE = {
|
|
|
1784
1801
|
currentMonitor: null,
|
|
1785
1802
|
getClients: () => [],
|
|
1786
1803
|
lastUpdateTime: 0,
|
|
1804
|
+
renderedDimensionsByTrack: {},
|
|
1787
1805
|
statsByView: {},
|
|
1788
1806
|
subscriptions: [],
|
|
1789
1807
|
numFailedStatsReports: 0,
|
|
@@ -1802,6 +1820,9 @@ const getNumMissingTrackSsrcLookups = () => numMissingTrackSsrcLookups;
|
|
|
1802
1820
|
const getNumFailedTrackSsrcLookups = () => numFailedTrackSsrcLookups;
|
|
1803
1821
|
const getUpdatedStats = () => { var _a; return (_a = STATE.currentMonitor) === null || _a === void 0 ? void 0 : _a.getUpdatedStats(); };
|
|
1804
1822
|
const setClientProvider = (provider) => (STATE.getClients = provider);
|
|
1823
|
+
const updateRenderedDimensions = (trackId, data) => {
|
|
1824
|
+
STATE.renderedDimensionsByTrack[trackId] = data;
|
|
1825
|
+
};
|
|
1805
1826
|
function startStatsMonitor(state, { interval, logger }) {
|
|
1806
1827
|
const collectStatsBound = collectStats.bind(null, state, { interval, logger });
|
|
1807
1828
|
let cpuObserver;
|
|
@@ -2423,7 +2444,7 @@ function fromLocation({ host = "whereby.com", protocol = "https:" } = {}) {
|
|
|
2423
2444
|
subdomain,
|
|
2424
2445
|
};
|
|
2425
2446
|
}
|
|
2426
|
-
fromLocation(window
|
|
2447
|
+
fromLocation(typeof window !== "undefined" ? window.location : undefined);
|
|
2427
2448
|
|
|
2428
2449
|
var _a$2, _b$1;
|
|
2429
2450
|
const adapter$2 = (_a$2 = adapterRaw.default) !== null && _a$2 !== void 0 ? _a$2 : adapterRaw;
|
|
@@ -2522,6 +2543,7 @@ class P2pRtcManager {
|
|
|
2522
2543
|
this._features = features || {};
|
|
2523
2544
|
this._isAudioOnlyMode = false;
|
|
2524
2545
|
this._closed = false;
|
|
2546
|
+
this._videoTrackIdByStreamId = {};
|
|
2525
2547
|
this._fetchMediaServersTimer = null;
|
|
2526
2548
|
this._stopCameraTimeout = null;
|
|
2527
2549
|
this._icePublicIPGatheringTimeoutID = null;
|
|
@@ -3002,6 +3024,8 @@ class P2pRtcManager {
|
|
|
3002
3024
|
});
|
|
3003
3025
|
return;
|
|
3004
3026
|
}
|
|
3027
|
+
if (event.track.kind === "video")
|
|
3028
|
+
this._videoTrackIdByStreamId[stream.id] = event.track.id;
|
|
3005
3029
|
if (session.streamIds.indexOf(stream.id) === -1) {
|
|
3006
3030
|
session.streamIds.push(stream.id);
|
|
3007
3031
|
this._emit(EVENTS.STREAM_ADDED, {
|
|
@@ -3432,7 +3456,11 @@ class P2pRtcManager {
|
|
|
3432
3456
|
}, 60 * 1000);
|
|
3433
3457
|
}
|
|
3434
3458
|
}
|
|
3435
|
-
updateStreamResolution(
|
|
3459
|
+
updateStreamResolution(streamId, _ignored, { width, height, }) {
|
|
3460
|
+
const trackId = this._videoTrackIdByStreamId[streamId];
|
|
3461
|
+
if (trackId)
|
|
3462
|
+
updateRenderedDimensions(trackId, { width, height, time: Date.now() });
|
|
3463
|
+
}
|
|
3436
3464
|
stopOrResumeAudio() {
|
|
3437
3465
|
}
|
|
3438
3466
|
_handleStopOrResumeVideo({ enable, track }) {
|
|
@@ -5573,7 +5601,7 @@ class VegaRtcManager {
|
|
|
5573
5601
|
this._syncIncomingStreamsWithPWA(clientId);
|
|
5574
5602
|
}
|
|
5575
5603
|
updateStreamResolution(streamId, _ignored, { width, height, }) {
|
|
5576
|
-
var _a, _b;
|
|
5604
|
+
var _a, _b, _c;
|
|
5577
5605
|
logger$2.info("updateStreamResolution()", { streamId, width, height });
|
|
5578
5606
|
const consumerId = this._streamIdToVideoConsumerId.get(streamId);
|
|
5579
5607
|
const consumer = this._consumers.get(consumerId);
|
|
@@ -5581,17 +5609,18 @@ class VegaRtcManager {
|
|
|
5581
5609
|
this._streamIdToVideoResolution.set(streamId, { width, height });
|
|
5582
5610
|
return;
|
|
5583
5611
|
}
|
|
5612
|
+
updateRenderedDimensions((_a = consumer.track) === null || _a === void 0 ? void 0 : _a.id, { width, height, time: Date.now() });
|
|
5584
5613
|
const numberOfActiveVideos = getNumberOfActiveVideos(this._consumers);
|
|
5585
5614
|
const numberOfTemporalLayers = getNumberOfTemporalLayers(consumer);
|
|
5586
5615
|
const { spatialLayer, temporalLayer } = getLayers({ width, height }, {
|
|
5587
5616
|
numberOfActiveVideos,
|
|
5588
5617
|
numberOfTemporalLayers,
|
|
5589
|
-
uncappedSingleRemoteVideoOn: (
|
|
5618
|
+
uncappedSingleRemoteVideoOn: (_b = this._features) === null || _b === void 0 ? void 0 : _b.uncappedSingleRemoteVideoOn,
|
|
5590
5619
|
});
|
|
5591
5620
|
if (consumer.appData.spatialLayer !== spatialLayer || consumer.appData.temporalLayer !== temporalLayer) {
|
|
5592
5621
|
consumer.appData.spatialLayer = spatialLayer;
|
|
5593
5622
|
consumer.appData.temporalLayer = temporalLayer;
|
|
5594
|
-
(
|
|
5623
|
+
(_c = this._vegaConnection) === null || _c === void 0 ? void 0 : _c.message("setConsumersPreferredLayers", {
|
|
5595
5624
|
consumerIds: [consumerId],
|
|
5596
5625
|
spatialLayer,
|
|
5597
5626
|
temporalLayer,
|
|
@@ -6006,6 +6035,92 @@ const getRoomMode = () => {
|
|
|
6006
6035
|
return roomMode;
|
|
6007
6036
|
};
|
|
6008
6037
|
|
|
6038
|
+
const createQualityDetector = (type) => {
|
|
6039
|
+
return {
|
|
6040
|
+
id: `quality-${type}`,
|
|
6041
|
+
enabled: ({ client }) => !client.isLocalClient && !client.isPresentation,
|
|
6042
|
+
check: ({ ssrc0, renderedDimensions, hasLiveTrack, kind }) => {
|
|
6043
|
+
if (!hasLiveTrack)
|
|
6044
|
+
return true;
|
|
6045
|
+
if (!ssrc0)
|
|
6046
|
+
return true;
|
|
6047
|
+
if (!ssrc0.bitrate)
|
|
6048
|
+
return true;
|
|
6049
|
+
if (kind === "video") {
|
|
6050
|
+
if (renderedDimensions && renderedDimensions.width && renderedDimensions.height) {
|
|
6051
|
+
const maxSideRendered = Math.max(renderedDimensions.width, renderedDimensions.height);
|
|
6052
|
+
const maxSideReceived = Math.max(ssrc0.width || 0, ssrc0.height || 0);
|
|
6053
|
+
const fpsReceived = ssrc0.fps || 0;
|
|
6054
|
+
const hadFreeze = !!ssrc0.freezeRate;
|
|
6055
|
+
const bitrate = ssrc0.bitrate || 0;
|
|
6056
|
+
if (maxSideRendered < 100) {
|
|
6057
|
+
if (type === "warning" && maxSideReceived < 160)
|
|
6058
|
+
return true;
|
|
6059
|
+
if (type === "critical" && maxSideReceived < 90)
|
|
6060
|
+
return true;
|
|
6061
|
+
if (type === "warning" && fpsReceived < 5)
|
|
6062
|
+
return true;
|
|
6063
|
+
if (type === "critical" && fpsReceived < 2)
|
|
6064
|
+
return true;
|
|
6065
|
+
if (type === "warning" && bitrate < 10000)
|
|
6066
|
+
return true;
|
|
6067
|
+
if (type === "critical" && bitrate < 5000)
|
|
6068
|
+
return true;
|
|
6069
|
+
}
|
|
6070
|
+
else if (maxSideRendered < 480) {
|
|
6071
|
+
if (type === "warning" && maxSideReceived < 240)
|
|
6072
|
+
return true;
|
|
6073
|
+
if (type === "critical" && maxSideReceived < 120)
|
|
6074
|
+
return true;
|
|
6075
|
+
if (type === "warning" && fpsReceived < 14)
|
|
6076
|
+
return true;
|
|
6077
|
+
if (type === "critical" && fpsReceived < 9)
|
|
6078
|
+
return true;
|
|
6079
|
+
if (hadFreeze)
|
|
6080
|
+
return true;
|
|
6081
|
+
if (type === "warning" && bitrate < 50000)
|
|
6082
|
+
return true;
|
|
6083
|
+
if (type === "critical" && bitrate < 20000)
|
|
6084
|
+
return true;
|
|
6085
|
+
}
|
|
6086
|
+
else {
|
|
6087
|
+
if (type === "warning" && maxSideReceived < 480)
|
|
6088
|
+
return true;
|
|
6089
|
+
if (type === "critical" && maxSideReceived < 240)
|
|
6090
|
+
return true;
|
|
6091
|
+
if (type === "warning" && fpsReceived < 14)
|
|
6092
|
+
return true;
|
|
6093
|
+
if (type === "critical" && fpsReceived < 9)
|
|
6094
|
+
return true;
|
|
6095
|
+
if (type === "warning" && bitrate < 200000)
|
|
6096
|
+
return true;
|
|
6097
|
+
if (type === "critical" && bitrate < 50000)
|
|
6098
|
+
return true;
|
|
6099
|
+
if (hadFreeze)
|
|
6100
|
+
return true;
|
|
6101
|
+
}
|
|
6102
|
+
}
|
|
6103
|
+
}
|
|
6104
|
+
else if (kind === "audio") {
|
|
6105
|
+
const audioLevel = ssrc0.audioLevel || 0;
|
|
6106
|
+
const concealment = ssrc0.audioConcealment || 0;
|
|
6107
|
+
const acceleration = ssrc0.audioAcceleration || 0;
|
|
6108
|
+
const deceleration = ssrc0.audioDeceleration || 0;
|
|
6109
|
+
const audioDistortion = concealment + acceleration + deceleration;
|
|
6110
|
+
if (audioLevel >= 0.01) {
|
|
6111
|
+
if (type === "warning" && audioDistortion > 0.1)
|
|
6112
|
+
return true;
|
|
6113
|
+
if (type === "critical" && audioDistortion > 0.2)
|
|
6114
|
+
return true;
|
|
6115
|
+
}
|
|
6116
|
+
}
|
|
6117
|
+
return false;
|
|
6118
|
+
},
|
|
6119
|
+
};
|
|
6120
|
+
};
|
|
6121
|
+
const qualityWarningDetector = createQualityDetector("warning");
|
|
6122
|
+
const qualityCriticalDetector = createQualityDetector("critical");
|
|
6123
|
+
|
|
6009
6124
|
const badNetworkIssueDetector = {
|
|
6010
6125
|
id: "bad-network",
|
|
6011
6126
|
enabled: ({ hasLiveTrack, ssrcs }) => hasLiveTrack && ssrcs.length > 0,
|
|
@@ -6229,6 +6344,8 @@ const issueDetectors = [
|
|
|
6229
6344
|
(ssrc0.audioLevel || 0) >= 0.001 &&
|
|
6230
6345
|
(ssrc0.audioAcceleration || 0) >= 0.1,
|
|
6231
6346
|
},
|
|
6347
|
+
qualityWarningDetector,
|
|
6348
|
+
qualityCriticalDetector,
|
|
6232
6349
|
];
|
|
6233
6350
|
|
|
6234
6351
|
let subscriptions = [];
|
|
@@ -6383,7 +6500,7 @@ function issueDetectorOrMetricEnabled(issueDetectorOrMetric, checkData) {
|
|
|
6383
6500
|
}
|
|
6384
6501
|
return enabled && (issueDetectorOrMetric.enabled ? issueDetectorOrMetric.enabled(checkData) : true);
|
|
6385
6502
|
}
|
|
6386
|
-
function onUpdatedStats(statsByView, clients) {
|
|
6503
|
+
function onUpdatedStats(statsByView, clients, renderedDimensionsByTrack) {
|
|
6387
6504
|
Object.values(aggregatedMetrics).forEach((metricData) => {
|
|
6388
6505
|
metricData.curTicks = 0;
|
|
6389
6506
|
metricData.curSum = 0;
|
|
@@ -6421,6 +6538,7 @@ function onUpdatedStats(statsByView, clients) {
|
|
|
6421
6538
|
kind,
|
|
6422
6539
|
track,
|
|
6423
6540
|
trackStats,
|
|
6541
|
+
renderedDimensions: (track === null || track === void 0 ? void 0 : track.id) ? renderedDimensionsByTrack[track.id] : undefined,
|
|
6424
6542
|
stats,
|
|
6425
6543
|
hasLiveTrack,
|
|
6426
6544
|
ssrc0,
|
|
@@ -7063,7 +7181,7 @@ class BandwidthTester extends EventEmitter {
|
|
|
7063
7181
|
}
|
|
7064
7182
|
|
|
7065
7183
|
const logger = new Logger();
|
|
7066
|
-
const isMobile = /mobi/i.test(navigator.userAgent);
|
|
7184
|
+
const isMobile = typeof navigator !== "undefined" && /mobi/i.test(navigator.userAgent);
|
|
7067
7185
|
class NoDevicesError extends Error {
|
|
7068
7186
|
constructor(...args) {
|
|
7069
7187
|
super(...args);
|
|
@@ -7321,8 +7439,8 @@ function hasGetDisplayMedia() {
|
|
|
7321
7439
|
}
|
|
7322
7440
|
const defaultDisplayMediaConstraints = {
|
|
7323
7441
|
video: {
|
|
7324
|
-
width: { max: window.screen.width },
|
|
7325
|
-
height: { max: window.screen.height },
|
|
7442
|
+
width: { max: typeof window !== "undefined" ? window.screen.width : 0 },
|
|
7443
|
+
height: { max: typeof window !== "undefined" ? window.screen.height : 0 },
|
|
7326
7444
|
},
|
|
7327
7445
|
};
|
|
7328
7446
|
function getDisplayMedia(constraints = defaultDisplayMediaConstraints, contentHint = "detail") {
|
|
@@ -7513,5 +7631,6 @@ exports.subscribeIssues = subscribeIssues;
|
|
|
7513
7631
|
exports.subscribeStats = subscribeStats;
|
|
7514
7632
|
exports.trackAnnotations = trackAnnotations;
|
|
7515
7633
|
exports.turnServerOverride = turnServerOverride;
|
|
7634
|
+
exports.updateRenderedDimensions = updateRenderedDimensions;
|
|
7516
7635
|
exports.variance = variance;
|
|
7517
7636
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
CHANGED
|
@@ -27,10 +27,16 @@ type PressureRecord = {
|
|
|
27
27
|
state: string;
|
|
28
28
|
time: number;
|
|
29
29
|
};
|
|
30
|
+
type RenderedDimensionsReport = {
|
|
31
|
+
time: number;
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
};
|
|
30
35
|
interface TrackStats {
|
|
31
36
|
startTime: number;
|
|
32
37
|
updated: number;
|
|
33
38
|
ssrcs: Record<string, SsrcStats>;
|
|
39
|
+
renderedDimensions?: RenderedDimensionsReport;
|
|
34
40
|
}
|
|
35
41
|
interface ViewStats {
|
|
36
42
|
startTime?: number;
|
|
@@ -93,6 +99,7 @@ interface SsrcStats {
|
|
|
93
99
|
encodeTime?: number;
|
|
94
100
|
sourceWidth?: number;
|
|
95
101
|
sourceFps?: number;
|
|
102
|
+
freezeRate?: number;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
interface IssueDetector {
|
|
@@ -106,6 +113,7 @@ interface IssueCheckData {
|
|
|
106
113
|
clients: StatsClient[];
|
|
107
114
|
kind: string;
|
|
108
115
|
track: MediaStreamTrack | MediaStreamTrackWithDenoiserContext | undefined;
|
|
116
|
+
renderedDimensions?: RenderedDimensionsReport;
|
|
109
117
|
trackStats?: TrackStats;
|
|
110
118
|
stats?: ViewStats;
|
|
111
119
|
hasLiveTrack: boolean;
|
|
@@ -236,7 +244,7 @@ interface StatsMonitor {
|
|
|
236
244
|
stop: () => void;
|
|
237
245
|
}
|
|
238
246
|
interface StatsSubscription {
|
|
239
|
-
onUpdatedStats: (statsByView: Record<string, ViewStats>, clients: StatsClient[]) => void;
|
|
247
|
+
onUpdatedStats: (statsByView: Record<string, ViewStats>, clients: StatsClient[], renderedDimensionsByTrack: Record<string, RenderedDimensionsReport>) => void;
|
|
240
248
|
}
|
|
241
249
|
interface StatsMonitorState {
|
|
242
250
|
currentMonitor: StatsMonitor | null;
|
|
@@ -245,6 +253,7 @@ interface StatsMonitorState {
|
|
|
245
253
|
lastUpdateTime: number;
|
|
246
254
|
nextTimeout?: number;
|
|
247
255
|
pressureObserver?: PressureObserver;
|
|
256
|
+
renderedDimensionsByTrack: Record<string, RenderedDimensionsReport>;
|
|
248
257
|
statsByView: Record<string, ViewStats>;
|
|
249
258
|
subscriptions: StatsSubscription[];
|
|
250
259
|
numFailedStatsReports: number;
|
|
@@ -261,6 +270,7 @@ declare const getNumMissingTrackSsrcLookups: () => number;
|
|
|
261
270
|
declare const getNumFailedTrackSsrcLookups: () => number;
|
|
262
271
|
declare const getUpdatedStats: () => Promise<Record<string, ViewStats> | undefined> | undefined;
|
|
263
272
|
declare const setClientProvider: (provider: () => StatsClient[]) => () => StatsClient[];
|
|
273
|
+
declare const updateRenderedDimensions: (trackId: string, data: RenderedDimensionsReport) => void;
|
|
264
274
|
declare function subscribeStats(subscription: StatsSubscription, options?: StatsMonitorOptions, state?: StatsMonitorState): {
|
|
265
275
|
stop(): void;
|
|
266
276
|
};
|
|
@@ -1641,6 +1651,7 @@ declare class P2pRtcManager implements RtcManager {
|
|
|
1641
1651
|
analytics: P2PAnalytics;
|
|
1642
1652
|
_rtcStatsDisconnectTimeout?: ReturnType<typeof setTimeout>;
|
|
1643
1653
|
_webcamPaused?: boolean;
|
|
1654
|
+
_videoTrackIdByStreamId: Record<string, string>;
|
|
1644
1655
|
constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features }: RtcManagerOptions);
|
|
1645
1656
|
numberOfPeerconnections(): number;
|
|
1646
1657
|
isInitializedWith({ selfId, roomName, isSfu }: {
|
|
@@ -1693,7 +1704,10 @@ declare class P2pRtcManager implements RtcManager {
|
|
|
1693
1704
|
clientId: string;
|
|
1694
1705
|
}): Session;
|
|
1695
1706
|
disconnect(clientId: string): void;
|
|
1696
|
-
updateStreamResolution(
|
|
1707
|
+
updateStreamResolution(streamId: string, _ignored: any, { width, height, }: {
|
|
1708
|
+
width: number;
|
|
1709
|
+
height: number;
|
|
1710
|
+
}): void;
|
|
1697
1711
|
stopOrResumeAudio(): void;
|
|
1698
1712
|
_handleStopOrResumeVideo({ enable, track }: {
|
|
1699
1713
|
enable: boolean;
|
|
@@ -1745,6 +1759,12 @@ declare const rtcStats: {
|
|
|
1745
1759
|
trace: (...args: any) => void;
|
|
1746
1760
|
close: () => void;
|
|
1747
1761
|
connect: () => void;
|
|
1762
|
+
} | {
|
|
1763
|
+
connected: boolean;
|
|
1764
|
+
attemptedConnectedAtLeastOnce: boolean;
|
|
1765
|
+
trace: () => void;
|
|
1766
|
+
close: () => void;
|
|
1767
|
+
connect: () => void;
|
|
1748
1768
|
};
|
|
1749
1769
|
};
|
|
1750
1770
|
|
|
@@ -2089,5 +2109,5 @@ declare class VegaRtcManager implements RtcManager {
|
|
|
2089
2109
|
hasClient(clientId: string): boolean;
|
|
2090
2110
|
}
|
|
2091
2111
|
|
|
2092
|
-
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, variance };
|
|
2112
|
+
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
|
|
2093
2113
|
export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockRejectedEvent, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
|
package/dist/index.d.mts
CHANGED
|
@@ -27,10 +27,16 @@ type PressureRecord = {
|
|
|
27
27
|
state: string;
|
|
28
28
|
time: number;
|
|
29
29
|
};
|
|
30
|
+
type RenderedDimensionsReport = {
|
|
31
|
+
time: number;
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
};
|
|
30
35
|
interface TrackStats {
|
|
31
36
|
startTime: number;
|
|
32
37
|
updated: number;
|
|
33
38
|
ssrcs: Record<string, SsrcStats>;
|
|
39
|
+
renderedDimensions?: RenderedDimensionsReport;
|
|
34
40
|
}
|
|
35
41
|
interface ViewStats {
|
|
36
42
|
startTime?: number;
|
|
@@ -93,6 +99,7 @@ interface SsrcStats {
|
|
|
93
99
|
encodeTime?: number;
|
|
94
100
|
sourceWidth?: number;
|
|
95
101
|
sourceFps?: number;
|
|
102
|
+
freezeRate?: number;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
interface IssueDetector {
|
|
@@ -106,6 +113,7 @@ interface IssueCheckData {
|
|
|
106
113
|
clients: StatsClient[];
|
|
107
114
|
kind: string;
|
|
108
115
|
track: MediaStreamTrack | MediaStreamTrackWithDenoiserContext | undefined;
|
|
116
|
+
renderedDimensions?: RenderedDimensionsReport;
|
|
109
117
|
trackStats?: TrackStats;
|
|
110
118
|
stats?: ViewStats;
|
|
111
119
|
hasLiveTrack: boolean;
|
|
@@ -236,7 +244,7 @@ interface StatsMonitor {
|
|
|
236
244
|
stop: () => void;
|
|
237
245
|
}
|
|
238
246
|
interface StatsSubscription {
|
|
239
|
-
onUpdatedStats: (statsByView: Record<string, ViewStats>, clients: StatsClient[]) => void;
|
|
247
|
+
onUpdatedStats: (statsByView: Record<string, ViewStats>, clients: StatsClient[], renderedDimensionsByTrack: Record<string, RenderedDimensionsReport>) => void;
|
|
240
248
|
}
|
|
241
249
|
interface StatsMonitorState {
|
|
242
250
|
currentMonitor: StatsMonitor | null;
|
|
@@ -245,6 +253,7 @@ interface StatsMonitorState {
|
|
|
245
253
|
lastUpdateTime: number;
|
|
246
254
|
nextTimeout?: number;
|
|
247
255
|
pressureObserver?: PressureObserver;
|
|
256
|
+
renderedDimensionsByTrack: Record<string, RenderedDimensionsReport>;
|
|
248
257
|
statsByView: Record<string, ViewStats>;
|
|
249
258
|
subscriptions: StatsSubscription[];
|
|
250
259
|
numFailedStatsReports: number;
|
|
@@ -261,6 +270,7 @@ declare const getNumMissingTrackSsrcLookups: () => number;
|
|
|
261
270
|
declare const getNumFailedTrackSsrcLookups: () => number;
|
|
262
271
|
declare const getUpdatedStats: () => Promise<Record<string, ViewStats> | undefined> | undefined;
|
|
263
272
|
declare const setClientProvider: (provider: () => StatsClient[]) => () => StatsClient[];
|
|
273
|
+
declare const updateRenderedDimensions: (trackId: string, data: RenderedDimensionsReport) => void;
|
|
264
274
|
declare function subscribeStats(subscription: StatsSubscription, options?: StatsMonitorOptions, state?: StatsMonitorState): {
|
|
265
275
|
stop(): void;
|
|
266
276
|
};
|
|
@@ -1641,6 +1651,7 @@ declare class P2pRtcManager implements RtcManager {
|
|
|
1641
1651
|
analytics: P2PAnalytics;
|
|
1642
1652
|
_rtcStatsDisconnectTimeout?: ReturnType<typeof setTimeout>;
|
|
1643
1653
|
_webcamPaused?: boolean;
|
|
1654
|
+
_videoTrackIdByStreamId: Record<string, string>;
|
|
1644
1655
|
constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features }: RtcManagerOptions);
|
|
1645
1656
|
numberOfPeerconnections(): number;
|
|
1646
1657
|
isInitializedWith({ selfId, roomName, isSfu }: {
|
|
@@ -1693,7 +1704,10 @@ declare class P2pRtcManager implements RtcManager {
|
|
|
1693
1704
|
clientId: string;
|
|
1694
1705
|
}): Session;
|
|
1695
1706
|
disconnect(clientId: string): void;
|
|
1696
|
-
updateStreamResolution(
|
|
1707
|
+
updateStreamResolution(streamId: string, _ignored: any, { width, height, }: {
|
|
1708
|
+
width: number;
|
|
1709
|
+
height: number;
|
|
1710
|
+
}): void;
|
|
1697
1711
|
stopOrResumeAudio(): void;
|
|
1698
1712
|
_handleStopOrResumeVideo({ enable, track }: {
|
|
1699
1713
|
enable: boolean;
|
|
@@ -1745,6 +1759,12 @@ declare const rtcStats: {
|
|
|
1745
1759
|
trace: (...args: any) => void;
|
|
1746
1760
|
close: () => void;
|
|
1747
1761
|
connect: () => void;
|
|
1762
|
+
} | {
|
|
1763
|
+
connected: boolean;
|
|
1764
|
+
attemptedConnectedAtLeastOnce: boolean;
|
|
1765
|
+
trace: () => void;
|
|
1766
|
+
close: () => void;
|
|
1767
|
+
connect: () => void;
|
|
1748
1768
|
};
|
|
1749
1769
|
};
|
|
1750
1770
|
|
|
@@ -2089,5 +2109,5 @@ declare class VegaRtcManager implements RtcManager {
|
|
|
2089
2109
|
hasClient(clientId: string): boolean;
|
|
2090
2110
|
}
|
|
2091
2111
|
|
|
2092
|
-
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, variance };
|
|
2112
|
+
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
|
|
2093
2113
|
export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockRejectedEvent, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
|
package/dist/index.d.ts
CHANGED
|
@@ -27,10 +27,16 @@ type PressureRecord = {
|
|
|
27
27
|
state: string;
|
|
28
28
|
time: number;
|
|
29
29
|
};
|
|
30
|
+
type RenderedDimensionsReport = {
|
|
31
|
+
time: number;
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
};
|
|
30
35
|
interface TrackStats {
|
|
31
36
|
startTime: number;
|
|
32
37
|
updated: number;
|
|
33
38
|
ssrcs: Record<string, SsrcStats>;
|
|
39
|
+
renderedDimensions?: RenderedDimensionsReport;
|
|
34
40
|
}
|
|
35
41
|
interface ViewStats {
|
|
36
42
|
startTime?: number;
|
|
@@ -93,6 +99,7 @@ interface SsrcStats {
|
|
|
93
99
|
encodeTime?: number;
|
|
94
100
|
sourceWidth?: number;
|
|
95
101
|
sourceFps?: number;
|
|
102
|
+
freezeRate?: number;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
interface IssueDetector {
|
|
@@ -106,6 +113,7 @@ interface IssueCheckData {
|
|
|
106
113
|
clients: StatsClient[];
|
|
107
114
|
kind: string;
|
|
108
115
|
track: MediaStreamTrack | MediaStreamTrackWithDenoiserContext | undefined;
|
|
116
|
+
renderedDimensions?: RenderedDimensionsReport;
|
|
109
117
|
trackStats?: TrackStats;
|
|
110
118
|
stats?: ViewStats;
|
|
111
119
|
hasLiveTrack: boolean;
|
|
@@ -236,7 +244,7 @@ interface StatsMonitor {
|
|
|
236
244
|
stop: () => void;
|
|
237
245
|
}
|
|
238
246
|
interface StatsSubscription {
|
|
239
|
-
onUpdatedStats: (statsByView: Record<string, ViewStats>, clients: StatsClient[]) => void;
|
|
247
|
+
onUpdatedStats: (statsByView: Record<string, ViewStats>, clients: StatsClient[], renderedDimensionsByTrack: Record<string, RenderedDimensionsReport>) => void;
|
|
240
248
|
}
|
|
241
249
|
interface StatsMonitorState {
|
|
242
250
|
currentMonitor: StatsMonitor | null;
|
|
@@ -245,6 +253,7 @@ interface StatsMonitorState {
|
|
|
245
253
|
lastUpdateTime: number;
|
|
246
254
|
nextTimeout?: number;
|
|
247
255
|
pressureObserver?: PressureObserver;
|
|
256
|
+
renderedDimensionsByTrack: Record<string, RenderedDimensionsReport>;
|
|
248
257
|
statsByView: Record<string, ViewStats>;
|
|
249
258
|
subscriptions: StatsSubscription[];
|
|
250
259
|
numFailedStatsReports: number;
|
|
@@ -261,6 +270,7 @@ declare const getNumMissingTrackSsrcLookups: () => number;
|
|
|
261
270
|
declare const getNumFailedTrackSsrcLookups: () => number;
|
|
262
271
|
declare const getUpdatedStats: () => Promise<Record<string, ViewStats> | undefined> | undefined;
|
|
263
272
|
declare const setClientProvider: (provider: () => StatsClient[]) => () => StatsClient[];
|
|
273
|
+
declare const updateRenderedDimensions: (trackId: string, data: RenderedDimensionsReport) => void;
|
|
264
274
|
declare function subscribeStats(subscription: StatsSubscription, options?: StatsMonitorOptions, state?: StatsMonitorState): {
|
|
265
275
|
stop(): void;
|
|
266
276
|
};
|
|
@@ -1641,6 +1651,7 @@ declare class P2pRtcManager implements RtcManager {
|
|
|
1641
1651
|
analytics: P2PAnalytics;
|
|
1642
1652
|
_rtcStatsDisconnectTimeout?: ReturnType<typeof setTimeout>;
|
|
1643
1653
|
_webcamPaused?: boolean;
|
|
1654
|
+
_videoTrackIdByStreamId: Record<string, string>;
|
|
1644
1655
|
constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features }: RtcManagerOptions);
|
|
1645
1656
|
numberOfPeerconnections(): number;
|
|
1646
1657
|
isInitializedWith({ selfId, roomName, isSfu }: {
|
|
@@ -1693,7 +1704,10 @@ declare class P2pRtcManager implements RtcManager {
|
|
|
1693
1704
|
clientId: string;
|
|
1694
1705
|
}): Session;
|
|
1695
1706
|
disconnect(clientId: string): void;
|
|
1696
|
-
updateStreamResolution(
|
|
1707
|
+
updateStreamResolution(streamId: string, _ignored: any, { width, height, }: {
|
|
1708
|
+
width: number;
|
|
1709
|
+
height: number;
|
|
1710
|
+
}): void;
|
|
1697
1711
|
stopOrResumeAudio(): void;
|
|
1698
1712
|
_handleStopOrResumeVideo({ enable, track }: {
|
|
1699
1713
|
enable: boolean;
|
|
@@ -1745,6 +1759,12 @@ declare const rtcStats: {
|
|
|
1745
1759
|
trace: (...args: any) => void;
|
|
1746
1760
|
close: () => void;
|
|
1747
1761
|
connect: () => void;
|
|
1762
|
+
} | {
|
|
1763
|
+
connected: boolean;
|
|
1764
|
+
attemptedConnectedAtLeastOnce: boolean;
|
|
1765
|
+
trace: () => void;
|
|
1766
|
+
close: () => void;
|
|
1767
|
+
connect: () => void;
|
|
1748
1768
|
};
|
|
1749
1769
|
};
|
|
1750
1770
|
|
|
@@ -2089,5 +2109,5 @@ declare class VegaRtcManager implements RtcManager {
|
|
|
2089
2109
|
hasClient(clientId: string): boolean;
|
|
2090
2110
|
}
|
|
2091
2111
|
|
|
2092
|
-
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, variance };
|
|
2112
|
+
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, _default as rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
|
|
2093
2113
|
export type { AddCameraStreamOptions, AddSpotlightRequest, AudioEnableRequest, AudioEnableRequestedEvent, AudioEnabledEvent, BreakoutConfig, BreakoutGroupJoinedEvent, BreakoutSessionUpdatedEvent, BuildDeviceListOptions, CannotJoinUnclaimedRoomError, ChatFileShare, ChatMessage, ChatMessageError, ChatMessageRemoved, ChatMessageRequest, ClearableTimeout, ClientKickedEvent, ClientLeftEvent, ClientMetadataPayload, ClientMetadataReceivedEvent, ClientRole, ClientUnableToJoinEvent, CloudRecordingStartedEvent, Codec, ConnectionStatus, Credentials, FileShareErrorCode, FileUploadUrl, ForbiddenError, ForbiddenErrorNames, GetConstraintsOptions, GetDeviceDataResult, GetMediaConstraintsOptions, GetStreamOptions, GetStreamResult, GetUpdatedDevicesResult, GetUserMediaAttempt, GetUserMediaAttemptOutcome, HostPresenceControlsError, IdentifyDeviceRequest, InternalServerError, InvalidAssistantKeyError, IssuesAndMetricsByView, JoinRoomRequest, KnockAcceptedEvent, KnockRejectedEvent, KnockRoomRequest, KnockerLeftEvent, LiveCaptionEvent, LiveCaptionsStartedEvent, LiveCaptionsStoppedEvent, LiveTranscriptionStartedEvent, LiveTranscriptionStoppedEvent, MaxViewerLimitReachedError, MediaPrefs, Metric, NewClientEvent, OrganizationAssistantNotEnabledError, OrganizationAssistantNotFoundError, OrganizationPlanExhaustedError, RemoveScreenshareStreamOptions, RemoveSpotlightRequest, RoleName, RoomConcurrencyControlsError, RoomEmptyError, RoomFullError, RoomJoinPermissionDeniedError, RoomJoinedErrors, RoomJoinedEvent, RoomJoinedSuccess, RoomKnockedEvent, RoomLockedError, RoomLockedEvent, RoomMeetingTimeExhaustedError, RoomMode, RoomSessionEndedEvent, RtcClientConnectionStatusChangedPayload, RtcEventEmitter, RtcEvents, RtcLocalStreamTrackAddedPayload, RtcLocalStreamTrackRemovedPayload, RtcManager, RtcManagerCreatedPayload, RtcManagerOptions, RtcStreamAddedPayload, ScreenshareStartedEvent, ScreenshareStoppedEvent, SendClientMetadataRequest, SignalClient, SignalEvents, SignalIceCandidateMessage, SignalIceEndOfCandidatesMessage, SignalIceServer, SignalKnocker, SignalMediaServerConfig, SignalRTCSessionDescription, SignalReadyToReceiveOfferMessage, SignalRequests, SignalRoom, SignalSDPMessage, SignalSFUServer, SignalTurnServer, SocketConf, SocketManager, Spotlight, SpotlightAddedEvent, SpotlightRemovedEvent, StatsMonitorOptions, StatsMonitorState, StatsSubscription, TurnTransportProtocol, UniqueRoleAlreadyInRoomError, UpdatedDeviceInfo, UpdatedDevicesInfo, VegaConnectionOptions, VegaRtcManagerOptions, VideoEnableRequest, VideoEnableRequestedEvent, VideoEnabledEvent, WebRTCProvider };
|
package/dist/index.mjs
CHANGED
|
@@ -201,9 +201,22 @@ function rtcStatsConnection(wsURL, logger = console) {
|
|
|
201
201
|
return connection;
|
|
202
202
|
}
|
|
203
203
|
const RTCSTATS_URL = "wss://rtcstats.srv.whereby.com";
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
204
|
+
const noopServer = {
|
|
205
|
+
connected: false,
|
|
206
|
+
attemptedConnectedAtLeastOnce: false,
|
|
207
|
+
trace: noop,
|
|
208
|
+
close: noop,
|
|
209
|
+
connect: noop,
|
|
210
|
+
};
|
|
211
|
+
let server;
|
|
212
|
+
if (typeof window !== "undefined") {
|
|
213
|
+
server = rtcStatsConnection(RTCSTATS_URL);
|
|
214
|
+
const stats = rtcstats(server.trace, 10000, [""]);
|
|
215
|
+
resetDelta = (stats === null || stats === void 0 ? void 0 : stats.resetDelta) || noop;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
server = noopServer;
|
|
219
|
+
}
|
|
207
220
|
const rtcStats = {
|
|
208
221
|
sendEvent: (type, value) => {
|
|
209
222
|
server.trace("customEvent", null, {
|
|
@@ -220,7 +233,7 @@ const rtcStats = {
|
|
|
220
233
|
server,
|
|
221
234
|
};
|
|
222
235
|
|
|
223
|
-
const debugOn = new URLSearchParams(window.location.search).has("debug");
|
|
236
|
+
const debugOn = (typeof window !== "undefined" && new URLSearchParams(window.location.search).has("debug"));
|
|
224
237
|
class Logger {
|
|
225
238
|
constructor() {
|
|
226
239
|
this._isEnabled = false;
|
|
@@ -1422,6 +1435,8 @@ function captureVideoSsrcMetrics(ssrcMetrics, currentSsrcStats, prevSsrcStats, t
|
|
|
1422
1435
|
const qpsumDiff = currentSsrcStats.qpSum - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.qpSum) || 0);
|
|
1423
1436
|
ssrcMetrics.qpf = qpsumDiff / frameCountDiff;
|
|
1424
1437
|
ssrcMetrics.fps = (frameCountDiff * 1000) / timeDiff;
|
|
1438
|
+
const freezeCountDiff = (currentSsrcStats.freezeCount || 0) - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.freezeCount) || 0);
|
|
1439
|
+
ssrcMetrics.freezeRate = (freezeCountDiff * 1000) / timeDiff;
|
|
1425
1440
|
}
|
|
1426
1441
|
else {
|
|
1427
1442
|
const kfCountDiff = currentSsrcStats.keyFramesEncoded - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.keyFramesEncoded) || 0);
|
|
@@ -1451,7 +1466,7 @@ const peerConnectionData = new WeakMap();
|
|
|
1451
1466
|
const removePeerConnection = (pc) => {
|
|
1452
1467
|
peerConnections = peerConnections.filter((old) => old !== pc);
|
|
1453
1468
|
};
|
|
1454
|
-
if (window.RTCPeerConnection) {
|
|
1469
|
+
if (typeof window !== "undefined" && window.RTCPeerConnection) {
|
|
1455
1470
|
const OriginalRTCPeerConnection = window.RTCPeerConnection;
|
|
1456
1471
|
function PatchedRTCPeerConnection(rtcConfig) {
|
|
1457
1472
|
const pc = new OriginalRTCPeerConnection(rtcConfig);
|
|
@@ -1567,15 +1582,17 @@ const getOrCreateSsrcMetricsContainer = (statsByView, time, pcIndex, clientId, t
|
|
|
1567
1582
|
ssrcStats.updated = time;
|
|
1568
1583
|
return ssrcStats;
|
|
1569
1584
|
};
|
|
1570
|
-
const removeNonUpdatedStats = (statsByView, time) => {
|
|
1585
|
+
const removeNonUpdatedStats = (statsByView, time, renderedDimensionsByTrack) => {
|
|
1571
1586
|
Object.entries(statsByView).forEach(([viewId, viewStats]) => {
|
|
1572
1587
|
if (viewStats.updated !== undefined && viewStats.updated < time) {
|
|
1588
|
+
Object.keys(viewStats.tracks).forEach((trackId) => delete renderedDimensionsByTrack[trackId]);
|
|
1573
1589
|
delete statsByView[viewId];
|
|
1574
1590
|
}
|
|
1575
1591
|
else {
|
|
1576
1592
|
Object.entries(viewStats.tracks).forEach(([trackId, trackStats]) => {
|
|
1577
1593
|
if (trackStats.updated < time) {
|
|
1578
1594
|
delete viewStats.tracks[trackId];
|
|
1595
|
+
delete renderedDimensionsByTrack[trackId];
|
|
1579
1596
|
}
|
|
1580
1597
|
else {
|
|
1581
1598
|
Object.entries(trackStats.ssrcs).forEach(([ssrc, ssrcStats]) => {
|
|
@@ -1613,7 +1630,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1613
1630
|
if (timeSinceLastUpdate < 400) {
|
|
1614
1631
|
if (immediate)
|
|
1615
1632
|
return state.statsByView;
|
|
1616
|
-
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients); });
|
|
1633
|
+
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients, state.renderedDimensionsByTrack); });
|
|
1617
1634
|
state.nextTimeout = setTimeout(collectStatsBound, interval);
|
|
1618
1635
|
return;
|
|
1619
1636
|
}
|
|
@@ -1706,7 +1723,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1706
1723
|
}
|
|
1707
1724
|
});
|
|
1708
1725
|
});
|
|
1709
|
-
removeNonUpdatedStats(state.statsByView, state.lastUpdateTime);
|
|
1726
|
+
removeNonUpdatedStats(state.statsByView, state.lastUpdateTime, state.renderedDimensionsByTrack);
|
|
1710
1727
|
Object.entries((defaultViewStats === null || defaultViewStats === void 0 ? void 0 : defaultViewStats.candidatePairs) || {}).forEach(([cpKey, cp]) => {
|
|
1711
1728
|
const active = cp.lastRtcStatsTime === state.lastUpdateTime;
|
|
1712
1729
|
cp.active = active;
|
|
@@ -1725,7 +1742,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1725
1742
|
return state.statsByView;
|
|
1726
1743
|
}
|
|
1727
1744
|
else {
|
|
1728
|
-
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients); });
|
|
1745
|
+
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients, state.renderedDimensionsByTrack); });
|
|
1729
1746
|
}
|
|
1730
1747
|
}
|
|
1731
1748
|
catch (e) {
|
|
@@ -1764,6 +1781,7 @@ const STATE = {
|
|
|
1764
1781
|
currentMonitor: null,
|
|
1765
1782
|
getClients: () => [],
|
|
1766
1783
|
lastUpdateTime: 0,
|
|
1784
|
+
renderedDimensionsByTrack: {},
|
|
1767
1785
|
statsByView: {},
|
|
1768
1786
|
subscriptions: [],
|
|
1769
1787
|
numFailedStatsReports: 0,
|
|
@@ -1782,6 +1800,9 @@ const getNumMissingTrackSsrcLookups = () => numMissingTrackSsrcLookups;
|
|
|
1782
1800
|
const getNumFailedTrackSsrcLookups = () => numFailedTrackSsrcLookups;
|
|
1783
1801
|
const getUpdatedStats = () => { var _a; return (_a = STATE.currentMonitor) === null || _a === void 0 ? void 0 : _a.getUpdatedStats(); };
|
|
1784
1802
|
const setClientProvider = (provider) => (STATE.getClients = provider);
|
|
1803
|
+
const updateRenderedDimensions = (trackId, data) => {
|
|
1804
|
+
STATE.renderedDimensionsByTrack[trackId] = data;
|
|
1805
|
+
};
|
|
1785
1806
|
function startStatsMonitor(state, { interval, logger }) {
|
|
1786
1807
|
const collectStatsBound = collectStats.bind(null, state, { interval, logger });
|
|
1787
1808
|
let cpuObserver;
|
|
@@ -2403,7 +2424,7 @@ function fromLocation({ host = "whereby.com", protocol = "https:" } = {}) {
|
|
|
2403
2424
|
subdomain,
|
|
2404
2425
|
};
|
|
2405
2426
|
}
|
|
2406
|
-
fromLocation(window
|
|
2427
|
+
fromLocation(typeof window !== "undefined" ? window.location : undefined);
|
|
2407
2428
|
|
|
2408
2429
|
var _a$2, _b$1;
|
|
2409
2430
|
const adapter$2 = (_a$2 = adapterRaw.default) !== null && _a$2 !== void 0 ? _a$2 : adapterRaw;
|
|
@@ -2502,6 +2523,7 @@ class P2pRtcManager {
|
|
|
2502
2523
|
this._features = features || {};
|
|
2503
2524
|
this._isAudioOnlyMode = false;
|
|
2504
2525
|
this._closed = false;
|
|
2526
|
+
this._videoTrackIdByStreamId = {};
|
|
2505
2527
|
this._fetchMediaServersTimer = null;
|
|
2506
2528
|
this._stopCameraTimeout = null;
|
|
2507
2529
|
this._icePublicIPGatheringTimeoutID = null;
|
|
@@ -2982,6 +3004,8 @@ class P2pRtcManager {
|
|
|
2982
3004
|
});
|
|
2983
3005
|
return;
|
|
2984
3006
|
}
|
|
3007
|
+
if (event.track.kind === "video")
|
|
3008
|
+
this._videoTrackIdByStreamId[stream.id] = event.track.id;
|
|
2985
3009
|
if (session.streamIds.indexOf(stream.id) === -1) {
|
|
2986
3010
|
session.streamIds.push(stream.id);
|
|
2987
3011
|
this._emit(EVENTS.STREAM_ADDED, {
|
|
@@ -3412,7 +3436,11 @@ class P2pRtcManager {
|
|
|
3412
3436
|
}, 60 * 1000);
|
|
3413
3437
|
}
|
|
3414
3438
|
}
|
|
3415
|
-
updateStreamResolution(
|
|
3439
|
+
updateStreamResolution(streamId, _ignored, { width, height, }) {
|
|
3440
|
+
const trackId = this._videoTrackIdByStreamId[streamId];
|
|
3441
|
+
if (trackId)
|
|
3442
|
+
updateRenderedDimensions(trackId, { width, height, time: Date.now() });
|
|
3443
|
+
}
|
|
3416
3444
|
stopOrResumeAudio() {
|
|
3417
3445
|
}
|
|
3418
3446
|
_handleStopOrResumeVideo({ enable, track }) {
|
|
@@ -5553,7 +5581,7 @@ class VegaRtcManager {
|
|
|
5553
5581
|
this._syncIncomingStreamsWithPWA(clientId);
|
|
5554
5582
|
}
|
|
5555
5583
|
updateStreamResolution(streamId, _ignored, { width, height, }) {
|
|
5556
|
-
var _a, _b;
|
|
5584
|
+
var _a, _b, _c;
|
|
5557
5585
|
logger$2.info("updateStreamResolution()", { streamId, width, height });
|
|
5558
5586
|
const consumerId = this._streamIdToVideoConsumerId.get(streamId);
|
|
5559
5587
|
const consumer = this._consumers.get(consumerId);
|
|
@@ -5561,17 +5589,18 @@ class VegaRtcManager {
|
|
|
5561
5589
|
this._streamIdToVideoResolution.set(streamId, { width, height });
|
|
5562
5590
|
return;
|
|
5563
5591
|
}
|
|
5592
|
+
updateRenderedDimensions((_a = consumer.track) === null || _a === void 0 ? void 0 : _a.id, { width, height, time: Date.now() });
|
|
5564
5593
|
const numberOfActiveVideos = getNumberOfActiveVideos(this._consumers);
|
|
5565
5594
|
const numberOfTemporalLayers = getNumberOfTemporalLayers(consumer);
|
|
5566
5595
|
const { spatialLayer, temporalLayer } = getLayers({ width, height }, {
|
|
5567
5596
|
numberOfActiveVideos,
|
|
5568
5597
|
numberOfTemporalLayers,
|
|
5569
|
-
uncappedSingleRemoteVideoOn: (
|
|
5598
|
+
uncappedSingleRemoteVideoOn: (_b = this._features) === null || _b === void 0 ? void 0 : _b.uncappedSingleRemoteVideoOn,
|
|
5570
5599
|
});
|
|
5571
5600
|
if (consumer.appData.spatialLayer !== spatialLayer || consumer.appData.temporalLayer !== temporalLayer) {
|
|
5572
5601
|
consumer.appData.spatialLayer = spatialLayer;
|
|
5573
5602
|
consumer.appData.temporalLayer = temporalLayer;
|
|
5574
|
-
(
|
|
5603
|
+
(_c = this._vegaConnection) === null || _c === void 0 ? void 0 : _c.message("setConsumersPreferredLayers", {
|
|
5575
5604
|
consumerIds: [consumerId],
|
|
5576
5605
|
spatialLayer,
|
|
5577
5606
|
temporalLayer,
|
|
@@ -5986,6 +6015,92 @@ const getRoomMode = () => {
|
|
|
5986
6015
|
return roomMode;
|
|
5987
6016
|
};
|
|
5988
6017
|
|
|
6018
|
+
const createQualityDetector = (type) => {
|
|
6019
|
+
return {
|
|
6020
|
+
id: `quality-${type}`,
|
|
6021
|
+
enabled: ({ client }) => !client.isLocalClient && !client.isPresentation,
|
|
6022
|
+
check: ({ ssrc0, renderedDimensions, hasLiveTrack, kind }) => {
|
|
6023
|
+
if (!hasLiveTrack)
|
|
6024
|
+
return true;
|
|
6025
|
+
if (!ssrc0)
|
|
6026
|
+
return true;
|
|
6027
|
+
if (!ssrc0.bitrate)
|
|
6028
|
+
return true;
|
|
6029
|
+
if (kind === "video") {
|
|
6030
|
+
if (renderedDimensions && renderedDimensions.width && renderedDimensions.height) {
|
|
6031
|
+
const maxSideRendered = Math.max(renderedDimensions.width, renderedDimensions.height);
|
|
6032
|
+
const maxSideReceived = Math.max(ssrc0.width || 0, ssrc0.height || 0);
|
|
6033
|
+
const fpsReceived = ssrc0.fps || 0;
|
|
6034
|
+
const hadFreeze = !!ssrc0.freezeRate;
|
|
6035
|
+
const bitrate = ssrc0.bitrate || 0;
|
|
6036
|
+
if (maxSideRendered < 100) {
|
|
6037
|
+
if (type === "warning" && maxSideReceived < 160)
|
|
6038
|
+
return true;
|
|
6039
|
+
if (type === "critical" && maxSideReceived < 90)
|
|
6040
|
+
return true;
|
|
6041
|
+
if (type === "warning" && fpsReceived < 5)
|
|
6042
|
+
return true;
|
|
6043
|
+
if (type === "critical" && fpsReceived < 2)
|
|
6044
|
+
return true;
|
|
6045
|
+
if (type === "warning" && bitrate < 10000)
|
|
6046
|
+
return true;
|
|
6047
|
+
if (type === "critical" && bitrate < 5000)
|
|
6048
|
+
return true;
|
|
6049
|
+
}
|
|
6050
|
+
else if (maxSideRendered < 480) {
|
|
6051
|
+
if (type === "warning" && maxSideReceived < 240)
|
|
6052
|
+
return true;
|
|
6053
|
+
if (type === "critical" && maxSideReceived < 120)
|
|
6054
|
+
return true;
|
|
6055
|
+
if (type === "warning" && fpsReceived < 14)
|
|
6056
|
+
return true;
|
|
6057
|
+
if (type === "critical" && fpsReceived < 9)
|
|
6058
|
+
return true;
|
|
6059
|
+
if (hadFreeze)
|
|
6060
|
+
return true;
|
|
6061
|
+
if (type === "warning" && bitrate < 50000)
|
|
6062
|
+
return true;
|
|
6063
|
+
if (type === "critical" && bitrate < 20000)
|
|
6064
|
+
return true;
|
|
6065
|
+
}
|
|
6066
|
+
else {
|
|
6067
|
+
if (type === "warning" && maxSideReceived < 480)
|
|
6068
|
+
return true;
|
|
6069
|
+
if (type === "critical" && maxSideReceived < 240)
|
|
6070
|
+
return true;
|
|
6071
|
+
if (type === "warning" && fpsReceived < 14)
|
|
6072
|
+
return true;
|
|
6073
|
+
if (type === "critical" && fpsReceived < 9)
|
|
6074
|
+
return true;
|
|
6075
|
+
if (type === "warning" && bitrate < 200000)
|
|
6076
|
+
return true;
|
|
6077
|
+
if (type === "critical" && bitrate < 50000)
|
|
6078
|
+
return true;
|
|
6079
|
+
if (hadFreeze)
|
|
6080
|
+
return true;
|
|
6081
|
+
}
|
|
6082
|
+
}
|
|
6083
|
+
}
|
|
6084
|
+
else if (kind === "audio") {
|
|
6085
|
+
const audioLevel = ssrc0.audioLevel || 0;
|
|
6086
|
+
const concealment = ssrc0.audioConcealment || 0;
|
|
6087
|
+
const acceleration = ssrc0.audioAcceleration || 0;
|
|
6088
|
+
const deceleration = ssrc0.audioDeceleration || 0;
|
|
6089
|
+
const audioDistortion = concealment + acceleration + deceleration;
|
|
6090
|
+
if (audioLevel >= 0.01) {
|
|
6091
|
+
if (type === "warning" && audioDistortion > 0.1)
|
|
6092
|
+
return true;
|
|
6093
|
+
if (type === "critical" && audioDistortion > 0.2)
|
|
6094
|
+
return true;
|
|
6095
|
+
}
|
|
6096
|
+
}
|
|
6097
|
+
return false;
|
|
6098
|
+
},
|
|
6099
|
+
};
|
|
6100
|
+
};
|
|
6101
|
+
const qualityWarningDetector = createQualityDetector("warning");
|
|
6102
|
+
const qualityCriticalDetector = createQualityDetector("critical");
|
|
6103
|
+
|
|
5989
6104
|
const badNetworkIssueDetector = {
|
|
5990
6105
|
id: "bad-network",
|
|
5991
6106
|
enabled: ({ hasLiveTrack, ssrcs }) => hasLiveTrack && ssrcs.length > 0,
|
|
@@ -6209,6 +6324,8 @@ const issueDetectors = [
|
|
|
6209
6324
|
(ssrc0.audioLevel || 0) >= 0.001 &&
|
|
6210
6325
|
(ssrc0.audioAcceleration || 0) >= 0.1,
|
|
6211
6326
|
},
|
|
6327
|
+
qualityWarningDetector,
|
|
6328
|
+
qualityCriticalDetector,
|
|
6212
6329
|
];
|
|
6213
6330
|
|
|
6214
6331
|
let subscriptions = [];
|
|
@@ -6363,7 +6480,7 @@ function issueDetectorOrMetricEnabled(issueDetectorOrMetric, checkData) {
|
|
|
6363
6480
|
}
|
|
6364
6481
|
return enabled && (issueDetectorOrMetric.enabled ? issueDetectorOrMetric.enabled(checkData) : true);
|
|
6365
6482
|
}
|
|
6366
|
-
function onUpdatedStats(statsByView, clients) {
|
|
6483
|
+
function onUpdatedStats(statsByView, clients, renderedDimensionsByTrack) {
|
|
6367
6484
|
Object.values(aggregatedMetrics).forEach((metricData) => {
|
|
6368
6485
|
metricData.curTicks = 0;
|
|
6369
6486
|
metricData.curSum = 0;
|
|
@@ -6401,6 +6518,7 @@ function onUpdatedStats(statsByView, clients) {
|
|
|
6401
6518
|
kind,
|
|
6402
6519
|
track,
|
|
6403
6520
|
trackStats,
|
|
6521
|
+
renderedDimensions: (track === null || track === void 0 ? void 0 : track.id) ? renderedDimensionsByTrack[track.id] : undefined,
|
|
6404
6522
|
stats,
|
|
6405
6523
|
hasLiveTrack,
|
|
6406
6524
|
ssrc0,
|
|
@@ -7043,7 +7161,7 @@ class BandwidthTester extends EventEmitter {
|
|
|
7043
7161
|
}
|
|
7044
7162
|
|
|
7045
7163
|
const logger = new Logger();
|
|
7046
|
-
const isMobile = /mobi/i.test(navigator.userAgent);
|
|
7164
|
+
const isMobile = typeof navigator !== "undefined" && /mobi/i.test(navigator.userAgent);
|
|
7047
7165
|
class NoDevicesError extends Error {
|
|
7048
7166
|
constructor(...args) {
|
|
7049
7167
|
super(...args);
|
|
@@ -7301,8 +7419,8 @@ function hasGetDisplayMedia() {
|
|
|
7301
7419
|
}
|
|
7302
7420
|
const defaultDisplayMediaConstraints = {
|
|
7303
7421
|
video: {
|
|
7304
|
-
width: { max: window.screen.width },
|
|
7305
|
-
height: { max: window.screen.height },
|
|
7422
|
+
width: { max: typeof window !== "undefined" ? window.screen.width : 0 },
|
|
7423
|
+
height: { max: typeof window !== "undefined" ? window.screen.height : 0 },
|
|
7306
7424
|
},
|
|
7307
7425
|
};
|
|
7308
7426
|
function getDisplayMedia(constraints = defaultDisplayMediaConstraints, contentHint = "detail") {
|
|
@@ -7393,4 +7511,4 @@ var RtcEventNames;
|
|
|
7393
7511
|
RtcEventNames["stream_added"] = "stream_added";
|
|
7394
7512
|
})(RtcEventNames || (RtcEventNames = {}));
|
|
7395
7513
|
|
|
7396
|
-
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, variance };
|
|
7514
|
+
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
|
package/dist/legacy-esm.js
CHANGED
|
@@ -201,9 +201,22 @@ function rtcStatsConnection(wsURL, logger = console) {
|
|
|
201
201
|
return connection;
|
|
202
202
|
}
|
|
203
203
|
const RTCSTATS_URL = "wss://rtcstats.srv.whereby.com";
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
204
|
+
const noopServer = {
|
|
205
|
+
connected: false,
|
|
206
|
+
attemptedConnectedAtLeastOnce: false,
|
|
207
|
+
trace: noop,
|
|
208
|
+
close: noop,
|
|
209
|
+
connect: noop,
|
|
210
|
+
};
|
|
211
|
+
let server;
|
|
212
|
+
if (typeof window !== "undefined") {
|
|
213
|
+
server = rtcStatsConnection(RTCSTATS_URL);
|
|
214
|
+
const stats = rtcstats(server.trace, 10000, [""]);
|
|
215
|
+
resetDelta = (stats === null || stats === void 0 ? void 0 : stats.resetDelta) || noop;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
server = noopServer;
|
|
219
|
+
}
|
|
207
220
|
const rtcStats = {
|
|
208
221
|
sendEvent: (type, value) => {
|
|
209
222
|
server.trace("customEvent", null, {
|
|
@@ -220,7 +233,7 @@ const rtcStats = {
|
|
|
220
233
|
server,
|
|
221
234
|
};
|
|
222
235
|
|
|
223
|
-
const debugOn = new URLSearchParams(window.location.search).has("debug");
|
|
236
|
+
const debugOn = (typeof window !== "undefined" && new URLSearchParams(window.location.search).has("debug"));
|
|
224
237
|
class Logger {
|
|
225
238
|
constructor() {
|
|
226
239
|
this._isEnabled = false;
|
|
@@ -1422,6 +1435,8 @@ function captureVideoSsrcMetrics(ssrcMetrics, currentSsrcStats, prevSsrcStats, t
|
|
|
1422
1435
|
const qpsumDiff = currentSsrcStats.qpSum - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.qpSum) || 0);
|
|
1423
1436
|
ssrcMetrics.qpf = qpsumDiff / frameCountDiff;
|
|
1424
1437
|
ssrcMetrics.fps = (frameCountDiff * 1000) / timeDiff;
|
|
1438
|
+
const freezeCountDiff = (currentSsrcStats.freezeCount || 0) - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.freezeCount) || 0);
|
|
1439
|
+
ssrcMetrics.freezeRate = (freezeCountDiff * 1000) / timeDiff;
|
|
1425
1440
|
}
|
|
1426
1441
|
else {
|
|
1427
1442
|
const kfCountDiff = currentSsrcStats.keyFramesEncoded - ((prevSsrcStats === null || prevSsrcStats === void 0 ? void 0 : prevSsrcStats.keyFramesEncoded) || 0);
|
|
@@ -1451,7 +1466,7 @@ const peerConnectionData = new WeakMap();
|
|
|
1451
1466
|
const removePeerConnection = (pc) => {
|
|
1452
1467
|
peerConnections = peerConnections.filter((old) => old !== pc);
|
|
1453
1468
|
};
|
|
1454
|
-
if (window.RTCPeerConnection) {
|
|
1469
|
+
if (typeof window !== "undefined" && window.RTCPeerConnection) {
|
|
1455
1470
|
const OriginalRTCPeerConnection = window.RTCPeerConnection;
|
|
1456
1471
|
function PatchedRTCPeerConnection(rtcConfig) {
|
|
1457
1472
|
const pc = new OriginalRTCPeerConnection(rtcConfig);
|
|
@@ -1567,15 +1582,17 @@ const getOrCreateSsrcMetricsContainer = (statsByView, time, pcIndex, clientId, t
|
|
|
1567
1582
|
ssrcStats.updated = time;
|
|
1568
1583
|
return ssrcStats;
|
|
1569
1584
|
};
|
|
1570
|
-
const removeNonUpdatedStats = (statsByView, time) => {
|
|
1585
|
+
const removeNonUpdatedStats = (statsByView, time, renderedDimensionsByTrack) => {
|
|
1571
1586
|
Object.entries(statsByView).forEach(([viewId, viewStats]) => {
|
|
1572
1587
|
if (viewStats.updated !== undefined && viewStats.updated < time) {
|
|
1588
|
+
Object.keys(viewStats.tracks).forEach((trackId) => delete renderedDimensionsByTrack[trackId]);
|
|
1573
1589
|
delete statsByView[viewId];
|
|
1574
1590
|
}
|
|
1575
1591
|
else {
|
|
1576
1592
|
Object.entries(viewStats.tracks).forEach(([trackId, trackStats]) => {
|
|
1577
1593
|
if (trackStats.updated < time) {
|
|
1578
1594
|
delete viewStats.tracks[trackId];
|
|
1595
|
+
delete renderedDimensionsByTrack[trackId];
|
|
1579
1596
|
}
|
|
1580
1597
|
else {
|
|
1581
1598
|
Object.entries(trackStats.ssrcs).forEach(([ssrc, ssrcStats]) => {
|
|
@@ -1613,7 +1630,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1613
1630
|
if (timeSinceLastUpdate < 400) {
|
|
1614
1631
|
if (immediate)
|
|
1615
1632
|
return state.statsByView;
|
|
1616
|
-
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients); });
|
|
1633
|
+
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients, state.renderedDimensionsByTrack); });
|
|
1617
1634
|
state.nextTimeout = setTimeout(collectStatsBound, interval);
|
|
1618
1635
|
return;
|
|
1619
1636
|
}
|
|
@@ -1706,7 +1723,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1706
1723
|
}
|
|
1707
1724
|
});
|
|
1708
1725
|
});
|
|
1709
|
-
removeNonUpdatedStats(state.statsByView, state.lastUpdateTime);
|
|
1726
|
+
removeNonUpdatedStats(state.statsByView, state.lastUpdateTime, state.renderedDimensionsByTrack);
|
|
1710
1727
|
Object.entries((defaultViewStats === null || defaultViewStats === void 0 ? void 0 : defaultViewStats.candidatePairs) || {}).forEach(([cpKey, cp]) => {
|
|
1711
1728
|
const active = cp.lastRtcStatsTime === state.lastUpdateTime;
|
|
1712
1729
|
cp.active = active;
|
|
@@ -1725,7 +1742,7 @@ function collectStats(state_1, _a, immediate_1) {
|
|
|
1725
1742
|
return state.statsByView;
|
|
1726
1743
|
}
|
|
1727
1744
|
else {
|
|
1728
|
-
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients); });
|
|
1745
|
+
state.subscriptions.forEach((subscription) => { var _a; return (_a = subscription.onUpdatedStats) === null || _a === void 0 ? void 0 : _a.call(subscription, state.statsByView, clients, state.renderedDimensionsByTrack); });
|
|
1729
1746
|
}
|
|
1730
1747
|
}
|
|
1731
1748
|
catch (e) {
|
|
@@ -1764,6 +1781,7 @@ const STATE = {
|
|
|
1764
1781
|
currentMonitor: null,
|
|
1765
1782
|
getClients: () => [],
|
|
1766
1783
|
lastUpdateTime: 0,
|
|
1784
|
+
renderedDimensionsByTrack: {},
|
|
1767
1785
|
statsByView: {},
|
|
1768
1786
|
subscriptions: [],
|
|
1769
1787
|
numFailedStatsReports: 0,
|
|
@@ -1782,6 +1800,9 @@ const getNumMissingTrackSsrcLookups = () => numMissingTrackSsrcLookups;
|
|
|
1782
1800
|
const getNumFailedTrackSsrcLookups = () => numFailedTrackSsrcLookups;
|
|
1783
1801
|
const getUpdatedStats = () => { var _a; return (_a = STATE.currentMonitor) === null || _a === void 0 ? void 0 : _a.getUpdatedStats(); };
|
|
1784
1802
|
const setClientProvider = (provider) => (STATE.getClients = provider);
|
|
1803
|
+
const updateRenderedDimensions = (trackId, data) => {
|
|
1804
|
+
STATE.renderedDimensionsByTrack[trackId] = data;
|
|
1805
|
+
};
|
|
1785
1806
|
function startStatsMonitor(state, { interval, logger }) {
|
|
1786
1807
|
const collectStatsBound = collectStats.bind(null, state, { interval, logger });
|
|
1787
1808
|
let cpuObserver;
|
|
@@ -2403,7 +2424,7 @@ function fromLocation({ host = "whereby.com", protocol = "https:" } = {}) {
|
|
|
2403
2424
|
subdomain,
|
|
2404
2425
|
};
|
|
2405
2426
|
}
|
|
2406
|
-
fromLocation(window
|
|
2427
|
+
fromLocation(typeof window !== "undefined" ? window.location : undefined);
|
|
2407
2428
|
|
|
2408
2429
|
var _a$2, _b$1;
|
|
2409
2430
|
const adapter$2 = (_a$2 = adapterRaw.default) !== null && _a$2 !== void 0 ? _a$2 : adapterRaw;
|
|
@@ -2502,6 +2523,7 @@ class P2pRtcManager {
|
|
|
2502
2523
|
this._features = features || {};
|
|
2503
2524
|
this._isAudioOnlyMode = false;
|
|
2504
2525
|
this._closed = false;
|
|
2526
|
+
this._videoTrackIdByStreamId = {};
|
|
2505
2527
|
this._fetchMediaServersTimer = null;
|
|
2506
2528
|
this._stopCameraTimeout = null;
|
|
2507
2529
|
this._icePublicIPGatheringTimeoutID = null;
|
|
@@ -2982,6 +3004,8 @@ class P2pRtcManager {
|
|
|
2982
3004
|
});
|
|
2983
3005
|
return;
|
|
2984
3006
|
}
|
|
3007
|
+
if (event.track.kind === "video")
|
|
3008
|
+
this._videoTrackIdByStreamId[stream.id] = event.track.id;
|
|
2985
3009
|
if (session.streamIds.indexOf(stream.id) === -1) {
|
|
2986
3010
|
session.streamIds.push(stream.id);
|
|
2987
3011
|
this._emit(EVENTS.STREAM_ADDED, {
|
|
@@ -3412,7 +3436,11 @@ class P2pRtcManager {
|
|
|
3412
3436
|
}, 60 * 1000);
|
|
3413
3437
|
}
|
|
3414
3438
|
}
|
|
3415
|
-
updateStreamResolution(
|
|
3439
|
+
updateStreamResolution(streamId, _ignored, { width, height, }) {
|
|
3440
|
+
const trackId = this._videoTrackIdByStreamId[streamId];
|
|
3441
|
+
if (trackId)
|
|
3442
|
+
updateRenderedDimensions(trackId, { width, height, time: Date.now() });
|
|
3443
|
+
}
|
|
3416
3444
|
stopOrResumeAudio() {
|
|
3417
3445
|
}
|
|
3418
3446
|
_handleStopOrResumeVideo({ enable, track }) {
|
|
@@ -5553,7 +5581,7 @@ class VegaRtcManager {
|
|
|
5553
5581
|
this._syncIncomingStreamsWithPWA(clientId);
|
|
5554
5582
|
}
|
|
5555
5583
|
updateStreamResolution(streamId, _ignored, { width, height, }) {
|
|
5556
|
-
var _a, _b;
|
|
5584
|
+
var _a, _b, _c;
|
|
5557
5585
|
logger$2.info("updateStreamResolution()", { streamId, width, height });
|
|
5558
5586
|
const consumerId = this._streamIdToVideoConsumerId.get(streamId);
|
|
5559
5587
|
const consumer = this._consumers.get(consumerId);
|
|
@@ -5561,17 +5589,18 @@ class VegaRtcManager {
|
|
|
5561
5589
|
this._streamIdToVideoResolution.set(streamId, { width, height });
|
|
5562
5590
|
return;
|
|
5563
5591
|
}
|
|
5592
|
+
updateRenderedDimensions((_a = consumer.track) === null || _a === void 0 ? void 0 : _a.id, { width, height, time: Date.now() });
|
|
5564
5593
|
const numberOfActiveVideos = getNumberOfActiveVideos(this._consumers);
|
|
5565
5594
|
const numberOfTemporalLayers = getNumberOfTemporalLayers(consumer);
|
|
5566
5595
|
const { spatialLayer, temporalLayer } = getLayers({ width, height }, {
|
|
5567
5596
|
numberOfActiveVideos,
|
|
5568
5597
|
numberOfTemporalLayers,
|
|
5569
|
-
uncappedSingleRemoteVideoOn: (
|
|
5598
|
+
uncappedSingleRemoteVideoOn: (_b = this._features) === null || _b === void 0 ? void 0 : _b.uncappedSingleRemoteVideoOn,
|
|
5570
5599
|
});
|
|
5571
5600
|
if (consumer.appData.spatialLayer !== spatialLayer || consumer.appData.temporalLayer !== temporalLayer) {
|
|
5572
5601
|
consumer.appData.spatialLayer = spatialLayer;
|
|
5573
5602
|
consumer.appData.temporalLayer = temporalLayer;
|
|
5574
|
-
(
|
|
5603
|
+
(_c = this._vegaConnection) === null || _c === void 0 ? void 0 : _c.message("setConsumersPreferredLayers", {
|
|
5575
5604
|
consumerIds: [consumerId],
|
|
5576
5605
|
spatialLayer,
|
|
5577
5606
|
temporalLayer,
|
|
@@ -5986,6 +6015,92 @@ const getRoomMode = () => {
|
|
|
5986
6015
|
return roomMode;
|
|
5987
6016
|
};
|
|
5988
6017
|
|
|
6018
|
+
const createQualityDetector = (type) => {
|
|
6019
|
+
return {
|
|
6020
|
+
id: `quality-${type}`,
|
|
6021
|
+
enabled: ({ client }) => !client.isLocalClient && !client.isPresentation,
|
|
6022
|
+
check: ({ ssrc0, renderedDimensions, hasLiveTrack, kind }) => {
|
|
6023
|
+
if (!hasLiveTrack)
|
|
6024
|
+
return true;
|
|
6025
|
+
if (!ssrc0)
|
|
6026
|
+
return true;
|
|
6027
|
+
if (!ssrc0.bitrate)
|
|
6028
|
+
return true;
|
|
6029
|
+
if (kind === "video") {
|
|
6030
|
+
if (renderedDimensions && renderedDimensions.width && renderedDimensions.height) {
|
|
6031
|
+
const maxSideRendered = Math.max(renderedDimensions.width, renderedDimensions.height);
|
|
6032
|
+
const maxSideReceived = Math.max(ssrc0.width || 0, ssrc0.height || 0);
|
|
6033
|
+
const fpsReceived = ssrc0.fps || 0;
|
|
6034
|
+
const hadFreeze = !!ssrc0.freezeRate;
|
|
6035
|
+
const bitrate = ssrc0.bitrate || 0;
|
|
6036
|
+
if (maxSideRendered < 100) {
|
|
6037
|
+
if (type === "warning" && maxSideReceived < 160)
|
|
6038
|
+
return true;
|
|
6039
|
+
if (type === "critical" && maxSideReceived < 90)
|
|
6040
|
+
return true;
|
|
6041
|
+
if (type === "warning" && fpsReceived < 5)
|
|
6042
|
+
return true;
|
|
6043
|
+
if (type === "critical" && fpsReceived < 2)
|
|
6044
|
+
return true;
|
|
6045
|
+
if (type === "warning" && bitrate < 10000)
|
|
6046
|
+
return true;
|
|
6047
|
+
if (type === "critical" && bitrate < 5000)
|
|
6048
|
+
return true;
|
|
6049
|
+
}
|
|
6050
|
+
else if (maxSideRendered < 480) {
|
|
6051
|
+
if (type === "warning" && maxSideReceived < 240)
|
|
6052
|
+
return true;
|
|
6053
|
+
if (type === "critical" && maxSideReceived < 120)
|
|
6054
|
+
return true;
|
|
6055
|
+
if (type === "warning" && fpsReceived < 14)
|
|
6056
|
+
return true;
|
|
6057
|
+
if (type === "critical" && fpsReceived < 9)
|
|
6058
|
+
return true;
|
|
6059
|
+
if (hadFreeze)
|
|
6060
|
+
return true;
|
|
6061
|
+
if (type === "warning" && bitrate < 50000)
|
|
6062
|
+
return true;
|
|
6063
|
+
if (type === "critical" && bitrate < 20000)
|
|
6064
|
+
return true;
|
|
6065
|
+
}
|
|
6066
|
+
else {
|
|
6067
|
+
if (type === "warning" && maxSideReceived < 480)
|
|
6068
|
+
return true;
|
|
6069
|
+
if (type === "critical" && maxSideReceived < 240)
|
|
6070
|
+
return true;
|
|
6071
|
+
if (type === "warning" && fpsReceived < 14)
|
|
6072
|
+
return true;
|
|
6073
|
+
if (type === "critical" && fpsReceived < 9)
|
|
6074
|
+
return true;
|
|
6075
|
+
if (type === "warning" && bitrate < 200000)
|
|
6076
|
+
return true;
|
|
6077
|
+
if (type === "critical" && bitrate < 50000)
|
|
6078
|
+
return true;
|
|
6079
|
+
if (hadFreeze)
|
|
6080
|
+
return true;
|
|
6081
|
+
}
|
|
6082
|
+
}
|
|
6083
|
+
}
|
|
6084
|
+
else if (kind === "audio") {
|
|
6085
|
+
const audioLevel = ssrc0.audioLevel || 0;
|
|
6086
|
+
const concealment = ssrc0.audioConcealment || 0;
|
|
6087
|
+
const acceleration = ssrc0.audioAcceleration || 0;
|
|
6088
|
+
const deceleration = ssrc0.audioDeceleration || 0;
|
|
6089
|
+
const audioDistortion = concealment + acceleration + deceleration;
|
|
6090
|
+
if (audioLevel >= 0.01) {
|
|
6091
|
+
if (type === "warning" && audioDistortion > 0.1)
|
|
6092
|
+
return true;
|
|
6093
|
+
if (type === "critical" && audioDistortion > 0.2)
|
|
6094
|
+
return true;
|
|
6095
|
+
}
|
|
6096
|
+
}
|
|
6097
|
+
return false;
|
|
6098
|
+
},
|
|
6099
|
+
};
|
|
6100
|
+
};
|
|
6101
|
+
const qualityWarningDetector = createQualityDetector("warning");
|
|
6102
|
+
const qualityCriticalDetector = createQualityDetector("critical");
|
|
6103
|
+
|
|
5989
6104
|
const badNetworkIssueDetector = {
|
|
5990
6105
|
id: "bad-network",
|
|
5991
6106
|
enabled: ({ hasLiveTrack, ssrcs }) => hasLiveTrack && ssrcs.length > 0,
|
|
@@ -6209,6 +6324,8 @@ const issueDetectors = [
|
|
|
6209
6324
|
(ssrc0.audioLevel || 0) >= 0.001 &&
|
|
6210
6325
|
(ssrc0.audioAcceleration || 0) >= 0.1,
|
|
6211
6326
|
},
|
|
6327
|
+
qualityWarningDetector,
|
|
6328
|
+
qualityCriticalDetector,
|
|
6212
6329
|
];
|
|
6213
6330
|
|
|
6214
6331
|
let subscriptions = [];
|
|
@@ -6363,7 +6480,7 @@ function issueDetectorOrMetricEnabled(issueDetectorOrMetric, checkData) {
|
|
|
6363
6480
|
}
|
|
6364
6481
|
return enabled && (issueDetectorOrMetric.enabled ? issueDetectorOrMetric.enabled(checkData) : true);
|
|
6365
6482
|
}
|
|
6366
|
-
function onUpdatedStats(statsByView, clients) {
|
|
6483
|
+
function onUpdatedStats(statsByView, clients, renderedDimensionsByTrack) {
|
|
6367
6484
|
Object.values(aggregatedMetrics).forEach((metricData) => {
|
|
6368
6485
|
metricData.curTicks = 0;
|
|
6369
6486
|
metricData.curSum = 0;
|
|
@@ -6401,6 +6518,7 @@ function onUpdatedStats(statsByView, clients) {
|
|
|
6401
6518
|
kind,
|
|
6402
6519
|
track,
|
|
6403
6520
|
trackStats,
|
|
6521
|
+
renderedDimensions: (track === null || track === void 0 ? void 0 : track.id) ? renderedDimensionsByTrack[track.id] : undefined,
|
|
6404
6522
|
stats,
|
|
6405
6523
|
hasLiveTrack,
|
|
6406
6524
|
ssrc0,
|
|
@@ -7043,7 +7161,7 @@ class BandwidthTester extends EventEmitter {
|
|
|
7043
7161
|
}
|
|
7044
7162
|
|
|
7045
7163
|
const logger = new Logger();
|
|
7046
|
-
const isMobile = /mobi/i.test(navigator.userAgent);
|
|
7164
|
+
const isMobile = typeof navigator !== "undefined" && /mobi/i.test(navigator.userAgent);
|
|
7047
7165
|
class NoDevicesError extends Error {
|
|
7048
7166
|
constructor(...args) {
|
|
7049
7167
|
super(...args);
|
|
@@ -7301,8 +7419,8 @@ function hasGetDisplayMedia() {
|
|
|
7301
7419
|
}
|
|
7302
7420
|
const defaultDisplayMediaConstraints = {
|
|
7303
7421
|
video: {
|
|
7304
|
-
width: { max: window.screen.width },
|
|
7305
|
-
height: { max: window.screen.height },
|
|
7422
|
+
width: { max: typeof window !== "undefined" ? window.screen.width : 0 },
|
|
7423
|
+
height: { max: typeof window !== "undefined" ? window.screen.height : 0 },
|
|
7306
7424
|
},
|
|
7307
7425
|
};
|
|
7308
7426
|
function getDisplayMedia(constraints = defaultDisplayMediaConstraints, contentHint = "detail") {
|
|
@@ -7393,5 +7511,5 @@ var RtcEventNames;
|
|
|
7393
7511
|
RtcEventNames["stream_added"] = "stream_added";
|
|
7394
7512
|
})(RtcEventNames || (RtcEventNames = {}));
|
|
7395
7513
|
|
|
7396
|
-
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, variance };
|
|
7514
|
+
export { ADDITIONAL_SCREEN_SHARE_SETTINGS, AUDIO_SETTINGS, BandwidthTester, CAMERA_STREAM_ID, EVENTS, FILE_SHARE_ERROR_CODES, KNOCK_MESSAGES, KalmanFilter, Logger, MEDIA_JITTER_BUFFER_TARGET, NoDevicesError, P2pRtcManager, PROTOCOL_ERRORS, PROTOCOL_EVENTS, PROTOCOL_REQUESTS, PROTOCOL_RESPONSES, RELAY_MESSAGES, ReconnectManager, RtcEventNames, RtcManagerDispatcher, SCREEN_SHARE_SETTINGS, SCREEN_SHARE_SIMULCAST_SETTINGS, STREAM_TYPES, ServerSocket, Session, SfuV2Parser, TYPES, VIDEO_SETTINGS_HD, VIDEO_SETTINGS_SD, VIDEO_SETTINGS_VP9, VIDEO_SETTINGS_VP9_LOW_BANDWIDTH, VegaConnection, VegaMediaQualityMonitor, VegaRtcManager, addAbsCaptureTimeExtMap, addExtMap, assert, buildDeviceList, calculateStd, captureAudioSsrcMetrics, captureCandidatePairInfoMetrics, captureCommonSsrcMetrics, captureSsrcInfo, captureVideoSsrcMetrics, cleanSdp, compareLocalDevices, createACFCalculator, createMicAnalyser, createWorker, deprioritizeH264, detectMicrophoneNotWorking, enumerate, external_stun_servers, filterMidExtension, filterMsidSemantic, fromLocation, generateByteString, getConstraints, getCurrentPeerConnections, getDeviceData, getDisplayMedia, getIssuesAndMetrics, getMediaConstraints, getMediaSettings, getMediasoupDeviceAsync, getNumFailedStatsReports, getNumFailedTrackSsrcLookups, getNumMissingTrackSsrcLookups, getPeerConnectionIndex, getStats, getStream, getUpdatedDevices, getUpdatedStats, getUserMedia, hasGetDisplayMedia, ipRegex, isFileShareError, isMobile, issueDetectorOrMetricEnabled, maybeTurnOnly, modifyMediaCapabilities, removePeerConnection, replaceTracksInStream, rtcManagerEvents, rtcStats, setClientProvider, setCodecPreferenceSDP, setPeerConnectionsForTests, setVideoBandwidthUsingSetParameters, sortCodecs, standardDeviation, startPerformanceMonitor, stopStreamTracks, subscribeIssues, subscribeStats, trackAnnotations, turnServerOverride, updateRenderedDimensions, variance };
|
|
7397
7515
|
//# sourceMappingURL=legacy-esm.js.map
|