minor refactor + cargo fmt --all

This commit is contained in:
Martin Kavík 2022-04-01 22:39:20 +02:00
parent 81e088800b
commit f10380f60a
6 changed files with 852 additions and 842 deletions

View file

@ -100,7 +100,10 @@ impl MainWindow {
let web_rx = web_rx.clone();
// Read message from player
thread::spawn(move || loop {
player_rx.iter().map(|msg| web_tx_player.send(msg)).for_each(drop);
player_rx
.iter()
.map(|msg| web_tx_player.send(msg))
.for_each(drop);
}); // thread
let toggle_fullscreen_sender = self.toggle_fullscreen_notice.sender();

View file

@ -21,13 +21,9 @@ impl RPCRequest {
.and_then(|arg| arg.as_str())
}
pub fn get_params(&self) -> Option<&serde_json::Value> {
self.args.as_ref().and_then(|args| {
if args.len() > 1 {
Some(&args[1])
} else {
None
}
})
self.args
.as_ref()
.and_then(|args| if args.len() > 1 { Some(&args[1]) } else { None })
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]

View file

@ -1,8 +1,8 @@
use core::convert::TryFrom;
use libmpv::{events::PropertyData, mpv_end_file_reason, EndFileReason};
use parse_display::{Display, FromStr};
use serde::{Deserialize, Serialize};
use std::fmt;
use libmpv::{events::PropertyData, EndFileReason, mpv_end_file_reason};
// Responses
const JSON_RESPONSES: [&str; 3] = ["track-list", "video-params", "metadata"];

View file

@ -1,14 +1,17 @@
use crate::stremio_app::ipc;
use crate::stremio_app::RPCResponse;
use flume::{Receiver, Sender};
use libmpv::{Mpv, events::Event, Format, SetData};
use libmpv::{events::Event, Format, Mpv, SetData};
use native_windows_gui::{self as nwg, PartialUi};
use std::{
sync::Arc,
thread::{self, JoinHandle},
};
use winapi::shared::windef::HWND;
use std::{thread::{self, JoinHandle}, sync::Arc};
use crate::stremio_app::stremio_player::{
InMsg, InMsgArgs, InMsgFn, PlayerEnded, PlayerEvent, PlayerProprChange, PlayerResponse,
PropKey, PropVal, CmdVal,
CmdVal, InMsg, InMsgArgs, InMsgFn, PlayerEnded, PlayerEvent, PlayerProprChange, PlayerResponse,
PropKey, PropVal,
};
struct ObserveProperty {
@ -27,22 +30,26 @@ impl PartialUi for Player {
data: &mut Self,
parent: Option<W>,
) -> Result<(), nwg::NwgError> {
let (in_msg_sender, in_msg_receiver) = flume::unbounded();
let (rpc_response_sender, rpc_response_receiver) = flume::unbounded();
data.channel = ipc::Channel::new(Some((in_msg_sender, rpc_response_receiver)));
// @TODO replace all `expect`s with proper error handling?
let window_handle = parent
.expect("no parent window")
.into()
.hwnd()
.expect("cannot obtain window handle");
// @TODO replace all `expect`s with proper error handling?
let (in_msg_sender, in_msg_receiver) = flume::unbounded();
let (rpc_response_sender, rpc_response_receiver) = flume::unbounded();
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 (observe_property_sender, observe_property_receiver) = flume::unbounded();
let _event_thread = create_event_thread(Arc::clone(&mpv), observe_property_receiver, rpc_response_sender);
let _event_thread = create_event_thread(
Arc::clone(&mpv),
observe_property_receiver,
rpc_response_sender,
);
let _message_thread = create_message_thread(mpv, observe_property_sender, in_msg_receiver);
// @TODO implement a mechanism to stop threads on `Player` drop if needed
@ -52,24 +59,43 @@ impl PartialUi for Player {
fn create_shareable_mpv(window_handle: HWND) -> Arc<Mpv> {
let mpv = Mpv::with_initializer(|initializer| {
initializer.set_property("wid", window_handle as i64).expect("failed setting wid");
initializer
.set_property("wid", window_handle as i64)
.expect("failed setting wid");
// initializer.set_property("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)
initializer.set_property("gpu-context", "angle").expect("failed setting gpu-contex");
initializer.set_property("gpu-api", "auto").expect("failed setting gpu-api");
initializer.set_property("title", "Stremio").expect("failed setting title");
initializer.set_property("terminal", "yes").expect("failed setting terminal");
initializer.set_property("msg-level", "all=no,cplayer=debug").expect("failed setting msg-level");
initializer.set_property("quiet", "yes").expect("failed setting quiet");
initializer.set_property("hwdec", "auto").expect("failed setting hwdec");
initializer
.set_property("gpu-context", "angle")
.expect("failed setting gpu-contex");
initializer
.set_property("gpu-api", "auto")
.expect("failed setting gpu-api");
initializer
.set_property("title", "Stremio")
.expect("failed setting title");
initializer
.set_property("terminal", "yes")
.expect("failed setting terminal");
initializer
.set_property("msg-level", "all=no,cplayer=debug")
.expect("failed setting msg-level");
initializer
.set_property("quiet", "yes")
.expect("failed setting quiet");
initializer
.set_property("hwdec", "auto")
.expect("failed setting hwdec");
// FIXME: very often the audio track isn't selected when using "aid" = "auto"
initializer.set_property("aid", 1).expect("failed setting aid");
initializer
.set_property("aid", 1)
.expect("failed setting aid");
Ok(())
}).expect("cannot build MPV");
})
.expect("cannot build MPV");
Arc::new(mpv)
}
@ -77,15 +103,19 @@ fn create_shareable_mpv(window_handle: HWND) -> Arc<Mpv> {
fn create_event_thread(
mpv: Arc<Mpv>,
observe_property_receiver: Receiver<ObserveProperty>,
rpc_response_sender: Sender<String>
rpc_response_sender: Sender<String>,
) -> JoinHandle<()> {
thread::spawn(move || {
let mut event_context = mpv.create_event_context();
event_context.disable_deprecated_events().expect("failed to disable deprecated MPV events");
event_context
.disable_deprecated_events()
.expect("failed to disable deprecated MPV events");
loop {
for ObserveProperty { name, format } in observe_property_receiver.drain() {
event_context.observe_property(&name, format, 0).expect("failed to observer MPV property");
event_context
.observe_property(&name, format, 0)
.expect("failed to observer MPV property");
}
// -1.0 means to block and wait for an event.
@ -100,32 +130,31 @@ fn create_event_thread(
};
// even if you don't do anything with the events, it is still necessary to empty the event loop
let resp_event = match event {
Event::PropertyChange {
name,
change,
..
} => PlayerResponse(
"mpv-prop-change",
PlayerEvent::PropChange(PlayerProprChange::from_name_value(
name.to_string(),
change,
)),
)
.to_value(),
Event::EndFile(reason) => PlayerResponse(
"mpv-event-ended",
PlayerEvent::End(PlayerEnded::from_end_reason(reason)),
)
.to_value(),
let player_response = match event {
Event::PropertyChange { name, change, .. } => {
PlayerResponse(
"mpv-prop-change",
PlayerEvent::PropChange(PlayerProprChange::from_name_value(
name.to_string(),
change,
)),
)
}
Event::EndFile(reason) => {
PlayerResponse(
"mpv-event-ended",
PlayerEvent::End(PlayerEnded::from_end_reason(reason)),
)
}
Event::Shutdown => {
break;
}
_ => None,
_ => continue,
};
if resp_event.is_some() {
rpc_response_sender.send(RPCResponse::response_message(resp_event)).ok();
}
rpc_response_sender
.send(RPCResponse::response_message(player_response.to_value()))
.expect("failed to send RPCResponse");
}
})
}
@ -133,28 +162,32 @@ fn create_event_thread(
fn create_message_thread(
mpv: Arc<Mpv>,
observe_property_sender: Sender<ObserveProperty>,
in_msg_receiver: Receiver<String>
in_msg_receiver: Receiver<String>,
) -> JoinHandle<()> {
thread::spawn(move || {
// -- Helpers --
let observe_property = |name: String, format: Format| {
observe_property_sender.send(ObserveProperty { name, format }).expect("cannot send ObserveProperty");
observe_property_sender
.send(ObserveProperty { name, format })
.expect("cannot send ObserveProperty");
mpv.wake_up();
};
let send_command = |cmd: CmdVal| {
let (name, arg) = match cmd {
CmdVal::Double(name, arg) => (name, format!(r#""{arg}""#)),
CmdVal::Single((name,)) => (name, String::new())
CmdVal::Single((name,)) => (name, String::new()),
};
mpv.command(&name.to_string(), &[&arg]).expect("failed to execute MPV command");
if let Err(error) = mpv.command(&name.to_string(), &[&arg]) {
eprintln!("failed to execute MPV command: '{error:#}'")
}
};
fn set_property(name: impl ToString, value: impl SetData, mpv: &Mpv) {
if let Err(error) = mpv.set_property(&name.to_string(), value) {
eprintln!("cannot set MPV property: '{error:#}'")
};
}
}
// -- InMsg handler loop --
@ -169,47 +202,26 @@ fn create_message_thread(
};
match in_msg {
InMsg(
InMsgFn::MpvObserveProp,
InMsgArgs::ObProp(PropKey::Bool(prop)),
) => {
InMsg(InMsgFn::MpvObserveProp, InMsgArgs::ObProp(PropKey::Bool(prop))) => {
observe_property(prop.to_string(), Format::Flag);
},
InMsg(
InMsgFn::MpvObserveProp,
InMsgArgs::ObProp(PropKey::Int(prop)),
) => {
}
InMsg(InMsgFn::MpvObserveProp, InMsgArgs::ObProp(PropKey::Int(prop))) => {
observe_property(prop.to_string(), Format::Int64);
},
InMsg(
InMsgFn::MpvObserveProp,
InMsgArgs::ObProp(PropKey::Fp(prop)),
) => {
}
InMsg(InMsgFn::MpvObserveProp, InMsgArgs::ObProp(PropKey::Fp(prop))) => {
observe_property(prop.to_string(), Format::Double);
},
InMsg(
InMsgFn::MpvObserveProp,
InMsgArgs::ObProp(PropKey::Str(prop)),
) => {
}
InMsg(InMsgFn::MpvObserveProp, InMsgArgs::ObProp(PropKey::Str(prop))) => {
observe_property(prop.to_string(), Format::String);
},
InMsg(
InMsgFn::MpvSetProp,
InMsgArgs::StProp(prop, PropVal::Bool(value)),
) => {
set_property(prop, value, &mpv);
}
InMsg(
InMsgFn::MpvSetProp,
InMsgArgs::StProp(prop, PropVal::Num(value)),
) => {
set_property(prop, value, &mpv);
InMsg(InMsgFn::MpvSetProp, InMsgArgs::StProp(name, PropVal::Bool(value))) => {
set_property(name, value, &mpv);
}
InMsg(
InMsgFn::MpvSetProp,
InMsgArgs::StProp(prop, PropVal::Str(value)),
) => {
set_property(prop, value, &mpv);
InMsg(InMsgFn::MpvSetProp, InMsgArgs::StProp(name, PropVal::Num(value))) => {
set_property(name, value, &mpv);
}
InMsg(InMsgFn::MpvSetProp, InMsgArgs::StProp(name, PropVal::Str(value))) => {
set_property(name, value, &mpv);
}
InMsg(InMsgFn::MpvCommand, InMsgArgs::Cmd(cmd)) => {
send_command(cmd);
@ -222,7 +234,6 @@ fn create_message_thread(
})
}
trait MpvExt {
fn wake_up(&self);
}

View file

@ -1,8 +1,8 @@
use std::os::windows::process::CommandExt;
use std::process::Command;
use std::thread;
use std::time::Duration;
use win32job::Job;
use std::os::windows::process::CommandExt;
const CREATE_NO_WINDOW: u32 = 0x08000000;