diff --git a/README.md b/README.md
index 368527f..1d0e77d 100644
--- a/README.md
+++ b/README.md
@@ -28,3 +28,4 @@ Mixrs will create a unix socket at `/tmp/mixrs` and listen for instructions. Ins
|6|PlayPauseCurrent|Tells the current sink input to toggle its `playing` state.
*Behavior varies based on the current sink input's player*|
|7|PlayNext|Tells the current sink input to play the next item (e.g. the next song).
*Behavior varies based on the current sink input's player*|
|8|PlayPrevious|Tells the current sink input to play the previous item (e.g. the previous song).
*Behavior varies based on the current sink input's player*|
+|9|GetCurrentOutput|Gets information about the currently selected sink input and sends it through the requesting unix socket|
diff --git a/src/instructions.rs b/src/instructions.rs
index 4d8efb2..812f11e 100644
--- a/src/instructions.rs
+++ b/src/instructions.rs
@@ -9,6 +9,7 @@ pub enum MixerInstruction {
PlayPauseCurrent,
PlayNext,
PlayPrevious,
+ GetCurrentOutput,
}
impl MixerInstruction {
@@ -23,6 +24,7 @@ impl MixerInstruction {
6 => Some(MixerInstruction::PlayPauseCurrent),
7 => Some(MixerInstruction::PlayNext),
8 => Some(MixerInstruction::PlayPrevious),
+ 9 => Some(MixerInstruction::GetCurrentOutput),
_ => None,
}
}
diff --git a/src/mixer.rs b/src/mixer.rs
index f5d6266..d4a17c5 100644
--- a/src/mixer.rs
+++ b/src/mixer.rs
@@ -4,8 +4,8 @@ use std::{
borrow::{Borrow, BorrowMut},
collections::HashMap,
fs,
- io::Read,
- os::unix::net::UnixListener,
+ io::{Read, Write},
+ os::unix::net::{UnixListener, UnixStream},
path::Path,
sync::{
mpsc::{channel, Receiver, Sender},
@@ -124,7 +124,7 @@ impl Mixer {
.create_socket_listener()
.expect("Error creating unix socket listener");
- let (mixer_tx, mixer_rx) = channel::();
+ let (mixer_tx, mixer_rx) = channel::<(MixerInstruction, UnixStream)>();
thread::spawn(move || {
for client in listener.incoming() {
@@ -134,7 +134,7 @@ impl Mixer {
stream.read_to_end(&mut buf).expect("Error reading stream");
match MixerInstruction::from_u8(buf[0]) {
- Some(ix) => mixer_tx.send(ix).unwrap(),
+ Some(ix) => mixer_tx.send((ix, stream)).unwrap(),
None => println!("Invalid instruction: {}", buf[0]),
}
}
@@ -181,7 +181,7 @@ impl Mixer {
loop {
match mixer_rx.try_recv() {
- Ok(ix) => match ix {
+ Ok((ix, stream)) => match ix {
MixerInstruction::SelectNext => self.select_next(),
MixerInstruction::SelectPrevious => self.select_previous(),
MixerInstruction::ToggleMuteCurrent => self.toggle_mute_current(),
@@ -191,6 +191,7 @@ impl Mixer {
MixerInstruction::PlayPauseCurrent => self.play_pause_current(),
MixerInstruction::PlayNext => self.play_next_current(),
MixerInstruction::PlayPrevious => self.play_previous_current(),
+ MixerInstruction::GetCurrentOutput => self.get_current_output(stream),
},
Err(_) => (),
}
@@ -495,7 +496,10 @@ impl Mixer {
let _ = send_notification_with_progress(
&format!(
"({}/{}) {}: {}%",
- index + 1, sink_inputs_length, ¤t_sink.name, current_sink_volume_percent
+ index + 1,
+ sink_inputs_length,
+ ¤t_sink.name,
+ current_sink_volume_percent
),
current_sink_volume_percent,
);
@@ -560,6 +564,31 @@ impl Mixer {
Err(_) => (),
};
}
+
+ pub fn get_current_output(&self, mut stream: UnixStream) {
+ let index_lock = self.selected_index.lock().unwrap();
+
+ let Some(index) = *index_lock else {
+ return;
+ };
+
+ drop(index_lock);
+
+ let Some(sink_index) = self.sink_inputs.keys().nth(index) else {
+ return;
+ };
+
+ let Some(sink_input) = self.sink_inputs.get(sink_index) else {
+ return;
+ };
+
+ let _ = stream.write_all(
+ sink_input
+ .get_output_data(index, self.sink_inputs.len(), *sink_index)
+ .as_bytes(),
+ );
+ let _ = stream.shutdown(std::net::Shutdown::Both);
+ }
}
pub fn iterate_mainloop(mainloop: &mut pulse::mainloop::standard::Mainloop) {
diff --git a/src/pulseaudio/mod.rs b/src/pulseaudio/mod.rs
index 0b83a91..6255d66 100644
--- a/src/pulseaudio/mod.rs
+++ b/src/pulseaudio/mod.rs
@@ -29,4 +29,17 @@ impl SinkInputMixerData {
pub fn get_volume_percent(&self) -> u8 {
total_volume_to_percentage(self.volume)
}
+
+ /// Formats the sink input data to a string separating fields by new lines
+ pub fn get_output_data(
+ &self,
+ selection_index: usize,
+ sink_count: usize,
+ sink_index: u32,
+ ) -> String {
+ format!(
+ "selection: {}/{sink_count}\nid: {sink_index}\nname: {}\nvolume: {}\nvolume_percentage: {}\nmuted: {}\n",
+ selection_index + 1, self.name, self.volume, self.get_volume_percent(), self.muted
+ )
+ }
}