fix(call): volume>100% crash, picker UI freeze, native-path diagnostics

Volume crash:
- setParticipantVolume / setScreenShareVolume propagated values up to 2.0
(200%) to the per-track GainNode, but also called applyToAttachedElements
which set the raw HTMLAudioElement.volume — that property is hard-clamped
to [0, 1] and throws IndexSizeError above 1. Clip the element-path apply
at 1.0. WebAudio GainNode keeps doing the actual amplification.

Picker freeze:
- Firing ~20 captureScreenSourceThumbnail invokes in parallel caused
perceptible input freezes while each ~100KB base64 result arrived and
triggered a setState. Bounded the worker pool to 4 concurrent captures
with a queue — overall wall-clock is nearly identical and the grid stays
scrollable / clickable throughout the load.

Native-path diagnostics:
- Previous logs only fired on non-NativeCaptureUnavailable errors, so
users couldn't tell whether the native path was skipped (audio toggle
on, no sourceId) or attempted-and-failed. Added explicit info logs for
each skip reason plus an always-on warn with the underlying error when
the try block throws. Makes the next debug pass on screenshare much
quicker.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
byGalax
2026-04-22 21:50:20 +02:00
parent c3e0c47d32
commit a5e930ac17
4 changed files with 53 additions and 24 deletions
+15 -3
View File
@@ -1196,8 +1196,18 @@ export function CallProvider({ children }: { children: ReactNode }) {
// completely skips the OS picker. Video-only (no system audio yet);
// if the user asked for audio we fall through to the legacy paths
// below so audio still works via getDisplayMedia.
if (!sourceId) {
console.info(
'screen-share: no sourceId supplied by picker, OS picker will open',
);
} else if (settings.includeSystemAudio) {
console.info(
'screen-share: system audio requested — native path unavailable (needs WASAPI/ScreenCaptureKit), OS picker will open',
);
}
if (sourceId && !settings.includeSystemAudio) {
try {
console.info('screen-share: trying native capture path', { sourceId, fps });
const { Track: LkTrack } = await import('livekit-client');
const maxWidth = ssParams.dims?.width ?? 1920;
const maxHeight = ssParams.dims?.height ?? 1080;
@@ -1236,6 +1246,7 @@ export function CallProvider({ children }: { children: ReactNode }) {
setIsScreenSharing(false);
})();
});
console.info('screen-share: native capture active');
setIsScreenSharing(true);
return;
} catch (err: unknown) {
@@ -1246,9 +1257,10 @@ export function CallProvider({ children }: { children: ReactNode }) {
await nativeCaptureRef.current.stop().catch(() => undefined);
nativeCaptureRef.current = null;
}
if (!(err instanceof NativeCaptureUnavailable)) {
console.warn('native screen-capture failed, falling back', err);
}
console.warn(
'screen-share: native path failed, falling back',
err instanceof Error ? err.message : err,
);
}
}