add linux audio picker

This commit is contained in:
Vendicated 2023-09-28 01:55:31 +02:00
parent e93b07001a
commit 7447fe3b70
No known key found for this signature in database
GPG key ID: D66986BAF75ECF18
3 changed files with 55 additions and 5 deletions

View file

@ -55,7 +55,10 @@ export function registerScreenShareHandler() {
const choice = await request.frame
.executeJavaScript(`Vesktop.Components.ScreenShare.openScreenSharePicker(${JSON.stringify(data)})`)
.then(e => e as StreamPick)
.catch(() => null);
.catch(e => {
console.error("Error during screenshare picker", e);
return null;
});
if (!choice) return callback({});

View file

@ -8,10 +8,10 @@ import "./screenSharePicker.css";
import { closeModal, Modals, openModal, useAwaiter } from "@vencord/types/utils";
import { findStoreLazy } from "@vencord/types/webpack";
import { Button, Card, Forms, Switch, Text, useState } from "@vencord/types/webpack/common";
import { Button, Card, Forms, Select, Switch, Text, useState } from "@vencord/types/webpack/common";
import type { Dispatch, SetStateAction } from "react";
import { addPatch } from "renderer/patches/shared";
import { isWindows } from "renderer/utils";
import { isLinux, isWindows } from "renderer/utils";
const StreamResolutions = ["480", "720", "1080", "1440"] as const;
const StreamFps = ["15", "30", "60"] as const;
@ -25,6 +25,7 @@ interface StreamSettings {
resolution: StreamResolution;
fps: StreamFps;
audio: boolean;
audioSource?: string;
}
export interface StreamPick extends StreamSettings {
@ -71,16 +72,21 @@ addPatch({
});
export function openScreenSharePicker(screens: Source[], skipPicker = false) {
let didSubmit = false;
return new Promise<StreamPick>((resolve, reject) => {
const key = openModal(
props => (
<ModalComponent
screens={screens}
modalProps={props}
submit={resolve}
submit={async v => {
didSubmit = true;
if (v.audioSource && v.audioSource !== "None") await VesktopNative.virtmic.start(v.audioSource);
resolve(v);
}}
close={() => {
props.onClose();
reject("Aborted");
if (!didSubmit) reject("Aborted");
}}
skipPicker={skipPicker}
/>
@ -183,11 +189,51 @@ function StreamSettings({
Stream With Audio
</Switch>
)}
{isLinux && (
<AudioSourcePickerLinux
audioSource={settings.audioSource}
setAudioSource={source => setSettings(s => ({ ...s, audioSource: source }))}
/>
)}
</Card>
</div>
);
}
function AudioSourcePickerLinux({
audioSource,
setAudioSource
}: {
audioSource?: string;
setAudioSource(s: string): void;
}) {
const [sources, _, loading] = useAwaiter(() => VesktopNative.virtmic.list(), { fallbackValue: [] });
const sourcesWithNone = sources ? ["None", ...sources] : null;
return (
<section>
<Forms.FormTitle>Audio</Forms.FormTitle>
{loading && <Forms.FormTitle>Loading Audio sources...</Forms.FormTitle>}
{sourcesWithNone === null && (
<Forms.FormTitle>
Failed to retrieve Audio Sources. If you would like to stream with Audio, make sure you're using
Pipewire, not Pulseaudio
</Forms.FormTitle>
)}
{sourcesWithNone && (
<Select
options={sourcesWithNone.map(s => ({ label: s, value: s, default: s === "None" }))}
isSelected={s => s === audioSource}
select={setAudioSource}
serialize={String}
/>
)}
</section>
);
}
function ModalComponent({
screens,
modalProps,

View file

@ -17,3 +17,4 @@ const { platform } = navigator;
export const isWindows = platform.startsWith("Win");
export const isMac = platform.startsWith("Mac");
export const isLinux = platform.startsWith("Linux");