mpris player metadata

This commit is contained in:
Erica Z 2024-11-19 21:07:05 +01:00
parent eab11095c8
commit 378eb0761d
2 changed files with 30 additions and 8 deletions

View file

@ -9,7 +9,7 @@ use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Value};
const MICROSECONDS: f64 = 1e6; // in a second const MICROSECONDS: f64 = 1e6; // in a second
#[derive(Default)] #[derive(Default)]
struct MetadataMap { pub struct MetadataMap {
// mpris // mpris
track_id: Option<OwnedObjectPath>, track_id: Option<OwnedObjectPath>,
length: Option<i64>, length: Option<i64>,
@ -37,7 +37,7 @@ struct MetadataMap {
} }
impl MetadataMap { impl MetadataMap {
fn from_playbin_song(song: Option<&Song>) -> Self { pub fn from_playbin_song(song: Option<&Song>) -> Self {
song.map(|song| MetadataMap { song.map(|song| MetadataMap {
// use a unique growing counter to identify tracks // use a unique growing counter to identify tracks
track_id: Some({ track_id: Some({
@ -115,7 +115,6 @@ impl MetadataMap {
} }
pub struct Player { pub struct Player {
metadata: MetadataMap,
window: SendWeakRef<Window>, window: SendWeakRef<Window>,
} }
@ -125,7 +124,6 @@ impl Player {
playbin: &Window, playbin: &Window,
) -> Result<InterfaceRef<Player>, zbus::Error> { ) -> Result<InterfaceRef<Player>, zbus::Error> {
let player = Self { let player = Self {
metadata: MetadataMap::from_playbin_song(None),
window: playbin.downgrade().into(), window: playbin.downgrade().into(),
}; };
@ -268,7 +266,8 @@ impl Player {
#[tracing::instrument(skip(self), parent = None, target = "audrey::mpris", level = Level::DEBUG, ret)] #[tracing::instrument(skip(self), parent = None, target = "audrey::mpris", level = Level::DEBUG, ret)]
fn set_position(&self, track_id: ObjectPath<'_>, position: i64) -> zbus::fdo::Result<()> { fn set_position(&self, track_id: ObjectPath<'_>, position: i64) -> zbus::fdo::Result<()> {
if Some(track_id) == self.metadata.track_id.as_ref().map(|x| x.as_ref()) { let metadata = self.metadata();
if Some(&track_id.into()) == metadata.get("track_id") {
self.window().set_time_pos(position as f64 / MICROSECONDS); self.window().set_time_pos(position as f64 / MICROSECONDS);
} }
Ok(()) Ok(())
@ -329,7 +328,8 @@ impl Player {
#[zbus(property)] #[zbus(property)]
fn metadata(&self) -> HashMap<&'static str, OwnedValue> { fn metadata(&self) -> HashMap<&'static str, OwnedValue> {
self.metadata.as_hash_map() // TODO: no need to MetadataMap wrapper anymore
MetadataMap::from_playbin_song(self.window().song().as_ref()).as_hash_map()
} }
#[zbus(property)] #[zbus(property)]

View file

@ -416,7 +416,10 @@ mod imp {
if let Some(iface_ref) = self.mpris_player() { if let Some(iface_ref) = self.mpris_player() {
glib::spawn_future_local(async move { glib::spawn_future_local(async move {
let iface = iface_ref.get().await; let iface = iface_ref.get().await;
match iface.playback_status_changed(iface_ref.signal_emitter()).await { match iface
.playback_status_changed(iface_ref.signal_emitter())
.await
{
Ok(()) => {} Ok(()) => {}
Err(err) => event!( Err(err) => event!(
Level::ERROR, Level::ERROR,
@ -427,6 +430,21 @@ mod imp {
} }
} }
fn mpris_player_metadata_changed(&self) {
if let Some(iface_ref) = self.mpris_player() {
glib::spawn_future_local(async move {
let iface = iface_ref.get().await;
match iface.metadata_changed(iface_ref.signal_emitter()).await {
Ok(()) => {}
Err(err) => event!(
Level::ERROR,
"could not notify new metadata through mpris interface: {err}"
),
}
});
}
}
fn volume(&self) -> i64 { fn volume(&self) -> i64 {
self.mpv.get_property("volume").unwrap() self.mpv.get_property("volume").unwrap()
} }
@ -663,6 +681,7 @@ mod imp {
self.obj().set_playing_cover_art(None::<gdk::Texture>); self.obj().set_playing_cover_art(None::<gdk::Texture>);
self.obj().set_background(None::<gdk::Texture>); self.obj().set_background(None::<gdk::Texture>);
self.mpris_player_metadata_changed();
self.mpris_player_playback_status_changed(); self.mpris_player_playback_status_changed();
} }
@ -686,11 +705,14 @@ mod imp {
self.obj().notify("song"); self.obj().notify("song");
self.buffering_start(); self.buffering_start();
let duration = self.obj().song().unwrap().duration() as f64; let song = self.obj().song().unwrap();
let duration = song.duration() as f64;
self.duration.set(duration); self.duration.set(duration);
event!(target: "audrey::playback", Level::DEBUG, "duration is now {duration} (from subsonic)"); event!(target: "audrey::playback", Level::DEBUG, "duration is now {duration} (from subsonic)");
self.obj().notify("duration"); self.obj().notify("duration");
self.mpris_player_metadata_changed();
self.mpris_player_playback_status_changed(); self.mpris_player_playback_status_changed();
let window = self.obj().clone(); let window = self.obj().clone();