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; mod handle;
pub use handle::Handle; pub use handle::Handle;
mod event; pub mod event;
pub use event::{EndFileEvent, EndFileReason, Event, LogMessageEvent, StartFileEvent}; pub use event::Event;

View file

@ -1,6 +1,7 @@
use super::Error; use super::Error;
use std::borrow::Cow;
#[derive(Copy, Clone, Debug)] #[derive(Clone, Debug)]
pub enum Event<'a> { pub enum Event<'a> {
Shutdown, Shutdown,
LogMessage(LogMessageEvent<'a>), LogMessage(LogMessageEvent<'a>),
@ -15,18 +16,18 @@ pub enum Event<'a> {
AudioReconfig, AudioReconfig,
//Seek, //Seek,
PlaybackRestart, PlaybackRestart,
//PropertyChange, PropertyChange(PropertyEvent<'a>),
//QueueOverflow, //QueueOverflow,
//Hook, //Hook,
Unknown(u32), Unknown(u32),
} }
#[derive(Copy, Clone, Debug)] #[derive(Clone, Debug)]
pub struct StartFileEvent { pub struct StartFileEvent {
pub playlist_entry_id: i64, pub playlist_entry_id: i64,
} }
#[derive(Copy, Clone, Debug)] #[derive(Clone, Debug)]
pub enum EndFileReason { pub enum EndFileReason {
Eof, Eof,
Stop, Stop,
@ -35,7 +36,7 @@ pub enum EndFileReason {
Unknown(u32), Unknown(u32),
} }
#[derive(Copy, Clone, Debug)] #[derive(Clone, Debug)]
pub struct EndFileEvent { pub struct EndFileEvent {
pub reason: Result<EndFileReason, Error>, pub reason: Result<EndFileReason, Error>,
pub playlist_entry_id: i64, pub playlist_entry_id: i64,
@ -43,10 +44,27 @@ pub struct EndFileEvent {
pub playlist_insert_num_entries: i32, pub playlist_insert_num_entries: i32,
} }
#[derive(Copy, Clone, Debug)] #[derive(Clone, Debug)]
pub struct LogMessageEvent<'a> { pub struct LogMessageEvent<'a> {
pub prefix: &'a str, pub prefix: &'a str,
pub level: &'a str, pub level: &'a str,
pub text: &'a str, pub text: &'a str,
//log_level: i32, //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::{ use super::{event, ffi, Error, Event as MpvEvent, SetProperty};
ffi, EndFileEvent, EndFileReason, Error, Event as MpvEvent, LogMessageEvent, SetProperty, use event::{
StartFileEvent, EndFileEvent, EndFileReason, LogMessageEvent, PropertyEvent, PropertyEventValue, StartFileEvent,
}; };
use event_listener::{Event, EventListener, IntoNotification}; use event_listener::{Event, EventListener, IntoNotification};
use std::ffi::{c_char, c_void, CStr, CString}; 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) }) 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 // should take listener before we drain the event queue, so we don't miss any notifications
pub fn wakeup_listener(&self) -> EventListener { pub fn wakeup_listener(&self) -> EventListener {
self.wakeup.listen() 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)), 11 => Some(MpvEvent::Unknown(event.event_id)),
_ => todo!("event {}", 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("video", false).unwrap();
mpv.set_property("prefetch-playlist", true).unwrap(); mpv.set_property("prefetch-playlist", true).unwrap();
mpv.set_property("gapless-audio", 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"]) mpv.command(["loadfile", "https://www.youtube.com/watch?v=19y8YTbvri8"])
.unwrap(); .unwrap();