Compare commits

..

No commits in common. "20aaacd40e70b06327a6f36e2403a98d9d51b5dd" and "4c90d0f10ed1f43d2ec6943cab5c4d0018958d0c" have entirely different histories.

4 changed files with 25 additions and 97 deletions

View file

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

View file

@ -63,7 +63,6 @@ pub enum PropertyEventValue {
Int64(i64),
Double(f64),
String(String),
Flag(bool),
}
#[derive(Clone, Debug)]

View file

@ -5,7 +5,7 @@ use super::event::{
use super::{ffi, Error, Event as MpvEvent, GetProperty, SetProperty};
use event_listener::{Event, EventListener, IntoNotification};
use std::cell::{RefCell, RefMut};
use std::ffi::{c_char, c_int, c_void, CStr, CString};
use std::ffi::{c_char, c_void, CStr, CString};
use std::fmt;
use std::pin::Pin;
use std::ptr::NonNull;
@ -177,18 +177,6 @@ impl Handle {
})
}
pub fn observe_property_flag(&self, reply_userdata: u64, name: &str) -> Result<(), Error> {
let name = CString::new(name).expect("null bytes in property name");
Error::from_return_code(unsafe {
ffi::mpv_observe_property(
self.inner.as_ptr(),
reply_userdata,
name.as_ptr(),
ffi::mpv_format_MPV_FORMAT_FLAG,
)
})
}
pub fn unobserve_property(&self, registered_reply_userdata: u64) -> Result<u32, Error> {
let rc =
unsafe { ffi::mpv_unobserve_property(self.inner.as_ptr(), registered_reply_userdata) };
@ -311,13 +299,6 @@ impl Handle {
String::from_utf8_lossy(value.to_bytes()).into_owned(),
))
}
ffi::mpv_format_MPV_FORMAT_FLAG => Some(PropertyEventValue::Flag(unsafe {
match *(data.data as *mut c_int) {
0 => false,
1 => true,
other => unreachable!("bad mpv flag value {other}"),
}
})),
_ => todo!(),
},
}))

View file

@ -99,7 +99,7 @@ mod imp {
mpv.observe_property_string(0, "path").unwrap();
mpv.observe_property_int64(3, "playlist-pos").unwrap();
mpv.observe_property_flag(4, "idle-active").unwrap();
mpv.observe_property(4, "idle-active").unwrap();
mpv.observe_property(6, "playlist-count").unwrap();
mpv.observe_property_double(7, "duration").unwrap();
@ -407,44 +407,6 @@ mod imp {
self.setup.present(Some(self.obj().as_ref()));
}
fn mpris_player(&self) -> Option<InterfaceRef<mpris::Player>> {
let borrowed = self.mpris_player.borrow();
borrowed.as_ref().cloned()
}
fn mpris_player_playback_status_changed(&self) {
if let Some(iface_ref) = self.mpris_player() {
glib::spawn_future_local(async move {
let iface = iface_ref.get().await;
match iface
.playback_status_changed(iface_ref.signal_emitter())
.await
{
Ok(()) => {}
Err(err) => event!(
Level::ERROR,
"could not notify new playback status through mpris interface: {err}"
),
}
});
}
}
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 {
self.mpv.get_property("volume").unwrap()
}
@ -452,7 +414,11 @@ mod imp {
fn set_volume(&self, volume: i64) {
self.mpv.set_property("volume", volume).unwrap();
if let Some(iface_ref) = self.mpris_player() {
let iface_borrowed = self.mpris_player.borrow();
let iface_ref = match iface_borrowed.as_ref() {
None => return, // zbus not set up yet
Some(iface_ref) => iface_ref.clone(),
};
glib::spawn_future_local(async move {
let iface = iface_ref.get().await;
match iface.volume_changed(iface_ref.signal_emitter()).await {
@ -464,7 +430,6 @@ mod imp {
}
});
}
}
fn mute(&self) -> bool {
self.mpv.get_property("mute").unwrap()
@ -480,10 +445,6 @@ mod imp {
fn set_pause(&self, pause: bool) {
self.mpv.set_property("pause", pause).unwrap();
if !self.idle_active() {
self.mpris_player_playback_status_changed();
}
}
fn time_pos(&self) -> f64 {
@ -583,13 +544,8 @@ mod imp {
4 => {
assert_eq!(event.name, "idle-active");
let value = match event.value {
Some(PropertyEventValue::Flag(b)) => b,
_ => unreachable!(),
};
event!(Level::TRACE, "idle-active is now {value}");
self.obj().notify("idle-active");
if value {
if self.obj().idle_active() {
self.on_idle_active();
}
}
@ -685,9 +641,6 @@ mod imp {
self.obj().set_playing_cover_art(None::<gdk::Texture>);
self.obj().set_background(None::<gdk::Texture>);
self.mpris_player_metadata_changed();
self.mpris_player_playback_status_changed();
}
fn on_start_file(&self) {
@ -710,16 +663,11 @@ mod imp {
self.obj().notify("song");
self.buffering_start();
let song = self.obj().song().unwrap();
let duration = song.duration() as f64;
let duration = self.obj().song().unwrap().duration() as f64;
self.duration.set(duration);
event!(target: "audrey::playback", Level::DEBUG, "duration is now {duration} (from subsonic)");
self.obj().notify("duration");
self.mpris_player_metadata_changed();
self.mpris_player_playback_status_changed();
let window = self.obj().clone();
let song_id = window.song().unwrap().id();
if let Some(handle) = self