@unboundcx/video-sdk-client 2.0.5 → 2.0.6
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.
|
@@ -367,18 +367,16 @@ export class LocalMediaManager extends EventEmitter {
|
|
|
367
367
|
// Note: Audio is only available when sharing a Chrome Tab or Window (not Screen)
|
|
368
368
|
// Chrome will show an audio checkbox for Tab and Window sharing if audio is requested
|
|
369
369
|
//
|
|
370
|
-
//
|
|
371
|
-
//
|
|
372
|
-
//
|
|
373
|
-
//
|
|
374
|
-
//
|
|
375
|
-
//
|
|
370
|
+
// Keep video constraints minimal — only the `cursor` hint. Some
|
|
371
|
+
// Chrome versions reject frameRate / width / height on
|
|
372
|
+
// getDisplayMedia and abort the capture with an opaque
|
|
373
|
+
// "Error starting tab capture", so we let the browser pick the
|
|
374
|
+
// source's native resolution + framerate. Bandwidth is bounded
|
|
375
|
+
// downstream by the encoder profile in MediasoupManager
|
|
376
|
+
// (single-layer, max 8 Mbps, maintain-resolution preference).
|
|
376
377
|
const constraints = {
|
|
377
378
|
video: {
|
|
378
379
|
cursor: 'always',
|
|
379
|
-
width: { max: 1920 },
|
|
380
|
-
height: { max: 1080 },
|
|
381
|
-
frameRate: { ideal: 15, max: 30 },
|
|
382
380
|
},
|
|
383
381
|
// Request audio with processing disabled for system audio
|
|
384
382
|
// System audio should not have echo cancellation, noise suppression, or auto gain control
|
|
@@ -532,20 +532,35 @@ export class MediasoupManager extends EventEmitter {
|
|
|
532
532
|
} catch (err) {
|
|
533
533
|
this.logger.warn("Could not set contentHint on screenshare track:", err);
|
|
534
534
|
}
|
|
535
|
+
// If the captured source is bigger than 1920×1080 (4K monitor,
|
|
536
|
+
// Retina display, etc.) scale it down before encoding so we
|
|
537
|
+
// don't waste CPU on pixels nobody will see. Encode at the
|
|
538
|
+
// larger of the two dimension ratios so neither dimension
|
|
539
|
+
// exceeds 1920×1080.
|
|
540
|
+
const maxW = 1920;
|
|
541
|
+
const maxH = 1080;
|
|
542
|
+
const scaleDown = Math.max(
|
|
543
|
+
1.0,
|
|
544
|
+
baseWidth / maxW,
|
|
545
|
+
baseHeight / maxH,
|
|
546
|
+
);
|
|
547
|
+
const encWidth = Math.round(baseWidth / scaleDown);
|
|
548
|
+
const encHeight = Math.round(baseHeight / scaleDown);
|
|
549
|
+
|
|
535
550
|
// Bitrate budget tuned for text crispness: ~5 Mbps at 1080p,
|
|
536
551
|
// ~3 Mbps at 720p, scaled linearly for unusual sizes. Cap
|
|
537
552
|
// upper at 8 Mbps so a huge external monitor doesn't blow
|
|
538
553
|
// through user bandwidth.
|
|
539
|
-
const
|
|
554
|
+
const encPixels = encWidth * encHeight;
|
|
540
555
|
const bitrate = Math.min(
|
|
541
556
|
8_000_000,
|
|
542
|
-
Math.max(2_000_000, Math.round(
|
|
557
|
+
Math.max(2_000_000, Math.round(encPixels * 2.5)),
|
|
543
558
|
);
|
|
544
559
|
produceOptions.encodings = [
|
|
545
560
|
{
|
|
546
561
|
rid: "h",
|
|
547
562
|
maxBitrate: bitrate,
|
|
548
|
-
scaleResolutionDownBy:
|
|
563
|
+
scaleResolutionDownBy: scaleDown,
|
|
549
564
|
},
|
|
550
565
|
];
|
|
551
566
|
// degradationPreference="maintain-resolution" tells WebRTC
|
|
@@ -553,7 +568,9 @@ export class MediasoupManager extends EventEmitter {
|
|
|
553
568
|
// — exactly what we want for text.
|
|
554
569
|
produceOptions.degradationPreference = "maintain-resolution";
|
|
555
570
|
this.logger.info("VIDEO_QUALITY :: screen-share encoder profile", {
|
|
556
|
-
|
|
571
|
+
sourceResolution: `${baseWidth}×${baseHeight}`,
|
|
572
|
+
encodedResolution: `${encWidth}×${encHeight}`,
|
|
573
|
+
scaleDown: scaleDown.toFixed(2),
|
|
557
574
|
bitrate: `${(bitrate / 1_000_000).toFixed(1)}Mbps`,
|
|
558
575
|
contentHint: track.contentHint,
|
|
559
576
|
degradationPreference: "maintain-resolution",
|