mirror of
https://github.com/Stremio/stremio-shell-ng.git
synced 2026-05-06 07:39:07 +00:00
Bump libmpv2 crate from 4.1.0 to 5.0.3
The 4.x -> 5.x release folded `EventContext` into `Mpv` and made `wait_event` take `&mut self`, so the previous design (a single `Arc<Mpv>` shared between the message and event threads, with the event thread constructing its own `EventContext` from `mpv.ctx`) no longer compiles. Migration: - Build the main `Mpv` (with `wid`, `title`, etc.) and use it from the message thread for commands and `set_property`. - `create_client(None)` a sub-client `Mpv`, owned by the event thread, which calls `disable_deprecated_events`/`observe_property`/`wait_event` on itself. Global events (`EndFile`, `Shutdown`) and property changes observed by this client land in its event queue. - Replace the old `MpvExt::wake_up` (which woke the main `Mpv`) with an `EventClientWakeup` holding the sub-client's `mpv_handle` pointer, so the message thread can interrupt the event thread's blocking `wait_event` after pushing a new observe request onto the channel. Also removed the `PropertyData::Node(_)` match arm in `communication.rs`: 5.0.0 dropped `mpv_node` support, so the variant no longer exists and the match is exhaustive without it. https://claude.ai/code/session_01CuGHFREBZFkf8tfaiRV4K6
This commit is contained in:
parent
e199d7f38c
commit
9b057a0030
4 changed files with 34 additions and 27 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
|
@ -880,9 +880,9 @@ checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
|||
|
||||
[[package]]
|
||||
name = "libmpv2"
|
||||
version = "4.1.0"
|
||||
version = "5.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e0c3802b4bb1a18adbf5659b078ce24cb8e16c79ff695557f4e10af2a44722a"
|
||||
checksum = "88dc8432d3de09ed6e343488d6b208467db6801fb41971a1f726fa2248302fe5"
|
||||
dependencies = [
|
||||
"libmpv2-sys",
|
||||
]
|
||||
|
|
@ -1598,7 +1598,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "stremio-shell-ng"
|
||||
version = "5.0.20"
|
||||
version = "5.0.21"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.4.2",
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ winapi = { version = "0.3.9", features = [
|
|||
] }
|
||||
webview2 = "0.1.4"
|
||||
webview2-sys = "0.1.1"
|
||||
libmpv2 = "4.1.0"
|
||||
libmpv2 = "5.0.3"
|
||||
libmpv2-sys = "4.0.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ impl PlayerProprChange {
|
|||
serde_json::Value::String(s.to_string())
|
||||
}
|
||||
}
|
||||
PropertyData::Node(_) => unimplemented!("`PropertyData::Node` is not supported"),
|
||||
}
|
||||
}
|
||||
pub fn from_name_value(name: String, value: PropertyData) -> Self {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use crate::stremio_app::ipc;
|
||||
use crate::stremio_app::RPCResponse;
|
||||
use flume::{Receiver, Sender};
|
||||
use libmpv2::{events::Event, events::EventContext, Format, Mpv, SetData};
|
||||
use libmpv2::{events::Event, Format, Mpv, SetData};
|
||||
use native_windows_gui::{self as nwg, PartialUi};
|
||||
use std::{
|
||||
ptr::NonNull,
|
||||
sync::Arc,
|
||||
thread::{self, JoinHandle},
|
||||
};
|
||||
|
|
@ -19,6 +20,18 @@ struct ObserveProperty {
|
|||
format: Format,
|
||||
}
|
||||
|
||||
// Wakes up the event thread blocked in `mpv_wait_event` on the sub-client.
|
||||
// `mpv_wakeup` is documented as safe to call from any thread.
|
||||
#[derive(Clone, Copy)]
|
||||
struct EventClientWakeup(NonNull<libmpv2_sys::mpv_handle>);
|
||||
unsafe impl Send for EventClientWakeup {}
|
||||
unsafe impl Sync for EventClientWakeup {}
|
||||
impl EventClientWakeup {
|
||||
fn wake_up(&self) {
|
||||
unsafe { libmpv2_sys::mpv_wakeup(self.0.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Player {
|
||||
pub channel: ipc::Channel,
|
||||
|
|
@ -43,21 +56,26 @@ impl PartialUi for Player {
|
|||
let (observe_property_sender, observe_property_receiver) = flume::unbounded();
|
||||
data.channel = ipc::Channel::new(Some((in_msg_sender, rpc_response_receiver)));
|
||||
|
||||
let mpv = create_shareable_mpv(window_handle);
|
||||
let mpv = Arc::new(create_mpv(window_handle));
|
||||
let mpv_event_client = mpv
|
||||
.create_client(None)
|
||||
.expect("cannot create MPV event client");
|
||||
let event_wakeup = EventClientWakeup(mpv_event_client.ctx);
|
||||
|
||||
let _event_thread = create_event_thread(
|
||||
Arc::clone(&mpv),
|
||||
mpv_event_client,
|
||||
observe_property_receiver,
|
||||
rpc_response_sender,
|
||||
);
|
||||
let _message_thread = create_message_thread(mpv, observe_property_sender, in_msg_receiver);
|
||||
let _message_thread =
|
||||
create_message_thread(mpv, event_wakeup, observe_property_sender, in_msg_receiver);
|
||||
// @TODO implement a mechanism to stop threads on `Player` drop if needed
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn create_shareable_mpv(window_handle: HWND) -> Arc<Mpv> {
|
||||
fn create_mpv(window_handle: HWND) -> Mpv {
|
||||
let mpv = Mpv::with_initializer(|initializer| {
|
||||
macro_rules! set_property {
|
||||
($name:literal, $value:expr) => {
|
||||
|
|
@ -79,17 +97,16 @@ fn create_shareable_mpv(window_handle: HWND) -> Arc<Mpv> {
|
|||
// set_property!("vo", "gpu-next,");
|
||||
Ok(())
|
||||
});
|
||||
Arc::new(mpv.expect("cannot build MPV"))
|
||||
mpv.expect("cannot build MPV")
|
||||
}
|
||||
|
||||
fn create_event_thread(
|
||||
mpv: Arc<Mpv>,
|
||||
mut mpv_event_client: Mpv,
|
||||
observe_property_receiver: Receiver<ObserveProperty>,
|
||||
rpc_response_sender: Sender<String>,
|
||||
) -> JoinHandle<()> {
|
||||
thread::spawn(move || {
|
||||
let mut event_context = EventContext::new(mpv.ctx);
|
||||
event_context
|
||||
mpv_event_client
|
||||
.disable_deprecated_events()
|
||||
.expect("failed to disable deprecated MPV events");
|
||||
|
||||
|
|
@ -97,13 +114,13 @@ fn create_event_thread(
|
|||
|
||||
loop {
|
||||
for ObserveProperty { name, format } in observe_property_receiver.drain() {
|
||||
event_context
|
||||
mpv_event_client
|
||||
.observe_property(&name, format, 0)
|
||||
.expect("failed to observer MPV property");
|
||||
}
|
||||
|
||||
// -1.0 means to block and wait for an event.
|
||||
let event = match event_context.wait_event(-1.) {
|
||||
let event = match mpv_event_client.wait_event(-1.) {
|
||||
Some(Ok(event)) => event,
|
||||
Some(Err(error)) => {
|
||||
eprintln!("Event errored: {error:?}");
|
||||
|
|
@ -141,6 +158,7 @@ fn create_event_thread(
|
|||
|
||||
fn create_message_thread(
|
||||
mpv: Arc<Mpv>,
|
||||
event_wakeup: EventClientWakeup,
|
||||
observe_property_sender: Sender<ObserveProperty>,
|
||||
in_msg_receiver: Receiver<String>,
|
||||
) -> JoinHandle<()> {
|
||||
|
|
@ -151,7 +169,7 @@ fn create_message_thread(
|
|||
observe_property_sender
|
||||
.send(ObserveProperty { name, format })
|
||||
.expect("cannot send ObserveProperty");
|
||||
mpv.wake_up();
|
||||
event_wakeup.wake_up();
|
||||
};
|
||||
|
||||
let send_command = |cmd: CmdVal| {
|
||||
|
|
@ -252,13 +270,3 @@ fn create_message_thread(
|
|||
})
|
||||
}
|
||||
|
||||
trait MpvExt {
|
||||
fn wake_up(&self);
|
||||
}
|
||||
|
||||
impl MpvExt for Mpv {
|
||||
// @TODO create a PR to the `libmpv` crate and then remove `libmpv-sys` from Cargo.toml?
|
||||
fn wake_up(&self) {
|
||||
unsafe { libmpv2_sys::mpv_wakeup(self.ctx.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue