From b5d676fb78f62f3182903c3b93d145ecf92ca69f Mon Sep 17 00:00:00 2001 From: Myx Date: Thu, 19 Mar 2026 21:39:20 +0100 Subject: [PATCH] New attempt to fix windows screenshare --- .../browser-screen-share.capture.ts | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/app/core/services/webrtc/screen-share-platforms/browser-screen-share.capture.ts b/src/app/core/services/webrtc/screen-share-platforms/browser-screen-share.capture.ts index 7722dcf..c71c860 100644 --- a/src/app/core/services/webrtc/screen-share-platforms/browser-screen-share.capture.ts +++ b/src/app/core/services/webrtc/screen-share-platforms/browser-screen-share.capture.ts @@ -1,5 +1,6 @@ import { ScreenShareQualityPreset, ScreenShareStartOptions } from '../screen-share.config'; import { WebRTCLogger } from '../webrtc-logger'; +import { ScreenShareWindow } from './shared'; export class BrowserScreenShareCapture { constructor(private readonly logger: WebRTCLogger) {} @@ -16,7 +17,11 @@ export class BrowserScreenShareCapture { throw new Error('navigator.mediaDevices.getDisplayMedia is not available.'); } - return await navigator.mediaDevices.getDisplayMedia(displayConstraints); + const stream = await navigator.mediaDevices.getDisplayMedia(displayConstraints); + + this.logAudioTrackSettings(stream); + + return stream; } private buildDisplayMediaConstraints( @@ -24,6 +29,7 @@ export class BrowserScreenShareCapture { preset: ScreenShareQualityPreset ): DisplayMediaStreamOptions { const supportedConstraints = navigator.mediaDevices?.getSupportedConstraints?.() as Record | undefined; + const isWindowsElectron = this.isWindowsElectron(); const audioConstraints: Record | false = options.includeSystemAudio ? { echoCancellation: false, @@ -37,7 +43,10 @@ export class BrowserScreenShareCapture { } if (audioConstraints && supportedConstraints?.['suppressLocalAudioPlayback']) { - audioConstraints['suppressLocalAudioPlayback'] = true; + // Windows Electron should keep voice playback audible to the sharer. + // Use own-audio restriction to keep the app's playback out of the + // captured stream instead of muting local playback. + audioConstraints['suppressLocalAudioPlayback'] = !isWindowsElectron; } return { @@ -53,4 +62,31 @@ export class BrowserScreenShareCapture { systemAudio: options.includeSystemAudio ? 'include' : 'exclude' } as DisplayMediaStreamOptions; } + + private logAudioTrackSettings(stream: MediaStream): void { + const audioTrack = stream.getAudioTracks()[0]; + + if (!audioTrack || typeof audioTrack.getSettings !== 'function') { + return; + } + + const settings = audioTrack.getSettings() as MediaTrackSettings & { + restrictOwnAudio?: boolean; + suppressLocalAudioPlayback?: boolean; + }; + + this.logger.info('getDisplayMedia audio track settings', { + restrictOwnAudio: settings.restrictOwnAudio ?? null, + suppressLocalAudioPlayback: settings.suppressLocalAudioPlayback ?? null + }); + } + + private isWindowsElectron(): boolean { + if (typeof window === 'undefined' || typeof navigator === 'undefined') { + return false; + } + + return !!(window as ScreenShareWindow).electronAPI + && /win/i.test(`${navigator.userAgent} ${navigator.platform}`); + } }