diff --git a/src/main/virtmic.ts b/src/main/virtmic.ts index e17d2c4..4c415b4 100644 --- a/src/main/virtmic.ts +++ b/src/main/virtmic.ts @@ -9,16 +9,28 @@ import { join } from "path"; import { IpcEvents } from "shared/IpcEvents"; import { STATIC_DIR } from "shared/paths"; -const importVenmic = () => require(join(STATIC_DIR, "dist/venmic.node")) as typeof import("venmic"); +let initialized = false; +let patchBay: import("venmic").PatchBay | undefined; -ipcMain.handle(IpcEvents.VIRT_MIC_LIST, async () => - importVenmic() - .list() - .map(m => m.name) +function obtainVenmic() { + if (!initialized) { + initialized = true; + try { + const { PatchBay } = require(join(STATIC_DIR, "dist/venmic.node")) as typeof import("venmic"); + patchBay = new PatchBay(); + } catch (e) { + console.error("Failed to initialise venmic. Make sure you're using pipewire", e); + } + } + + return patchBay; +} + +ipcMain.handle(IpcEvents.VIRT_MIC_LIST, () => obtainVenmic()?.list() ?? []); + +ipcMain.handle( + IpcEvents.VIRT_MIC_START, + (_, target: string, mode: "include" | "exclude") => obtainVenmic()?.link(target, mode) ); -ipcMain.handle(IpcEvents.VIRT_MIC_START, (_, target: string) => { - importVenmic().link(target); -}); - -ipcMain.handle(IpcEvents.VIRT_MIC_KILL, () => importVenmic().unlink()); +ipcMain.handle(IpcEvents.VIRT_MIC_KILL, () => obtainVenmic()?.unlink()); diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 0ba545d..10f2ede 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -63,7 +63,7 @@ export const VesktopNative = { /** only available on Linux. */ virtmic: { list: () => invoke(IpcEvents.VIRT_MIC_LIST), - start: (target: string) => invoke(IpcEvents.VIRT_MIC_START, target), + start: (target: string, mode: "include" | "exclude") => invoke(IpcEvents.VIRT_MIC_START, target, mode), kill: () => invoke(IpcEvents.VIRT_MIC_KILL) }, arrpc: { diff --git a/src/renderer/components/ScreenSharePicker.tsx b/src/renderer/components/ScreenSharePicker.tsx index fc0cd0c..fd59d1c 100644 --- a/src/renderer/components/ScreenSharePicker.tsx +++ b/src/renderer/components/ScreenSharePicker.tsx @@ -81,7 +81,13 @@ export function openScreenSharePicker(screens: Source[], skipPicker: boolean) { modalProps={props} submit={async v => { didSubmit = true; - if (v.audioSource && v.audioSource !== "None") await VesktopNative.virtmic.start(v.audioSource); + if (v.audioSource && v.audioSource !== "None") { + if (v.audioSource === "Entire System") { + await VesktopNative.virtmic.start("Chromium", "exclude"); + } else { + await VesktopNative.virtmic.start(v.audioSource, "include"); + } + } resolve(v); }} close={() => { @@ -214,22 +220,22 @@ function AudioSourcePickerLinux({ setAudioSource(s: string): void; }) { const [sources, _, loading] = useAwaiter(() => VesktopNative.virtmic.list(), { fallbackValue: [] }); - const sourcesWithNone = sources ? ["None", ...sources] : null; + const allSources = sources ? ["None", "Entire System", ...sources] : null; return (
Audio {loading && Loading Audio sources...} - {sourcesWithNone === null && ( + {allSources === null && ( Failed to retrieve Audio Sources. If you would like to stream with Audio, make sure you're using Pipewire, not Pulseaudio )} - {sourcesWithNone && ( + {allSources && (