Skip to content

Commit

Permalink
feat: allow patching screenshare with any audio device
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanccn committed Dec 8, 2023
1 parent 623fa5d commit d4453f6
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
42 changes: 42 additions & 0 deletions src/renderer/components/ScreenSharePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
useState
} from "@vencord/types/webpack/common";
import type { Dispatch, SetStateAction } from "react";
import { patchAudioWithDevice } from "renderer/patches/screenShareAudio";
import { addPatch } from "renderer/patches/shared";
import { isLinux, isWindows } from "renderer/utils";

Expand All @@ -36,6 +37,7 @@ interface StreamSettings {
fps: StreamFps;
audio: boolean;
audioSource?: string;
audioDevice?: string;
}

export interface StreamPick extends StreamSettings {
Expand Down Expand Up @@ -109,6 +111,9 @@ export function openScreenSharePicker(screens: Source[], skipPicker: boolean) {
await VesktopNative.virtmic.start([v.audioSource]);
}
}

patchAudioWithDevice(v.audioDevice);

resolve(v);
}}
close={() => {
Expand Down Expand Up @@ -211,6 +216,11 @@ function StreamSettings({
</section>
</div>

<AudioSourceAnyDevice
audioDevice={settings.audioDevice}
setAudioDevice={source => setSettings(s => ({ ...s, audioDevice: source }))}
/>

{isWindows && (
<Switch
value={settings.audio}
Expand All @@ -233,6 +243,38 @@ function StreamSettings({
);
}

function AudioSourceAnyDevice({
audioDevice,
setAudioDevice
}: {
audioDevice?: string;
setAudioDevice(s: string): void;
}) {
const [sources, _, loading] = useAwaiter(
() =>
navigator.mediaDevices
.enumerateDevices()
.then(devices => devices.filter(device => device.kind === "audioinput")),
{ fallbackValue: [] }
);

return (
<section>
<Forms.FormTitle>Audio</Forms.FormTitle>
{loading && <Forms.FormTitle>Loading audio devices...</Forms.FormTitle>}

{sources.length > 0 && (
<Select
options={sources.map((s, idx) => ({ label: s.label, value: s.deviceId, default: idx === 0 }))}
isSelected={s => s === audioDevice}
select={setAudioDevice}
serialize={String}
/>
)}
</section>
);
}

function AudioSourcePickerLinux({
audioSource,
setAudioSource
Expand Down
22 changes: 20 additions & 2 deletions src/renderer/patches/screenShareAudio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,27 @@

import { isLinux } from "renderer/utils";

if (isLinux) {
const original = navigator.mediaDevices.getDisplayMedia;
const original = navigator.mediaDevices.getDisplayMedia;

export const patchAudioWithDevice = (deviceId?: string) => {
if (!deviceId) {
navigator.mediaDevices.getDisplayMedia = original;
return;
}

navigator.mediaDevices.getDisplayMedia = async function (opts) {
const stream = await original.call(this, opts);
const audio = await navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: deviceId } } });
const tracks = audio.getAudioTracks();

tracks.forEach(t => stream.addTrack(t));
console.log(`Patched stream ${stream.id} with ${tracks.length} audio tracks from ${deviceId}`);

return stream;
};
};

if (isLinux) {
async function getVirtmic() {
try {
const devices = await navigator.mediaDevices.enumerateDevices();
Expand Down

0 comments on commit d4453f6

Please sign in to comment.