Skip to content

Commit 5b5edf4

Browse files
committed
feat: allow patching screen share with audio devices
1 parent 5d675ef commit 5b5edf4

File tree

2 files changed

+67
-16
lines changed

2 files changed

+67
-16
lines changed

src/renderer/components/ScreenSharePicker.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from "@vencord/types/webpack/common";
2222
import { Node } from "@vencord/venmic";
2323
import type { Dispatch, SetStateAction } from "react";
24+
import { patchOverrideAudioDevice } from "renderer/patches/screenShareFixes";
2425
import { addPatch } from "renderer/patches/shared";
2526
import { useSettings } from "renderer/settings";
2627
import { isLinux, isWindows } from "renderer/utils";
@@ -47,6 +48,7 @@ interface StreamSettings {
4748
resolution: StreamResolution;
4849
fps: StreamFps;
4950
audio: boolean;
51+
overrideAudioDevice?: string;
5052
contentHint?: string;
5153
includeSources?: AudioSources;
5254
excludeSources?: AudioSources;
@@ -140,6 +142,8 @@ export function openScreenSharePicker(screens: Source[], skipPicker: boolean) {
140142
}
141143
}
142144

145+
patchOverrideAudioDevice(v.overrideAudioDevice);
146+
143147
resolve(v);
144148
}}
145149
close={() => {
@@ -325,6 +329,11 @@ function StreamSettings({
325329
}
326330
);
327331

332+
const [audioDevices, , audioDevicesPending] = useAwaiter(
333+
() => navigator.mediaDevices.enumerateDevices().then(g => g.filter(d => d.kind === "audioinput")),
334+
{ fallbackValue: [] }
335+
);
336+
328337
const openSettings = () => {
329338
const key = openModal(props => (
330339
<AudioSettingsModal
@@ -428,6 +437,27 @@ function StreamSettings({
428437
</p>
429438
</div>
430439
</div>
440+
441+
<div>
442+
<Forms.FormTitle>
443+
{audioDevicesPending ? "Loading audio devices..." : "Audio devices"}
444+
</Forms.FormTitle>
445+
<Select
446+
options={audioDevices.map(({ label, deviceId }) => ({
447+
label,
448+
value: deviceId
449+
}))}
450+
isSelected={d => settings.overrideAudioDevice === d}
451+
select={d => {
452+
setSettings(v => ({ ...v, overrideAudioDevice: d }));
453+
}}
454+
serialize={String}
455+
popoutPosition="top"
456+
closeOnSelect={true}
457+
isDisabled={audioDevicesPending}
458+
/>
459+
</div>
460+
431461
{isWindows && (
432462
<Switch
433463
value={settings.audio}

src/renderer/patches/screenShareFixes.ts

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,42 @@ import { isLinux } from "renderer/utils";
1010

1111
const logger = new Logger("VesktopStreamFixes");
1212

13-
if (isLinux) {
14-
const original = navigator.mediaDevices.getDisplayMedia;
15-
16-
async function getVirtmic() {
17-
try {
18-
const devices = await navigator.mediaDevices.enumerateDevices();
19-
const audioDevice = devices.find(({ label }) => label === "vencord-screen-share");
20-
return audioDevice?.deviceId;
21-
} catch (error) {
22-
return null;
23-
}
13+
const original = navigator.mediaDevices.getDisplayMedia;
14+
15+
let overrideAudioDevice: string | undefined = undefined;
16+
17+
export const patchOverrideAudioDevice = (deviceId?: string) => {
18+
overrideAudioDevice = deviceId;
19+
};
20+
21+
async function getVirtmic() {
22+
try {
23+
const devices = await navigator.mediaDevices.enumerateDevices();
24+
const audioDevice = devices.find(({ label }) => label === "vencord-screen-share");
25+
return audioDevice?.deviceId;
26+
} catch (error) {
27+
return null;
2428
}
29+
}
30+
31+
navigator.mediaDevices.getDisplayMedia = async function (opts) {
32+
const stream = await original.call(this, opts);
2533

26-
navigator.mediaDevices.getDisplayMedia = async function (opts) {
27-
const stream = await original.call(this, opts);
34+
if (overrideAudioDevice) {
35+
const audio = await navigator.mediaDevices.getUserMedia({
36+
audio: {
37+
deviceId: { exact: overrideAudioDevice },
38+
autoGainControl: false,
39+
echoCancellation: false,
40+
noiseSuppression: false
41+
}
42+
});
43+
44+
stream.getAudioTracks().forEach(t => stream.removeTrack(t));
45+
audio.getAudioTracks().forEach(t => stream.addTrack(t));
46+
}
47+
48+
if (isLinux) {
2849
const id = await getVirtmic();
2950

3051
const frameRate = Number(currentSettings?.fps);
@@ -63,7 +84,7 @@ if (isLinux) {
6384
});
6485
audio.getAudioTracks().forEach(t => stream.addTrack(t));
6586
}
87+
}
6688

67-
return stream;
68-
};
69-
}
89+
return stream;
90+
};

0 commit comments

Comments
 (0)