mirror of
https://github.com/Stremio/stremio-shell-ng.git
synced 2026-01-11 22:40:32 +00:00
Use libmpv-rs instead of mpv-rs
This commit is contained in:
parent
4d05ec1a5d
commit
98a079db82
5 changed files with 174 additions and 284 deletions
178
Cargo.lock
generated
178
Cargo.lock
generated
|
|
@ -107,6 +107,16 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embed-resource"
|
||||
version = "1.6.3"
|
||||
|
|
@ -118,21 +128,6 @@ dependencies = [
|
|||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum_primitive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
|
||||
dependencies = [
|
||||
"num-traits 0.1.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
|
|
@ -185,14 +180,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
name = "libmpv"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
checksum = "61a58e2d19b34775e81e0fdca194b3b8ee8de973b092e7582b416343979e22e7"
|
||||
dependencies = [
|
||||
"log 0.4.14",
|
||||
"libmpv-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libmpv-sys"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0df938d3145cd8f134572721a27afa3a51f9bc1c26ae30a1d5077162f96d074b"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
|
|
@ -208,17 +209,6 @@ version = "2.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "mpv"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e57fd944655bbef6aaab8a154b0f78ed55aaaaf211edf956330c56309236f82"
|
||||
dependencies = [
|
||||
"enum_primitive",
|
||||
"log 0.3.9",
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "muldiv"
|
||||
version = "0.2.1"
|
||||
|
|
@ -253,84 +243,6 @@ dependencies = [
|
|||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits 0.2.14",
|
||||
"rand",
|
||||
"rustc-serialize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656"
|
||||
dependencies = [
|
||||
"num-traits 0.2.14",
|
||||
"rustc-serialize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits 0.2.14",
|
||||
"rustc-serialize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
dependencies = [
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
|
|
@ -394,7 +306,7 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
|
||||
dependencies = [
|
||||
"num-traits 0.2.14",
|
||||
"num-traits",
|
||||
"plotters-backend",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
|
|
@ -457,43 +369,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
dependencies = [
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.3.1",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
|
|
@ -511,12 +386,6 @@ version = "0.6.25"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
|
|
@ -568,8 +437,9 @@ name = "stremio-shell-ng"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossbeam-utils",
|
||||
"embed-resource",
|
||||
"mpv",
|
||||
"libmpv",
|
||||
"native-windows-derive",
|
||||
"native-windows-gui",
|
||||
"once_cell",
|
||||
|
|
@ -772,7 +642,7 @@ checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
|||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log 0.4.14",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
|
|
|
|||
17
Cargo.toml
17
Cargo.toml
|
|
@ -5,14 +5,22 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
once_cell = "1.3.1"
|
||||
native-windows-gui = { version = "1.0.4", features = ["high-dpi", "notice", "tray-notification", "menu"] }
|
||||
native-windows-gui = { version = "1.0.4", features = [
|
||||
"high-dpi",
|
||||
"notice",
|
||||
"tray-notification",
|
||||
"menu",
|
||||
] }
|
||||
native-windows-derive = "1.0.3"
|
||||
winapi = { version = "0.3.9", features = [
|
||||
"libloaderapi", "handleapi", "wincon", "winuser"
|
||||
"libloaderapi",
|
||||
"handleapi",
|
||||
"wincon",
|
||||
"winuser",
|
||||
] }
|
||||
webview2 = "0.1.0"
|
||||
webview2-sys = "0.1.0-beta.1"
|
||||
mpv = "0.2.3"
|
||||
libmpv = { version = "2.0.1", features = [] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
structopt = "0.3"
|
||||
|
|
@ -21,8 +29,9 @@ urlencoding = "2.1.0"
|
|||
bitflags = "1.2.1"
|
||||
win32job = "1"
|
||||
parse-display = "0.5.1"
|
||||
crossbeam-utils = "0.8.5"
|
||||
|
||||
[build-dependencies]
|
||||
embed-resource = "1.3"
|
||||
[dev-dependencies]
|
||||
serde_test = "1.0.*"
|
||||
serde_test = "1.0.*"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use core::convert::TryFrom;
|
||||
use libmpv::events::PropertyData;
|
||||
use parse_display::{Display, FromStr};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
|
@ -12,26 +13,27 @@ pub struct PlayerProprChange {
|
|||
data: serde_json::Value,
|
||||
}
|
||||
impl PlayerProprChange {
|
||||
fn value_from_format(data: mpv::Format, as_json: bool) -> serde_json::Value {
|
||||
fn value_from_format(data: PropertyData, as_json: bool) -> serde_json::Value {
|
||||
match data {
|
||||
mpv::Format::Flag(d) => serde_json::Value::Bool(d),
|
||||
mpv::Format::Int(d) => serde_json::Value::Number(
|
||||
PropertyData::Flag(d) => serde_json::Value::Bool(d),
|
||||
PropertyData::Int64(d) => serde_json::Value::Number(
|
||||
serde_json::Number::from_f64(d as f64).expect("MPV returned invalid number"),
|
||||
),
|
||||
mpv::Format::Double(d) => serde_json::Value::Number(
|
||||
PropertyData::Double(d) => serde_json::Value::Number(
|
||||
serde_json::Number::from_f64(d).expect("MPV returned invalid number"),
|
||||
),
|
||||
mpv::Format::OsdStr(s) => serde_json::Value::String(s.to_string()),
|
||||
mpv::Format::Str(s) => {
|
||||
PropertyData::OsdStr(s) => serde_json::Value::String(s.to_string()),
|
||||
PropertyData::Str(s) => {
|
||||
if as_json {
|
||||
serde_json::from_str(s).expect("MPV returned invalid JSON data")
|
||||
} else {
|
||||
serde_json::Value::String(s.to_string())
|
||||
}
|
||||
}
|
||||
_ => serde_json::Value::Null,
|
||||
}
|
||||
}
|
||||
pub fn from_name_value(name: String, value: mpv::Format) -> Self {
|
||||
pub fn from_name_value(name: String, value: PropertyData) -> Self {
|
||||
let is_json = JSON_RESPONSES.contains(&name.as_str());
|
||||
Self {
|
||||
name,
|
||||
|
|
@ -44,14 +46,15 @@ pub struct PlayerEnded {
|
|||
reason: String,
|
||||
}
|
||||
impl PlayerEnded {
|
||||
fn string_from_end_reason(data: mpv::EndFileReason) -> String {
|
||||
fn string_from_end_reason(data: u32) -> String {
|
||||
// defined here https://github.com/mpv-player/mpv/blob/master/libmpv/client.h#L1585
|
||||
match data {
|
||||
mpv::EndFileReason::MPV_END_FILE_REASON_ERROR => "error".to_string(),
|
||||
mpv::EndFileReason::MPV_END_FILE_REASON_QUIT => "quit".to_string(),
|
||||
4 => "error".to_string(),
|
||||
3 => "quit".to_string(),
|
||||
_ => "other".to_string(),
|
||||
}
|
||||
}
|
||||
pub fn from_end_reason(data: mpv::EndFileReason) -> Self {
|
||||
pub fn from_end_reason(data: u32) -> Self {
|
||||
Self {
|
||||
reason: Self::string_from_end_reason(data),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use crate::stremio_app::stremio_player::communication::{
|
|||
};
|
||||
|
||||
use serde_test::{assert_tokens, Token};
|
||||
use libmpv::events::PropertyData;
|
||||
|
||||
#[test]
|
||||
fn propr_change_tokens() {
|
||||
|
|
@ -20,7 +21,7 @@ fn propr_change_tokens() {
|
|||
Token::StructEnd,
|
||||
];
|
||||
|
||||
fn tokens_by_type(tokens: &[Token; 6], name: &'static str, val: mpv::Format, token: Token) {
|
||||
fn tokens_by_type(tokens: &[Token; 6], name: &'static str, val: PropertyData, token: Token) {
|
||||
let mut typed_tokens = tokens.clone();
|
||||
typed_tokens[2] = Token::Str(name);
|
||||
typed_tokens[4] = token;
|
||||
|
|
@ -29,29 +30,29 @@ fn propr_change_tokens() {
|
|||
&typed_tokens,
|
||||
);
|
||||
}
|
||||
tokens_by_type(&tokens, prop, mpv::Format::Flag(true), Token::Bool(true));
|
||||
tokens_by_type(&tokens, prop, mpv::Format::Int(1), Token::F64(1.0));
|
||||
tokens_by_type(&tokens, prop, mpv::Format::Double(1.0), Token::F64(1.0));
|
||||
tokens_by_type(&tokens, prop, mpv::Format::OsdStr("ok"), Token::Str("ok"));
|
||||
tokens_by_type(&tokens, prop, mpv::Format::Str("ok"), Token::Str("ok"));
|
||||
tokens_by_type(&tokens, prop, PropertyData::Flag(true), Token::Bool(true));
|
||||
tokens_by_type(&tokens, prop, PropertyData::Int64(1), Token::F64(1.0));
|
||||
tokens_by_type(&tokens, prop, PropertyData::Double(1.0), Token::F64(1.0));
|
||||
tokens_by_type(&tokens, prop, PropertyData::OsdStr("ok"), Token::Str("ok"));
|
||||
tokens_by_type(&tokens, prop, PropertyData::Str("ok"), Token::Str("ok"));
|
||||
|
||||
// JSON response
|
||||
tokens_by_type(
|
||||
&tokens,
|
||||
"track-list",
|
||||
mpv::Format::Str(r#""ok""#),
|
||||
PropertyData::Str(r#""ok""#),
|
||||
Token::Str("ok"),
|
||||
);
|
||||
tokens_by_type(
|
||||
&tokens,
|
||||
"video-params",
|
||||
mpv::Format::Str(r#""ok""#),
|
||||
PropertyData::Str(r#""ok""#),
|
||||
Token::Str("ok"),
|
||||
);
|
||||
tokens_by_type(
|
||||
&tokens,
|
||||
"metadata",
|
||||
mpv::Format::Str(r#""ok""#),
|
||||
PropertyData::Str(r#""ok""#),
|
||||
Token::Str("ok"),
|
||||
);
|
||||
}
|
||||
|
|
@ -70,13 +71,13 @@ fn ended_tokens() {
|
|||
let mut typed_tokens = tokens.clone();
|
||||
typed_tokens[2] = Token::Str("error");
|
||||
assert_tokens(
|
||||
&PlayerEnded::from_end_reason(mpv::EndFileReason::MPV_END_FILE_REASON_ERROR),
|
||||
&PlayerEnded::from_end_reason(4),
|
||||
&typed_tokens,
|
||||
);
|
||||
let mut typed_tokens = tokens.clone();
|
||||
typed_tokens[2] = Token::Str("quit");
|
||||
assert_tokens(
|
||||
&PlayerEnded::from_end_reason(mpv::EndFileReason::MPV_END_FILE_REASON_QUIT),
|
||||
&PlayerEnded::from_end_reason(3),
|
||||
&typed_tokens,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use crate::stremio_app::ipc;
|
||||
use crate::stremio_app::RPCResponse;
|
||||
use libmpv::events::Event;
|
||||
use libmpv::{Format, Mpv};
|
||||
use native_windows_gui::{self as nwg, PartialUi};
|
||||
use std::cell::RefCell;
|
||||
use std::sync::mpsc;
|
||||
|
|
@ -30,115 +32,120 @@ impl PartialUi for Player {
|
|||
.hwnd()
|
||||
.expect("Cannot obtain window handle") as i64;
|
||||
thread::spawn(move || {
|
||||
let mut mpv_builder =
|
||||
mpv::MpvHandlerBuilder::new().expect("Error while creating MPV builder");
|
||||
mpv_builder
|
||||
.set_option("wid", hwnd)
|
||||
.expect("failed setting wid");
|
||||
// mpv_builder.set_option("vo", "gpu").expect("unable to set vo");
|
||||
// win, opengl: works but least performancy, 10-15% CPU
|
||||
// winvk, vulkan: works as good as d3d11
|
||||
// d3d11, d1d11: works great
|
||||
// dxinterop, auto: works, slightly more cpu use than d3d11
|
||||
// default (auto) seems to be d3d11 (vo/gpu/d3d11)
|
||||
mpv_builder
|
||||
.set_option("gpu-context", "angle")
|
||||
.and_then(|_| mpv_builder.set_option("gpu-api", "auto"))
|
||||
.expect("setting gpu options failed");
|
||||
mpv_builder
|
||||
.try_hardware_decoding()
|
||||
.expect("failed setting hwdec");
|
||||
mpv_builder
|
||||
.set_option("title", "Stremio")
|
||||
.expect("failed setting title");
|
||||
mpv_builder
|
||||
.set_option("terminal", "yes")
|
||||
.expect("failed setting terminal");
|
||||
mpv_builder
|
||||
.set_option("msg-level", "all=no,cplayer=debug")
|
||||
.expect("failed setting msg-level");
|
||||
mpv_builder
|
||||
.set_option("quiet", "yes")
|
||||
.expect("failed setting msg-level");
|
||||
let mut mpv = mpv_builder.build().expect("Cannot build MPV");
|
||||
// builder thread
|
||||
let mpv = Mpv::with_initializer(|init| {
|
||||
init.set_property("wid", hwnd)?;
|
||||
init.set_property("gpu-context", "angle")?;
|
||||
init.set_property("gpu-api", "auto")?;
|
||||
init.set_property("title", "Stremio")?;
|
||||
init.set_property("terminal", "yes")?;
|
||||
init.set_property("msg-level", "all=no,cplayer=debug")?;
|
||||
init.set_property("quiet", "yes")?;
|
||||
Ok(())
|
||||
})
|
||||
.expect("Cannot create MPV");
|
||||
let ev_ctx = Arc::new(Mutex::new(mpv.create_event_context()));
|
||||
crossbeam_utils::thread::scope(|scope| {
|
||||
scope.spawn(|_| {
|
||||
let rx = rx;
|
||||
for msg in rx.iter() {
|
||||
match serde_json::from_str::<InMsg>(msg.as_str()) {
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvObserveProp,
|
||||
InMsgArgs::ObProp(PropKey::Bool(prop)),
|
||||
)) => {
|
||||
let ev_ctx = ev_ctx.lock().unwrap();
|
||||
ev_ctx.observe_property(prop.to_string().as_str(), Format::Flag, 0)
|
||||
}
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvObserveProp,
|
||||
InMsgArgs::ObProp(PropKey::Int(prop)),
|
||||
)) => {
|
||||
let ev_ctx = ev_ctx.lock().unwrap();
|
||||
ev_ctx.observe_property(prop.to_string().as_str(), Format::Int64, 0)
|
||||
}
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvObserveProp,
|
||||
InMsgArgs::ObProp(PropKey::Fp(prop)),
|
||||
)) => {
|
||||
let ev_ctx = ev_ctx.lock().unwrap();
|
||||
ev_ctx.observe_property(
|
||||
prop.to_string().as_str(),
|
||||
Format::Double,
|
||||
0,
|
||||
)
|
||||
}
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvObserveProp,
|
||||
InMsgArgs::ObProp(PropKey::Str(prop)),
|
||||
)) => {
|
||||
let ev_ctx = ev_ctx.lock().unwrap();
|
||||
ev_ctx.observe_property(
|
||||
prop.to_string().as_str(),
|
||||
Format::String,
|
||||
0,
|
||||
)
|
||||
}
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvSetProp,
|
||||
InMsgArgs::StProp(prop, PropVal::Bool(val)),
|
||||
)) => mpv.set_property(prop.to_string().as_str(), val),
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvSetProp,
|
||||
InMsgArgs::StProp(prop, PropVal::Num(val)),
|
||||
)) => mpv.set_property(prop.to_string().as_str(), val),
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvSetProp,
|
||||
InMsgArgs::StProp(prop, PropVal::Str(val)),
|
||||
)) => mpv.set_property(prop.to_string().as_str(), val.as_str()),
|
||||
Ok(InMsg(InMsgFn::MpvCommand, InMsgArgs::Cmd(cmd))) => {
|
||||
let cmd: Vec<String> = cmd.into();
|
||||
let cmd = cmd.iter().map(|s| s.as_str()).collect::<Vec<_>>();
|
||||
mpv.command(cmd[0], &cmd[1..])
|
||||
}
|
||||
_ => {
|
||||
eprintln!("MPV unsupported message {}", msg);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
.ok();
|
||||
} // incoming message drain loop
|
||||
});
|
||||
|
||||
'main: loop {
|
||||
// wait up to X seconds for an event.
|
||||
while let Some(event) = mpv.wait_event(0.0) {
|
||||
'main: loop {
|
||||
// Give time for observe_property commands to be processed before locking the mutex
|
||||
thread::sleep(std::time::Duration::from_millis(30));
|
||||
// even if you don't do anything with the events, it is still necessary to empty
|
||||
// the event loop
|
||||
let mut ev_ctx = ev_ctx.lock().unwrap();
|
||||
// wait up to X seconds for an event. -1 means forever; 0 returns event isntantly
|
||||
while let Some(event) = ev_ctx.wait_event(1.0) {
|
||||
let resp_event = match event {
|
||||
Ok(Event::PropertyChange { name, change, .. }) => PlayerResponse(
|
||||
"mpv-prop-change",
|
||||
PlayerEvent::PropChange(PlayerProprChange::from_name_value(
|
||||
name.to_string(),
|
||||
change,
|
||||
)),
|
||||
)
|
||||
.to_value(),
|
||||
|
||||
let resp_event = match event {
|
||||
mpv::Event::PropertyChange {
|
||||
name,
|
||||
change,
|
||||
reply_userdata: _,
|
||||
} => PlayerResponse(
|
||||
"mpv-prop-change",
|
||||
PlayerEvent::PropChange(PlayerProprChange::from_name_value(
|
||||
name.to_string(),
|
||||
change,
|
||||
)),
|
||||
)
|
||||
.to_value(),
|
||||
mpv::Event::EndFile(Ok(reason)) => PlayerResponse(
|
||||
"mpv-event-ended",
|
||||
PlayerEvent::End(PlayerEnded::from_end_reason(reason)),
|
||||
)
|
||||
.to_value(),
|
||||
mpv::Event::Shutdown => {
|
||||
break 'main;
|
||||
Ok(Event::EndFile(reason)) => PlayerResponse(
|
||||
"mpv-event-ended",
|
||||
PlayerEvent::End(PlayerEnded::from_end_reason(reason)),
|
||||
)
|
||||
.to_value(),
|
||||
Ok(Event::Shutdown) => {
|
||||
break 'main;
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
if resp_event.is_some() {
|
||||
tx1.send(RPCResponse::response_message(resp_event)).ok();
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
if resp_event.is_some() {
|
||||
tx1.send(RPCResponse::response_message(resp_event)).ok();
|
||||
}
|
||||
} // event processing
|
||||
|
||||
thread::sleep(std::time::Duration::from_millis(30));
|
||||
for msg in rx.try_iter() {
|
||||
match serde_json::from_str::<InMsg>(msg.as_str()) {
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvObserveProp,
|
||||
InMsgArgs::ObProp(PropKey::Bool(prop)),
|
||||
)) => mpv.observe_property::<bool>(prop.to_string().as_str(), 0),
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvObserveProp,
|
||||
InMsgArgs::ObProp(PropKey::Int(prop)),
|
||||
)) => mpv.observe_property::<i64>(prop.to_string().as_str(), 0),
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvObserveProp,
|
||||
InMsgArgs::ObProp(PropKey::Fp(prop)),
|
||||
)) => mpv.observe_property::<f64>(prop.to_string().as_str(), 0),
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvObserveProp,
|
||||
InMsgArgs::ObProp(PropKey::Str(prop)),
|
||||
)) => mpv.observe_property::<&str>(prop.to_string().as_str(), 0),
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvSetProp,
|
||||
InMsgArgs::StProp(prop, PropVal::Bool(val)),
|
||||
)) => mpv.set_property(prop.to_string().as_str(), val),
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvSetProp,
|
||||
InMsgArgs::StProp(prop, PropVal::Num(val)),
|
||||
)) => mpv.set_property(prop.to_string().as_str(), val),
|
||||
Ok(InMsg(
|
||||
InMsgFn::MpvSetProp,
|
||||
InMsgArgs::StProp(prop, PropVal::Str(val)),
|
||||
)) => mpv.set_property(prop.to_string().as_str(), val.as_str()),
|
||||
Ok(InMsg(InMsgFn::MpvCommand, InMsgArgs::Cmd(cmd))) => {
|
||||
let cmd: Vec<String> = cmd.into();
|
||||
mpv.command(&cmd.iter().map(|s| s.as_str()).collect::<Vec<_>>())
|
||||
}
|
||||
_ => {
|
||||
eprintln!("MPV unsupported message {}", msg);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
.ok();
|
||||
} // incoming message drain loop
|
||||
} // main loop
|
||||
} // event processing loop
|
||||
} // main loop
|
||||
}) // crossbeam scope
|
||||
}); // builder thread
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue