This commit is contained in:
Erica Z 2024-11-13 20:33:25 +01:00
parent 939b08887e
commit 29774b136b
3 changed files with 48 additions and 19 deletions

View file

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

View file

@ -165,6 +165,18 @@ impl Handle {
}) })
} }
pub fn observe_property_string(&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_STRING,
)
})
}
pub fn unobserve_property(&self, registered_reply_userdata: u64) -> Result<u32, Error> { pub fn unobserve_property(&self, registered_reply_userdata: u64) -> Result<u32, Error> {
let rc = let rc =
unsafe { ffi::mpv_unobserve_property(self.inner.as_ptr(), registered_reply_userdata) }; unsafe { ffi::mpv_unobserve_property(self.inner.as_ptr(), registered_reply_userdata) };
@ -281,6 +293,12 @@ impl Handle {
*(data.data as *mut f64) *(data.data as *mut f64)
})) }))
} }
ffi::mpv_format_MPV_FORMAT_STRING => {
let value = unsafe { CStr::from_ptr(*(data.data as *mut *mut c_char)) };
Some(PropertyEventValue::String(
String::from_utf8_lossy(value.to_bytes()).into_owned(),
))
}
_ => todo!(), _ => todo!(),
}, },
})) }))

View file

@ -97,6 +97,7 @@ mod imp {
mpv.set_property("vid", false).unwrap(); mpv.set_property("vid", false).unwrap();
mpv.set_property("prefetch-playlist", true).unwrap(); mpv.set_property("prefetch-playlist", true).unwrap();
mpv.observe_property_string(0, "path").unwrap();
mpv.observe_property_int64(3, "playlist-pos").unwrap(); mpv.observe_property_int64(3, "playlist-pos").unwrap();
mpv.observe_property(4, "idle-active").unwrap(); mpv.observe_property(4, "idle-active").unwrap();
mpv.observe_property(6, "playlist-count").unwrap(); mpv.observe_property(6, "playlist-count").unwrap();
@ -473,12 +474,15 @@ mod imp {
} }
fn idle_active(&self) -> bool { fn idle_active(&self) -> bool {
self.mpv.get_property("idle-active").unwrap() match self.state.get() {
State::Idle => true,
_ => false,
}
} }
fn playlist_count(&self) -> i64 { fn playlist_count(&self) -> i64 {
let count = self.mpv.get_property::<i64>("playlist-count").unwrap(); let count = self.mpv.get_property::<i64>("playlist-count").unwrap();
assert_eq!(count as u32, self.playlist_model.n_items()); assert_eq!(count as u32, self.playlist_model.n_items()); // sanity check
count count
} }
@ -530,6 +534,18 @@ mod imp {
use crate::mpv::event::PropertyEventValue; use crate::mpv::event::PropertyEventValue;
match event.reply_userdata { match event.reply_userdata {
0 => {
/* FIXME: can happen before playlist-pos is updated
assert_eq!(event.name, "path");
match event.value {
None => {}
Some(PropertyEventValue::String(s)) => {
// sanity check
assert_eq!(self.obj().song().unwrap().stream_url(), s);
}
_ => unreachable!(),
}*/
}
3 => { 3 => {
assert_eq!(event.name, "playlist-pos"); assert_eq!(event.name, "playlist-pos");
let value = match event.value { let value = match event.value {
@ -567,6 +583,17 @@ mod imp {
self.duration.set(value); self.duration.set(value);
event!(Level::TRACE, "duration is now {value} (from mpv)"); event!(Level::TRACE, "duration is now {value} (from mpv)");
self.obj().notify("duration"); self.obj().notify("duration");
{
let left = value as i64;
let right = self.song().unwrap().duration();
if left != right {
event!(
Level::WARN,
"mpv duration {left:?} doesn not match subsonic duration {right:?}"
);
}
}
} }
_ => unreachable!(), _ => unreachable!(),
@ -707,23 +734,6 @@ mod imp {
self.state.set(State::FileLoaded); self.state.set(State::FileLoaded);
event!(Level::INFO, "FileLoaded"); event!(Level::INFO, "FileLoaded");
// sanity check
// i think "path" is only available after this event is dispatched
assert_eq!(
self.mpv.get_property::<String>("path").unwrap(),
self.obj().song().unwrap().stream_url()
);
// same with "duration"
{
let left = self.mpv.get_property::<f64>("duration").unwrap() as i64;
let right = self.song().unwrap().duration();
if left != right {
event!(
Level::WARN,
"mpv duration {left:?} doesn not match subsonic duration {right:?}"
);
}
}
} }
fn on_seek(&self) { fn on_seek(&self) {