feat: allow patching screenshare with any audio device

This commit is contained in:
Ryan Cao 2023-10-28 15:41:54 +08:00
parent 4abae9c708
commit 6a7bffc76a
No known key found for this signature in database
2 changed files with 62 additions and 2 deletions

View file

@ -20,6 +20,7 @@ import {
useState useState
} from "@vencord/types/webpack/common"; } from "@vencord/types/webpack/common";
import type { Dispatch, SetStateAction } from "react"; import type { Dispatch, SetStateAction } from "react";
import { patchAudioWithDevice } from "renderer/patches/screenShareAudio";
import { addPatch } from "renderer/patches/shared"; import { addPatch } from "renderer/patches/shared";
import { isLinux, isWindows } from "renderer/utils"; import { isLinux, isWindows } from "renderer/utils";
@ -37,6 +38,7 @@ interface StreamSettings {
audio: boolean; audio: boolean;
audioSource?: string; audioSource?: string;
workaround?: boolean; workaround?: boolean;
audioDevice?: string;
} }
export interface StreamPick extends StreamSettings { export interface StreamPick extends StreamSettings {
@ -113,6 +115,9 @@ export function openScreenSharePicker(screens: Source[], skipPicker: boolean) {
await VesktopNative.virtmic.start([v.audioSource], v.workaround); await VesktopNative.virtmic.start([v.audioSource], v.workaround);
} }
} }
patchAudioWithDevice(v.audioDevice);
resolve(v); resolve(v);
}} }}
close={() => { close={() => {
@ -215,6 +220,11 @@ function StreamSettings({
</section> </section>
</div> </div>
<AudioSourceAnyDevice
audioDevice={settings.audioDevice}
setAudioDevice={source => setSettings(s => ({ ...s, audioDevice: source }))}
/>
{isWindows && ( {isWindows && (
<Switch <Switch
value={settings.audio} value={settings.audio}
@ -239,6 +249,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({ function AudioSourcePickerLinux({
audioSource, audioSource,
workaround, workaround,

View file

@ -6,9 +6,27 @@
import { isLinux } from "renderer/utils"; 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() { async function getVirtmic() {
try { try {
const devices = await navigator.mediaDevices.enumerateDevices(); const devices = await navigator.mediaDevices.enumerateDevices();