@unboundcx/video-sdk-client 2.0.0 → 2.0.2
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/VideoMeetingClient.js +1651 -1488
- package/managers/ConnectionHealthMonitor.js +278 -0
- package/managers/ConnectionManager.js +17 -4
- package/managers/MediasoupManager.js +1061 -859
- package/managers/QualityMonitor.js +845 -0
- package/managers/RemoteMediaManager.js +17 -15
- package/managers/StatsCollector.js +35 -4
- package/package.json +1 -1
|
@@ -474,21 +474,23 @@ export class RemoteMediaManager extends EventEmitter {
|
|
|
474
474
|
* @returns {number} - Optimal spatial layer (0-2)
|
|
475
475
|
*/
|
|
476
476
|
_calculateOptimalSpatialLayer(width, height) {
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
//
|
|
481
|
-
//
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
477
|
+
// Pick the smallest simulcast layer whose source resolution is >=
|
|
478
|
+
// the number of pixels the browser will actually paint for this
|
|
479
|
+
// tile. Browsers render at CSS pixels × devicePixelRatio; on
|
|
480
|
+
// Retina (DPR=2) a 540px CSS tile actually displays 1080 device
|
|
481
|
+
// pixels and *does* benefit from the 1080p source, while on a
|
|
482
|
+
// standard (DPR=1) display that same 540px tile can be served
|
|
483
|
+
// from the 540p source without any visible difference.
|
|
484
|
+
//
|
|
485
|
+
// Source resolutions (rid l/m/h in MediasoupManager produce
|
|
486
|
+
// options): 480×270, 960×540, 1920×1080.
|
|
487
|
+
const dpr =
|
|
488
|
+
(typeof window !== 'undefined' && window.devicePixelRatio) || 1;
|
|
489
|
+
const maxPx = Math.max(width || 0, height || 0) * dpr;
|
|
490
|
+
|
|
491
|
+
if (maxPx <= 480) return 0; // ≤480 px → 270p source suffices
|
|
492
|
+
if (maxPx <= 960) return 1; // ≤960 px → 540p source suffices
|
|
493
|
+
return 2; // larger → need 1080p source
|
|
492
494
|
}
|
|
493
495
|
|
|
494
496
|
/**
|
|
@@ -9,16 +9,35 @@ export class StatsCollector {
|
|
|
9
9
|
this.sendTransportStatsTimeout = null;
|
|
10
10
|
this.recvTransportStatsInterval = null;
|
|
11
11
|
this.tracks = new Map(); // trackId -> { participantId, kind }
|
|
12
|
-
this.onStatsCallback = null; //
|
|
12
|
+
this.onStatsCallback = null; // Host-app callback (UI display)
|
|
13
|
+
this._internalCallbacks = []; // SDK-internal subscribers (QualityMonitor)
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
|
-
* Set callback for stats updates (for local UI display)
|
|
17
|
+
* Set callback for stats updates (for local UI display). Calling this
|
|
18
|
+
* replaces the prior host callback. SDK-internal subscribers (like
|
|
19
|
+
* QualityMonitor) use addInternalCallback() instead so they can't be
|
|
20
|
+
* accidentally clobbered by the host calling setStatsCallback.
|
|
17
21
|
*/
|
|
18
22
|
setStatsCallback(callback) {
|
|
19
23
|
this.onStatsCallback = callback;
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
/**
|
|
27
|
+
* SDK-internal: append a stats subscriber that survives host
|
|
28
|
+
* setStatsCallback() calls. Used by QualityMonitor so it can keep
|
|
29
|
+
* receiving stats even when the meet UI installs its own callback.
|
|
30
|
+
* Returns an unsubscribe function.
|
|
31
|
+
*/
|
|
32
|
+
addInternalCallback(callback) {
|
|
33
|
+
if (typeof callback !== 'function') return () => {};
|
|
34
|
+
this._internalCallbacks.push(callback);
|
|
35
|
+
return () => {
|
|
36
|
+
const i = this._internalCallbacks.indexOf(callback);
|
|
37
|
+
if (i >= 0) this._internalCallbacks.splice(i, 1);
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
22
41
|
/**
|
|
23
42
|
* Register a track for stats collection
|
|
24
43
|
*/
|
|
@@ -676,9 +695,21 @@ export class StatsCollector {
|
|
|
676
695
|
bandwidth,
|
|
677
696
|
};
|
|
678
697
|
|
|
679
|
-
//
|
|
698
|
+
// Fan out to host callback (UI display) AND SDK-internal subscribers
|
|
699
|
+
// (e.g. QualityMonitor). Internal subscribers go first so monitor
|
|
700
|
+
// state updates BEFORE the UI sees the sample — the host callback
|
|
701
|
+
// may read monitor state to render badges. Each callback is wrapped
|
|
702
|
+
// so one throwing subscriber can't starve the others (or the server
|
|
703
|
+
// emit below).
|
|
704
|
+
for (const cb of this._internalCallbacks || []) {
|
|
705
|
+
try { cb(statData); } catch (err) {
|
|
706
|
+
this.logger.warn('StatsCollector :: internal callback error', err);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
680
709
|
if (this.onStatsCallback) {
|
|
681
|
-
this.onStatsCallback(statData);
|
|
710
|
+
try { this.onStatsCallback(statData); } catch (err) {
|
|
711
|
+
this.logger.warn('StatsCollector :: host callback error', err);
|
|
712
|
+
}
|
|
682
713
|
}
|
|
683
714
|
|
|
684
715
|
// Emit to server
|