feat: allow patching screenshare with any audio device
This commit is contained in:
parent
4abae9c708
commit
6a7bffc76a
2 changed files with 62 additions and 2 deletions
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Reference in a new issue