add linux audio picker
This commit is contained in:
parent
e93b07001a
commit
7447fe3b70
3 changed files with 55 additions and 5 deletions
|
@ -55,7 +55,10 @@ export function registerScreenShareHandler() {
|
||||||
const choice = await request.frame
|
const choice = await request.frame
|
||||||
.executeJavaScript(`Vesktop.Components.ScreenShare.openScreenSharePicker(${JSON.stringify(data)})`)
|
.executeJavaScript(`Vesktop.Components.ScreenShare.openScreenSharePicker(${JSON.stringify(data)})`)
|
||||||
.then(e => e as StreamPick)
|
.then(e => e as StreamPick)
|
||||||
.catch(() => null);
|
.catch(e => {
|
||||||
|
console.error("Error during screenshare picker", e);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
if (!choice) return callback({});
|
if (!choice) return callback({});
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@ import "./screenSharePicker.css";
|
||||||
|
|
||||||
import { closeModal, Modals, openModal, useAwaiter } from "@vencord/types/utils";
|
import { closeModal, Modals, openModal, useAwaiter } from "@vencord/types/utils";
|
||||||
import { findStoreLazy } from "@vencord/types/webpack";
|
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 type { Dispatch, SetStateAction } from "react";
|
||||||
import { addPatch } from "renderer/patches/shared";
|
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 StreamResolutions = ["480", "720", "1080", "1440"] as const;
|
||||||
const StreamFps = ["15", "30", "60"] as const;
|
const StreamFps = ["15", "30", "60"] as const;
|
||||||
|
@ -25,6 +25,7 @@ interface StreamSettings {
|
||||||
resolution: StreamResolution;
|
resolution: StreamResolution;
|
||||||
fps: StreamFps;
|
fps: StreamFps;
|
||||||
audio: boolean;
|
audio: boolean;
|
||||||
|
audioSource?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StreamPick extends StreamSettings {
|
export interface StreamPick extends StreamSettings {
|
||||||
|
@ -71,16 +72,21 @@ addPatch({
|
||||||
});
|
});
|
||||||
|
|
||||||
export function openScreenSharePicker(screens: Source[], skipPicker = false) {
|
export function openScreenSharePicker(screens: Source[], skipPicker = false) {
|
||||||
|
let didSubmit = false;
|
||||||
return new Promise<StreamPick>((resolve, reject) => {
|
return new Promise<StreamPick>((resolve, reject) => {
|
||||||
const key = openModal(
|
const key = openModal(
|
||||||
props => (
|
props => (
|
||||||
<ModalComponent
|
<ModalComponent
|
||||||
screens={screens}
|
screens={screens}
|
||||||
modalProps={props}
|
modalProps={props}
|
||||||
submit={resolve}
|
submit={async v => {
|
||||||
|
didSubmit = true;
|
||||||
|
if (v.audioSource && v.audioSource !== "None") await VesktopNative.virtmic.start(v.audioSource);
|
||||||
|
resolve(v);
|
||||||
|
}}
|
||||||
close={() => {
|
close={() => {
|
||||||
props.onClose();
|
props.onClose();
|
||||||
reject("Aborted");
|
if (!didSubmit) reject("Aborted");
|
||||||
}}
|
}}
|
||||||
skipPicker={skipPicker}
|
skipPicker={skipPicker}
|
||||||
/>
|
/>
|
||||||
|
@ -183,11 +189,51 @@ function StreamSettings({
|
||||||
Stream With Audio
|
Stream With Audio
|
||||||
</Switch>
|
</Switch>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{isLinux && (
|
||||||
|
<AudioSourcePickerLinux
|
||||||
|
audioSource={settings.audioSource}
|
||||||
|
setAudioSource={source => setSettings(s => ({ ...s, audioSource: source }))}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</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({
|
function ModalComponent({
|
||||||
screens,
|
screens,
|
||||||
modalProps,
|
modalProps,
|
||||||
|
|
|
@ -17,3 +17,4 @@ const { platform } = navigator;
|
||||||
|
|
||||||
export const isWindows = platform.startsWith("Win");
|
export const isWindows = platform.startsWith("Win");
|
||||||
export const isMac = platform.startsWith("Mac");
|
export const isMac = platform.startsWith("Mac");
|
||||||
|
export const isLinux = platform.startsWith("Linux");
|
||||||
|
|
Reference in a new issue