also for duration
This commit is contained in:
parent
5dc1ed221b
commit
939b08887e
3 changed files with 43 additions and 31 deletions
|
@ -61,6 +61,7 @@ pub struct PropertyEvent {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum PropertyEventValue {
|
pub enum PropertyEventValue {
|
||||||
Int64(i64),
|
Int64(i64),
|
||||||
|
Double(f64),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -141,7 +141,7 @@ impl Handle {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn observe_property_i64(&self, reply_userdata: u64, name: &str) -> Result<(), Error> {
|
pub fn observe_property_int64(&self, reply_userdata: u64, name: &str) -> Result<(), Error> {
|
||||||
let name = CString::new(name).expect("null bytes in property name");
|
let name = CString::new(name).expect("null bytes in property name");
|
||||||
Error::from_return_code(unsafe {
|
Error::from_return_code(unsafe {
|
||||||
ffi::mpv_observe_property(
|
ffi::mpv_observe_property(
|
||||||
|
@ -153,6 +153,18 @@ impl Handle {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn observe_property_double(&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_DOUBLE,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
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) };
|
||||||
|
@ -264,6 +276,11 @@ impl Handle {
|
||||||
*(data.data as *mut i64)
|
*(data.data as *mut i64)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
ffi::mpv_format_MPV_FORMAT_DOUBLE => {
|
||||||
|
Some(PropertyEventValue::Double(unsafe {
|
||||||
|
*(data.data as *mut f64)
|
||||||
|
}))
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -65,8 +65,8 @@ mod imp {
|
||||||
playlist_pos: Cell<i64>,
|
playlist_pos: Cell<i64>,
|
||||||
#[property(type = f64, get = Self::time_pos)]
|
#[property(type = f64, get = Self::time_pos)]
|
||||||
_time_pos: (),
|
_time_pos: (),
|
||||||
#[property(type = f64, get = Self::duration)]
|
#[property(get)]
|
||||||
_duration: (), // as reported by mpv, compare with song.duration
|
duration: Cell<f64>, // as reported by mpv, compare with song.duration
|
||||||
#[property(type = bool, get = Self::idle_active)]
|
#[property(type = bool, get = Self::idle_active)]
|
||||||
_idle_active: (),
|
_idle_active: (),
|
||||||
#[property(type = i64, get = Self::playlist_count)]
|
#[property(type = i64, get = Self::playlist_count)]
|
||||||
|
@ -97,10 +97,10 @@ 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_i64(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();
|
||||||
mpv.observe_property(7, "duration").unwrap();
|
mpv.observe_property_double(7, "duration").unwrap();
|
||||||
|
|
||||||
// "Useful to drain property changes before a new file is loaded."
|
// "Useful to drain property changes before a new file is loaded."
|
||||||
mpv.add_hook(0, "on_before_start_file", 0).unwrap();
|
mpv.add_hook(0, "on_before_start_file", 0).unwrap();
|
||||||
|
@ -128,7 +128,7 @@ mod imp {
|
||||||
_pause: (),
|
_pause: (),
|
||||||
playlist_pos: Cell::new(-1),
|
playlist_pos: Cell::new(-1),
|
||||||
_time_pos: (),
|
_time_pos: (),
|
||||||
_duration: (),
|
duration: Cell::new(0.0),
|
||||||
_idle_active: (),
|
_idle_active: (),
|
||||||
_playlist_count: (),
|
_playlist_count: (),
|
||||||
|
|
||||||
|
@ -268,11 +268,6 @@ mod imp {
|
||||||
|
|
||||||
// only send property change notifications after the event queue is drained
|
// only send property change notifications after the event queue is drained
|
||||||
let freeze_notify = window.freeze_notify();
|
let freeze_notify = window.freeze_notify();
|
||||||
event!(
|
|
||||||
Level::TRACE,
|
|
||||||
"before event loop, state is {:?}",
|
|
||||||
window.imp().state.get()
|
|
||||||
);
|
|
||||||
|
|
||||||
let listener = loop {
|
let listener = loop {
|
||||||
let listener = window.imp().mpv.wakeup_listener();
|
let listener = window.imp().mpv.wakeup_listener();
|
||||||
|
@ -322,11 +317,6 @@ mod imp {
|
||||||
|
|
||||||
// send property change notifications now
|
// send property change notifications now
|
||||||
drop(freeze_notify);
|
drop(freeze_notify);
|
||||||
event!(
|
|
||||||
Level::TRACE,
|
|
||||||
"after event loop, state is {:?}",
|
|
||||||
window.imp().state.get()
|
|
||||||
);
|
|
||||||
|
|
||||||
drop(window);
|
drop(window);
|
||||||
listener.await;
|
listener.await;
|
||||||
|
@ -482,21 +472,6 @@ mod imp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn duration(&self) -> f64 {
|
|
||||||
match self.state.get() {
|
|
||||||
State::Idle => 0.0,
|
|
||||||
|
|
||||||
State::FileLoading | State::FileEnded => self
|
|
||||||
.song()
|
|
||||||
.map(|song| song.duration() as f64)
|
|
||||||
.unwrap_or(0.0),
|
|
||||||
|
|
||||||
State::FileLoaded | State::Active | State::Seeking => {
|
|
||||||
self.mpv.get_property::<f64>("duration").unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn idle_active(&self) -> bool {
|
fn idle_active(&self) -> bool {
|
||||||
self.mpv.get_property("idle-active").unwrap()
|
self.mpv.get_property("idle-active").unwrap()
|
||||||
}
|
}
|
||||||
|
@ -581,6 +556,16 @@ mod imp {
|
||||||
|
|
||||||
7 => {
|
7 => {
|
||||||
assert_eq!(event.name, "duration");
|
assert_eq!(event.name, "duration");
|
||||||
|
let value = match event.value {
|
||||||
|
None => return, // don't change, could be one of two things
|
||||||
|
// 1. we are switching tracks (duration is set in
|
||||||
|
// on_start_file)
|
||||||
|
// 2. we are done (duration is set in on_idle_active)
|
||||||
|
Some(PropertyEventValue::Double(f)) => f,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
self.duration.set(value);
|
||||||
|
event!(Level::TRACE, "duration is now {value} (from mpv)");
|
||||||
self.obj().notify("duration");
|
self.obj().notify("duration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,6 +618,10 @@ mod imp {
|
||||||
other => panic!("invalid state transition: IdleActive from {other:?}"),
|
other => panic!("invalid state transition: IdleActive from {other:?}"),
|
||||||
}
|
}
|
||||||
self.state.set(State::Idle);
|
self.state.set(State::Idle);
|
||||||
|
|
||||||
|
self.duration.set(0.0);
|
||||||
|
event!(Level::DEBUG, "duration is now 0 (idle active)");
|
||||||
|
self.obj().notify("duration");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_start_file(&self) {
|
fn on_start_file(&self) {
|
||||||
|
@ -651,6 +640,11 @@ 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;
|
||||||
|
self.duration.set(duration);
|
||||||
|
event!(Level::TRACE, "duration is now {duration} (from subsonic)");
|
||||||
|
self.obj().notify("duration");
|
||||||
|
|
||||||
let window = self.obj().clone();
|
let window = self.obj().clone();
|
||||||
let song_id = window.song().unwrap().id();
|
let song_id = window.song().unwrap().id();
|
||||||
if let Some(handle) = self
|
if let Some(handle) = self
|
||||||
|
|
Loading…
Reference in a new issue