diff --git a/package.json b/package.json index 294a9c4..68d26c1 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "electron-updater": "6.6.2" }, "optionalDependencies": { - "@vencord/venmic": "^7.1.0" + "@vencord/venmic": "^6.1.0" }, "devDependencies": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a776af8..3e09751 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -96,8 +96,8 @@ importers: version: 3.7.0 optionalDependencies: '@vencord/venmic': - specifier: ^7.1.0 - version: 7.1.0(supports-color@7.2.0) + specifier: ^6.1.0 + version: 6.1.0(supports-color@7.2.0) packages/libvesktop: devDependencies: @@ -562,8 +562,8 @@ packages: '@types/react': 18.3.1 '@types/react-dom': 18.3.1 - '@vencord/venmic@7.1.0': - resolution: {integrity: sha512-HQpZoUKGz8j7m1+1BCgE+7B6T/+/IArVO8km7SjsWxe/5+2YblAs0Fwgy9C9XqCCir/u0+F1FMqrQQUX2PATYw==} + '@vencord/venmic@6.1.0': + resolution: {integrity: sha512-YiCtzml/W8tYbGhu3jm5jfbbEnl2slKKARNK0jO+8qV979k9eFnfIRTxvhMN/SWq1h8ZNJdXVwvXpffQwq0RuA==} engines: {node: '>=14.15'} os: [linux] @@ -3324,7 +3324,7 @@ snapshots: ts-pattern: 5.9.0 type-fest: 5.8.0 - '@vencord/venmic@7.1.0(supports-color@7.2.0)': + '@vencord/venmic@6.1.0(supports-color@7.2.0)': dependencies: cmake-js: 7.4.0(supports-color@7.2.0) node-addon-api: 8.9.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 8306458..23f5fc8 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -13,5 +13,4 @@ recursiveInstall: false packages: - packages/* minimumReleaseAgeExclude: - - electron - - '@vencord/*' + - electron \ No newline at end of file diff --git a/src/main/venmic.ts b/src/main/venmic.ts index 80192c5..b6a0d08 100644 --- a/src/main/venmic.ts +++ b/src/main/venmic.ts @@ -66,23 +66,28 @@ function getRendererAudioServicePid() { ); } -function buildLinkData({ include, exclude }: { include?: Node[]; exclude?: Node[] }) { - const pid = getRendererAudioServicePid(); +ipcMain.handle(IpcEvents.VIRT_MIC_LIST, () => { + const audioPid = getRendererAudioServicePid(); - const { mute, ignoreDevices, ignoreInputMedia, ignoreVirtual, workaround, onlySpeakers, onlyDefaultSpeakers } = - Settings.store.audio ?? {}; + const { granularSelect } = Settings.store.audio ?? {}; + + const targets = obtainVenmic() + ?.list(granularSelect ? ["node.name"] : undefined) + .filter(s => s["application.process.id"] !== audioPid); + + return targets ? { ok: true, targets, hasPipewirePulse } : { ok: false, isGlibCxxOutdated }; +}); + +ipcMain.handle(IpcEvents.VIRT_MIC_START, (_, include: Node[]) => { + const pid = getRendererAudioServicePid(); + const { ignoreDevices, ignoreInputMedia, ignoreVirtual, workaround } = Settings.store.audio ?? {}; const data: LinkData = { - mute: mute ?? true, - include: include ?? [], - exclude: exclude ?? [], - only_speakers: onlySpeakers, - ignore_devices: ignoreDevices, - only_default_speakers: onlyDefaultSpeakers + include, + exclude: [{ "application.process.id": pid }], + ignore_devices: ignoreDevices }; - data.exclude.push({ "application.process.id": pid }); - if (ignoreInputMedia ?? true) { data.exclude.push({ "media.class": "Stream/Input/Audio" }); } @@ -95,31 +100,36 @@ function buildLinkData({ include, exclude }: { include?: Node[]; exclude?: Node[ data.workaround = [{ "application.process.id": pid, "media.name": "RecordStream" }]; } - return data; -} - -ipcMain.handle(IpcEvents.VIRT_MIC_LIST, () => { - const audioPid = getRendererAudioServicePid(); - - const { granularSelect } = Settings.store.audio ?? {}; - - const targets = obtainVenmic() - ?.list(granularSelect ? [] : ["application.name", "node.name"]) - .filter(s => s["application.process.id"] !== audioPid); - - return targets ? { ok: true, targets, hasPipewirePulse } : { ok: false, isGlibCxxOutdated }; -}); - -ipcMain.handle(IpcEvents.VIRT_MIC_START, (_, include: Node[]) => { - return obtainVenmic()?.link(buildLinkData({ include })); + return obtainVenmic()?.link(data); }); ipcMain.handle(IpcEvents.VIRT_MIC_START_SYSTEM, (_, exclude: Node[]) => { - return obtainVenmic()?.link(buildLinkData({ exclude })); -}); + const pid = getRendererAudioServicePid(); -ipcMain.handle(IpcEvents.VIRT_MIC_UNMUTE, () => { - return obtainVenmic()?.unmute(); + const { workaround, ignoreDevices, ignoreInputMedia, ignoreVirtual, onlySpeakers, onlyDefaultSpeakers } = + Settings.store.audio ?? {}; + + const data: LinkData = { + include: [], + exclude: [{ "application.process.id": pid }, ...exclude], + only_speakers: onlySpeakers, + ignore_devices: ignoreDevices, + only_default_speakers: onlyDefaultSpeakers + }; + + if (ignoreInputMedia ?? true) { + data.exclude.push({ "media.class": "Stream/Input/Audio" }); + } + + if (ignoreVirtual) { + data.exclude.push({ "node.virtual": "true" }); + } + + if (workaround) { + data.workaround = [{ "application.process.id": pid, "media.name": "RecordStream" }]; + } + + return obtainVenmic()?.link(data); }); ipcMain.handle(IpcEvents.VIRT_MIC_STOP, () => obtainVenmic()?.unlink()); diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 1dd6710..e11fae7 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -92,7 +92,6 @@ export const VesktopNative = { >(IpcEvents.VIRT_MIC_LIST), start: (include: Node[]) => invoke(IpcEvents.VIRT_MIC_START, include), startSystem: (exclude: Node[]) => invoke(IpcEvents.VIRT_MIC_START_SYSTEM, exclude), - unmute: () => invoke(IpcEvents.VIRT_MIC_UNMUTE), stop: () => invoke(IpcEvents.VIRT_MIC_STOP) }, clipboard: { diff --git a/src/renderer/components/ScreenSharePicker.tsx b/src/renderer/components/ScreenSharePicker.tsx index 69d8d63..4f8d7aa 100644 --- a/src/renderer/components/ScreenSharePicker.tsx +++ b/src/renderer/components/ScreenSharePicker.tsx @@ -121,25 +121,15 @@ addPatch({ if (isLinux) { onceReady.then(() => { - const ownsStream = (streamKey: string) => { - return streamKey.split(":").at(-1) === UserStore.getCurrentUser().id; - }; - FluxDispatcher.subscribe("STREAM_CLOSE", ({ streamKey }: { streamKey: string }) => { - if (!ownsStream(streamKey)) { + const owner = streamKey.split(":").at(-1); + + if (owner !== UserStore.getCurrentUser().id) { return; } VesktopNative.virtmic.stop(); }); - - FluxDispatcher.subscribe("STREAM_UPDATE", ({ streamKey }: { streamKey: string }) => { - if (!ownsStream(streamKey)) { - return; - } - - VesktopNative.virtmic.unmute(); - }); }); } @@ -226,13 +216,6 @@ function AudioSettingsModal({ actions={[{ text: "Back", variant: "secondary", onClick: close }]} >
- (Settings.audio = { ...Settings.audio, mute: v })} - value={Settings.audio?.mute ?? true} - /> value[key] === other[key]); +} + function mapToAudioItem(node: AudioSource, granularSelect?: boolean, deviceSelect?: boolean): AudioItem[] { if (isSpecialSource(node)) { return [{ name: node, value: node }]; } + const rtn: AudioItem[] = []; + const mediaClass = node["media.class"]; if (mediaClass?.includes("Video") || mediaClass?.includes("Midi")) { - return []; + return rtn; } if (!deviceSelect && node["device.id"]) { - return []; + return rtn; } - const preferred = ["application.name", "node.description", "node.name", "application.process.binary"] as const; - const prop = preferred.find(prop => node[prop]); + const name = node["application.name"]; - if (!prop) { - return []; + if (name) { + rtn.push({ name: name, value: { "application.name": name } }); } - const name = node[prop]!; - const items: AudioItem[] = [{ name: name, value: { [prop]: name } }]; - if (!granularSelect) { - return items; + return rtn; } - let granularName = name; - const granularProps: Node = { [prop]: name }; + const rawName = node["node.name"]; - const append = (name: string, brackets: string) => { - const value = node[name]; + if (!name) { + rtn.push({ name: rawName, value: { "node.name": rawName } }); + } - if (!value) { - return; - } + const binary = node["application.process.binary"]; - granularName += ` ${brackets[0]}${value}${brackets[1]}`; - granularProps[name] = value; - }; + if (!name && binary) { + rtn.push({ name: binary, value: { "application.process.binary": binary } }); + } - append("application.process.id", "<>"); - append("application.process.binary", "()"); - append("media.name", "[]"); + const pid = node["application.process.id"]; - items.push({ name: granularName, value: granularProps }); + const first = rtn[0]; + const firstValues = first.value as Node; - return items; -} + if (pid) { + rtn.push({ + name: `${first.name} (${pid})`, + value: { ...firstValues, "application.process.id": pid } + }); + } -function hasMatchingProps(value: Node, other: Node) { - const keys = Object.keys(value); - return keys.length === Object.keys(other).length && keys.every(key => value[key] === other[key]); + const mediaName = node["media.name"]; + + if (mediaName) { + rtn.push({ + name: `${first.name} [${mediaName}]`, + value: { ...firstValues, "media.name": mediaName } + }); + } + + if (mediaClass) { + rtn.push({ + name: `${first.name} [${mediaClass}]`, + value: { ...firstValues, "media.class": mediaClass } + }); + } + + return rtn; } function isItemSelected(sources?: AudioSources) { @@ -647,10 +647,9 @@ function AudioSourcePickerLinux({ }))} isSelected={isItemSelected(includeSources)} select={updateItems(setIncludeSources, includeSources)} - serialize={JSON.stringify} + serialize={String} popoutPosition="top" closeOnSelect={false} - renderOptionLabel={o => o.label} /> @@ -668,10 +667,9 @@ function AudioSourcePickerLinux({ }))} isSelected={isItemSelected(excludeSources)} select={updateItems(setExcludeSources, excludeSources)} - serialize={JSON.stringify} + serialize={String} popoutPosition="top" closeOnSelect={false} - renderOptionLabel={o => o.label} /> diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index 55efe80..13f27b4 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -49,7 +49,6 @@ export const enum IpcEvents { VIRT_MIC_LIST = "VCD_VIRT_MIC_LIST", VIRT_MIC_START = "VCD_VIRT_MIC_START", VIRT_MIC_START_SYSTEM = "VCD_VIRT_MIC_START_ALL", - VIRT_MIC_UNMUTE = "VCD_VIRT_MIC_UNMUTE", VIRT_MIC_STOP = "VCD_VIRT_MIC_STOP", CLIPBOARD_COPY_IMAGE = "VCD_CLIPBOARD_COPY_IMAGE", diff --git a/src/shared/settings.d.ts b/src/shared/settings.d.ts index 53065c9..9eb1045 100644 --- a/src/shared/settings.d.ts +++ b/src/shared/settings.d.ts @@ -50,7 +50,6 @@ export interface Settings { ignoreDevices?: boolean; ignoreInputMedia?: boolean; - mute?: boolean; onlySpeakers?: boolean; onlyDefaultSpeakers?: boolean; };