observed properties

This commit is contained in:
Erica Z 2024-11-03 13:09:44 +01:00
parent bbd635c7c0
commit 58ef3e956c
4 changed files with 63 additions and 12 deletions

View file

@ -9,5 +9,5 @@ pub use format::SetProperty;
mod handle;
pub use handle::Handle;
mod event;
pub use event::{EndFileEvent, EndFileReason, Event, LogMessageEvent, StartFileEvent};
pub mod event;
pub use event::Event;

View file

@ -1,6 +1,7 @@
use super::Error;
use std::borrow::Cow;
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub enum Event<'a> {
Shutdown,
LogMessage(LogMessageEvent<'a>),
@ -15,18 +16,18 @@ pub enum Event<'a> {
AudioReconfig,
//Seek,
PlaybackRestart,
//PropertyChange,
PropertyChange(PropertyEvent<'a>),
//QueueOverflow,
//Hook,
Unknown(u32),
}
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct StartFileEvent {
pub playlist_entry_id: i64,
}
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub enum EndFileReason {
Eof,
Stop,
@ -35,7 +36,7 @@ pub enum EndFileReason {
Unknown(u32),
}
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct EndFileEvent {
pub reason: Result<EndFileReason, Error>,
pub playlist_entry_id: i64,
@ -43,10 +44,27 @@ pub struct EndFileEvent {
pub playlist_insert_num_entries: i32,
}
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct LogMessageEvent<'a> {
pub prefix: &'a str,
pub level: &'a str,
pub text: &'a str,
//log_level: i32,
}
#[derive(Clone, Debug)]
pub struct PropertyEvent<'a> {
pub reply_userdata: u64,
pub name: &'a str,
pub value: PropertyEventValue<'a>,
}
#[derive(Clone, Debug)]
pub enum PropertyEventValue<'a> {
None,
String(Cow<'a, str>),
OsdString(&'a str),
Flag(bool),
Int64(i64),
Double(f64),
}

View file

@ -1,6 +1,6 @@
use super::{
ffi, EndFileEvent, EndFileReason, Error, Event as MpvEvent, LogMessageEvent, SetProperty,
StartFileEvent,
use super::{event, ffi, Error, Event as MpvEvent, SetProperty};
use event::{
EndFileEvent, EndFileReason, LogMessageEvent, PropertyEvent, PropertyEventValue, StartFileEvent,
};
use event_listener::{Event, EventListener, IntoNotification};
use std::ffi::{c_char, c_void, CStr, CString};
@ -99,6 +99,24 @@ impl Handle {
Error::from_return_code(unsafe { ffi::mpv_command(self.inner.as_ptr(), args) })
}
pub fn observe_property_i64(&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_INT64,
)
})
}
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) };
Error::from_return_code(rc).map(|()| rc as u32)
}
// should take listener before we drain the event queue, so we don't miss any notifications
pub fn wakeup_listener(&self) -> EventListener {
self.wakeup.listen()
@ -156,6 +174,21 @@ impl Handle {
}))
}
ffi::mpv_event_id_MPV_EVENT_PROPERTY_CHANGE => {
let data = unsafe { &*(event.data as *mut ffi::mpv_event_property) };
Some(MpvEvent::PropertyChange(PropertyEvent {
reply_userdata: event.reply_userdata,
name: unsafe { CStr::from_ptr(data.name) }.to_str().unwrap(),
value: match data.format {
ffi::mpv_format_MPV_FORMAT_NONE => PropertyEventValue::None,
ffi::mpv_format_MPV_FORMAT_INT64 => {
PropertyEventValue::Int64(*unsafe { &*(data.data as *mut i64) })
}
_ => todo!("{:?}", data.format),
},
}))
}
11 => Some(MpvEvent::Unknown(event.event_id)),
_ => todo!("event {}", event.event_id),

View file

@ -59,7 +59,7 @@ mod imp {
mpv.set_property("video", false).unwrap();
mpv.set_property("prefetch-playlist", true).unwrap();
mpv.set_property("gapless-audio", true).unwrap();
// TODO: observe properties
mpv.observe_property_i64(0, "duration").unwrap();
mpv.command(["loadfile", "https://www.youtube.com/watch?v=19y8YTbvri8"])
.unwrap();