Skip to content

Commit

Permalink
AudioShare: Even more granular selection, Allow device sharing (#750)
Browse files Browse the repository at this point in the history
  • Loading branch information
Curve authored Jul 12, 2024
1 parent 61bbd7f commit 9acc665
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/main/venmic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ ipcMain.handle(IpcEvents.VIRT_MIC_LIST, () => {
const { granularSelect } = Settings.store.audio ?? {};

const targets = obtainVenmic()
?.list(granularSelect ? ["application.process.id"] : undefined)
?.list(granularSelect ? ["node.name"] : undefined)
.filter(s => s["application.process.id"] !== audioPid);

return targets ? { ok: true, targets, hasPipewirePulse } : { ok: false, isGlibCxxOutdated };
Expand Down
74 changes: 57 additions & 17 deletions src/renderer/components/ScreenSharePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,13 @@ function AudioSettingsModal({
</Switch>
<Switch
hideBorder
onChange={v => (Settings.audio = { ...Settings.audio, ignoreDevices: v })}
onChange={v =>
(Settings.audio = {
...Settings.audio,
ignoreDevices: v,
deviceSelect: v ? false : Settings.audio?.deviceSelect
})
}
value={Settings.audio?.ignoreDevices ?? true}
note={<>Exclude device nodes, such as nodes belonging to microphones or speakers.</>}
>
Expand All @@ -271,6 +277,23 @@ function AudioSettingsModal({
>
Granular Selection
</Switch>
<Switch
hideBorder
onChange={value => {
Settings.audio = { ...Settings.audio, deviceSelect: value };
setAudioSources("None");
}}
value={Settings.audio?.deviceSelect ?? false}
disabled={Settings.audio?.ignoreDevices}
note={
<>
Allow to select devices such as microphones. Requires <b>Ignore Devices</b> to be turned
off.
</>
}
>
Device Selection
</Switch>
</Modals.ModalContent>
<Modals.ModalFooter className="vcd-screen-picker-footer">
<Button color={Button.Colors.TRANSPARENT} onClick={close}>
Expand Down Expand Up @@ -423,6 +446,7 @@ function StreamSettings({
openSettings={openSettings}
includeSources={settings.includeSources}
excludeSources={settings.excludeSources}
deviceSelect={Settings.audio?.deviceSelect}
granularSelect={Settings.audio?.granularSelect}
setIncludeSources={sources => setSettings(s => ({ ...s, includeSources: sources }))}
setExcludeSources={sources => setSettings(s => ({ ...s, excludeSources: sources }))}
Expand All @@ -441,13 +465,23 @@ function hasMatchingProps(value: Node, other: Node) {
return Object.keys(value).every(key => value[key] === other[key]);
}

function mapToAudioItem(node: AudioSource, granularSelect?: boolean): AudioItem[] {
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 rtn;
}

if (!deviceSelect && node["device.id"]) {
return rtn;
}

const name = node["application.name"];

if (name) {
Expand All @@ -458,9 +492,15 @@ function mapToAudioItem(node: AudioSource, granularSelect?: boolean): AudioItem[
return rtn;
}

const binary = node["application.process.binary"];
const rawName = node["node.name"];

if (!name) {
rtn.push({ name: rawName, value: { "node.name": rawName } });
}

const binary = node["application.process.binary"];

if (!name && binary) {
rtn.push({ name: binary, value: { "application.process.binary": binary } });
}

Expand All @@ -469,10 +509,12 @@ function mapToAudioItem(node: AudioSource, granularSelect?: boolean): AudioItem[
const first = rtn[0];
const firstValues = first.value as Node;

rtn.push({
name: `${first.name} (${pid})`,
value: { ...firstValues, "application.process.id": pid }
});
if (pid) {
rtn.push({
name: `${first.name} (${pid})`,
value: { ...firstValues, "application.process.id": pid }
});
}

const mediaName = node["media.name"];

Expand All @@ -483,17 +525,13 @@ function mapToAudioItem(node: AudioSource, granularSelect?: boolean): AudioItem[
});
}

const mediaClass = node["media.class"];

if (!mediaClass) {
return rtn;
if (mediaClass) {
rtn.push({
name: `${first.name} [${mediaClass}]`,
value: { ...firstValues, "media.class": mediaClass }
});
}

rtn.push({
name: `${first.name} [${mediaClass}]`,
value: { ...firstValues, "media.class": mediaClass }
});

return rtn;
}

Expand Down Expand Up @@ -535,13 +573,15 @@ function updateItems(setSources: (s: AudioSources) => void, sources?: AudioSourc
function AudioSourcePickerLinux({
includeSources,
excludeSources,
deviceSelect,
granularSelect,
openSettings,
setIncludeSources,
setExcludeSources
}: {
includeSources?: AudioSources;
excludeSources?: AudioSources;
deviceSelect?: boolean;
granularSelect?: boolean;
openSettings: () => void;
setIncludeSources: (s: AudioSources) => void;
Expand Down Expand Up @@ -592,7 +632,7 @@ function AudioSourcePickerLinux({

const allSources = sources.ok
? [...specialSources, ...sources.targets]
.map(target => mapToAudioItem(target, granularSelect))
.map(target => mapToAudioItem(target, granularSelect, deviceSelect))
.flat()
.filter(uniqueName)
: [];
Expand Down
2 changes: 2 additions & 0 deletions src/shared/settings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export interface Settings {

audio?: {
workaround?: boolean;

deviceSelect?: boolean;
granularSelect?: boolean;

ignoreVirtual?: boolean;
Expand Down

0 comments on commit 9acc665

Please sign in to comment.