Skip to content

Commit a8e2798

Browse files
committed
feat: add option to mute specific device ID with setMute
1 parent 7f5b0e3 commit a8e2798

File tree

5 files changed

+50
-45
lines changed

5 files changed

+50
-45
lines changed

packages/client-api/src/desktop/desktop-commands.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,21 @@ export type ProviderFunction =
3030

3131
export interface AudioFunction {
3232
type: 'audio';
33-
function: {
34-
name: 'set_volume' | 'set_mute';
35-
args: {
36-
volume?: number;
37-
mute?: boolean;
38-
deviceId?: string;
39-
};
40-
};
33+
function:
34+
| {
35+
name: 'set_volume';
36+
args: {
37+
volume?: number;
38+
deviceId?: string;
39+
};
40+
}
41+
| {
42+
name: 'set_mute';
43+
args: {
44+
mute?: boolean;
45+
deviceId?: string;
46+
};
47+
};
4148
}
4249

4350
export interface MediaFunction {

packages/client-api/src/providers/audio/audio-provider-types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@ export interface AudioOutput {
1212
playbackDevices: AudioDevice[];
1313
recordingDevices: AudioDevice[];
1414
setVolume(volume: number, options?: SetVolumeOptions): Promise<void>;
15-
setMute(mute: boolean): Promise<void>;
15+
setMute(mute: boolean, options?: SetMuteOptions): Promise<void>;
1616
}
1717

1818
export interface SetVolumeOptions {
1919
deviceId?: string;
2020
}
2121

22+
export interface SetMuteOptions {
23+
deviceId?: string;
24+
}
25+
2226
export interface AudioDevice {
2327
deviceId: string;
2428
name: string;

packages/client-api/src/providers/audio/create-audio-provider.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
AudioOutput,
77
AudioProvider,
88
AudioProviderConfig,
9+
SetMuteOptions,
910
SetVolumeOptions,
1011
} from './audio-provider-types';
1112

@@ -36,12 +37,12 @@ export function createAudioProvider(
3637
},
3738
});
3839
},
39-
setMute: (mute: boolean) => {
40+
setMute: (mute: boolean, options?: SetMuteOptions) => {
4041
return desktopCommands.callProviderFunction(configHash, {
4142
type: 'audio',
4243
function: {
4344
name: 'set_mute',
44-
args: { mute },
45+
args: { mute, deviceId: options?.deviceId },
4546
},
4647
});
4748
},

packages/desktop/src/providers/audio/audio_provider.rs

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ enum AudioEvent {
8989
DeviceAdded(String),
9090
DeviceRemoved(String),
9191
DefaultDeviceChanged(String, DeviceType),
92-
VolumeChanged(String, f32),
93-
MuteChanged(String, bool),
92+
VolumeChanged(String, f32, bool),
9493
}
9594

9695
/// Holds the state of an audio device.
@@ -437,13 +436,9 @@ impl AudioProvider {
437436
}
438437
}
439438
}
440-
AudioEvent::VolumeChanged(device_id, new_volume) => {
439+
AudioEvent::VolumeChanged(device_id, new_volume, new_mute) => {
441440
if let Some(state) = self.device_states.get_mut(&device_id) {
442441
state.volume = (new_volume * 100.0).round() as u32;
443-
}
444-
}
445-
AudioEvent::MuteChanged(device_id, new_mute) => {
446-
if let Some(state) = self.device_states.get_mut(&device_id) {
447442
state.is_muted = new_mute;
448443
}
449444
}
@@ -457,41 +452,40 @@ impl AudioProvider {
457452
&mut self,
458453
function: AudioFunction,
459454
) -> anyhow::Result<ProviderFunctionResponse> {
455+
let device_id = match function {
456+
AudioFunction::SetVolume(ref args) => args.device_id.as_ref(),
457+
AudioFunction::SetMute(ref args) => args.device_id.as_ref(),
458+
};
459+
460460
// Get target device - use specified ID or default playback
461461
// device.
462-
let get_device_state =
463-
|device_id: &Option<String>| -> Result<&DeviceState, anyhow::Error> {
464-
if let Some(id) = device_id {
465-
self
466-
.device_states
467-
.get(id)
468-
.context("Specified device not found.")
469-
} else {
470-
self
471-
.default_playback_id
472-
.as_ref()
473-
.and_then(|id| self.device_states.get(id))
474-
.context("No active playback device.")
475-
}
476-
};
462+
let device_state = if let Some(id) = device_id {
463+
self
464+
.device_states
465+
.get(id)
466+
.context("Specified device not found.")?
467+
} else {
468+
self
469+
.default_playback_id
470+
.as_ref()
471+
.and_then(|id| self.device_states.get(id))
472+
.context("No active playback device.")?
473+
};
474+
477475
match function {
478476
AudioFunction::SetVolume(args) => {
479477
unsafe {
480-
get_device_state(&args.device_id)?
481-
.com_volume
482-
.SetMasterVolumeLevelScalar(
483-
args.volume / 100.,
484-
&GUID::zeroed(),
485-
)
478+
device_state.com_volume.SetMasterVolumeLevelScalar(
479+
args.volume / 100.,
480+
&GUID::zeroed(),
481+
)
486482
}?;
487483

488484
Ok(ProviderFunctionResponse::Null)
489485
}
490486
AudioFunction::SetMute(args) => {
491487
unsafe {
492-
get_device_state(&args.device_id)?
493-
.com_volume
494-
.SetMute(args.mute, &GUID::zeroed())
488+
device_state.com_volume.SetMute(args.mute, &GUID::zeroed())
495489
}?;
496490

497491
Ok(ProviderFunctionResponse::Null)
@@ -545,9 +539,6 @@ impl IAudioEndpointVolumeCallback_Impl for VolumeCallback_Impl {
545539
let _ = self.event_tx.send(AudioEvent::VolumeChanged(
546540
self.device_id.clone(),
547541
data.fMasterVolume,
548-
));
549-
let _ = self.event_tx.send(AudioEvent::MuteChanged(
550-
self.device_id.clone(),
551542
data.bMuted.as_bool(),
552543
));
553544
}

packages/desktop/src/providers/provider_function.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ pub enum AudioFunction {
1616
}
1717

1818
#[derive(Debug, Clone, Serialize, Deserialize)]
19+
#[serde(rename_all = "camelCase")]
1920
pub struct SetVolumeArgs {
2021
pub volume: f32,
2122
pub device_id: Option<String>,
2223
}
2324

2425
#[derive(Debug, Clone, Serialize, Deserialize)]
26+
#[serde(rename_all = "camelCase")]
2527
pub struct SetMuteArgs {
2628
pub mute: bool,
2729
pub device_id: Option<String>,

0 commit comments

Comments
 (0)