From 76842dcc6521bfa143893557dbcb32e883ae204a Mon Sep 17 00:00:00 2001 From: Vladimir Borisov Date: Tue, 20 Jul 2021 10:15:24 +0300 Subject: [PATCH] Improved performance --- src/stremio_app/stremio_app.rs | 132 ++++++++---------- .../stremio_player/stremio_player.rs | 28 +++- .../stremio_wevbiew/stremio_wevbiew.rs | 17 +-- 3 files changed, 89 insertions(+), 88 deletions(-) diff --git a/src/stremio_app/stremio_app.rs b/src/stremio_app/stremio_app.rs index 54960fb..4b657ad 100644 --- a/src/stremio_app/stremio_app.rs +++ b/src/stremio_app/stremio_app.rs @@ -74,86 +74,72 @@ impl MainWindow { let (web_tx, web_rx) = web_channel .as_ref() .expect("Cannont obtain communication channel for the Web UI"); - let web_tx = web_tx.clone(); + let web_tx_player = web_tx.clone(); + let web_tx_web = web_tx.clone(); let web_rx = Arc::clone(web_rx); - thread::spawn(move || { - loop { - // Read message from player - { - let rx = player_rx.lock().unwrap(); - if let Ok(msg) = rx.try_recv() { + // Read message from player + thread::spawn(move || loop { + let rx = player_rx.lock().unwrap(); + if let Ok(msg) = rx.recv() { + let resp = RPCResponse { + id: 1, + object: "transport".to_string(), + response_type: 1, + args: serde_json::from_str(&msg).ok(), + ..Default::default() + }; + let resp_json = + serde_json::to_string(&resp).expect("Cannot serialize the response"); + web_tx_player.send(resp_json).ok(); + } // recv + }); // thread + // read message from WebView + thread::spawn(move || loop { + let rx = web_rx.lock().unwrap(); + if let Ok(msg) = rx.recv() { + if let Ok(msg) = serde_json::from_str::(&msg) { + // The handshake. Here we send some useful data to the WEB UI + if msg.id == 0 { let resp = RPCResponse { - id: 1, + id: 0, object: "transport".to_string(), - response_type: 1, - args: serde_json::from_str(&msg).ok(), + response_type: 3, + data: Some(RPCResponseData { + transport: RPCResponseDataTransport { + properties: vec![ + vec![], + vec![ + "".to_string(), + "shellVersion".to_string(), + "".to_string(), + "5.0.0".to_string(), + ], + ], + signals: vec![], + methods: vec![vec!["onEvent".to_string(), "".to_string()]], + }, + }), ..Default::default() }; - let resp_json = - serde_json::to_string(&resp).expect("Cannot serialize the response"); - web_tx.send(resp_json).ok(); - } - }; - - // read message from WebView - { - let rx = web_rx.lock().unwrap(); - if let Ok(msg) = rx.try_recv() { - if let Ok(msg) = serde_json::from_str::(&msg) { - // The handshake. Here we send some useful data to the WEB UI - if msg.id == 0 { - let resp = RPCResponse { - id: 0, - object: "transport".to_string(), - response_type: 3, - data: Some(RPCResponseData { - transport: RPCResponseDataTransport { - properties: vec![ - vec![], - vec![ - "".to_string(), - "shellVersion".to_string(), - "".to_string(), - "5.0.0".to_string(), - ], - ], - signals: vec![], - methods: vec![vec![ - "onEvent".to_string(), - "".to_string(), - ]], - }, - }), - ..Default::default() - }; - let resp_json = serde_json::to_string(&resp).unwrap(); - web_tx.send(resp_json).ok(); - } else if let Some(args) = msg.args { - // TODO: this can panic - if let Some(method) = args.first() { - let method = method.as_str().unwrap(); - if method.starts_with("mpv-") { - let resp_json = serde_json::to_string(&args).unwrap(); - player_tx.send(resp_json).ok(); - } else { - eprintln!("Unsupported command {:?}", args) - } - } + let resp_json = serde_json::to_string(&resp).unwrap(); + web_tx_web.send(resp_json).ok(); + } else if let Some(args) = msg.args { + // TODO: this can panic + if let Some(method) = args.first() { + let method = method.as_str().unwrap(); + if method.starts_with("mpv-") { + let resp_json = serde_json::to_string(&args).unwrap(); + player_tx.send(resp_json).ok(); + } else { + eprintln!("Unsupported command {:?}", args) } - } else { - eprintln!("Web UI sent invalid JSON: {:?}", msg); } - } // try_recv - }; - } - }); - // // let video_path = "/home/ivo/storage/bbb_sunflower_1080p_30fps_normal.mp4"; - // let video_path = "http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4"; - // self.player.command(&["loadfile", video_path]); - // // self.player.set_prop("time-pos", 120.0); - // self.player.set_prop("speed", 2.0); - // // self.player.set_prop("pause", true); - // self.player.command(&["stop"]); + } + } else { + eprintln!("Web UI sent invalid JSON: {:?}", msg); + } + } // recv + }); // thread } fn on_quit(&self) { nwg::stop_thread_dispatch(); diff --git a/src/stremio_app/stremio_player/stremio_player.rs b/src/stremio_app/stremio_player/stremio_player.rs index a7b0990..adfa64c 100644 --- a/src/stremio_app/stremio_player/stremio_player.rs +++ b/src/stremio_app/stremio_player/stremio_player.rs @@ -91,9 +91,20 @@ impl PartialUi for Player { .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"); + + let message_queue: Arc>> = Arc::new(Mutex::new(vec![])); + let thread_messages = Arc::clone(&message_queue); + + thread::spawn(move || loop { + if let Ok(msg) = rx.recv() { + let mut messages = thread_messages.lock().unwrap(); + messages.push(msg); + } + }); + 'main: loop { - // wait up to 0.0 seconds for an event. - while let Some(event) = mpv.wait_event(0.0) { + // wait up to X seconds for an event. + while let Some(event) = mpv.wait_event(0.03) { // even if you don't do anything with the events, it is still necessary to empty // the event loop @@ -132,11 +143,13 @@ impl PartialUi for Player { ) .ok(); } - } - if let Ok(msg) = rx.try_recv() { - let (message, data): (String, serde_json::Value) = - serde_json::from_str(&msg).unwrap(); - match message.as_str() { + } // event processing + + let mut in_message = message_queue.lock().unwrap(); + for msg in in_message.iter() { + let (command, data): (String, serde_json::Value) = + serde_json::from_str(msg).unwrap(); + match command.as_str() { "mpv-observe-prop" => { if let Some(property) = data.as_str() { match property { @@ -213,6 +226,7 @@ impl PartialUi for Player { // mpv.command(&["stop"]).ok(); // mpv.set_property("paused", true).ok(); } + *in_message = vec![]; } }); diff --git a/src/stremio_app/stremio_wevbiew/stremio_wevbiew.rs b/src/stremio_app/stremio_wevbiew/stremio_wevbiew.rs index ab30344..c2908c8 100644 --- a/src/stremio_app/stremio_wevbiew/stremio_wevbiew.rs +++ b/src/stremio_app/stremio_wevbiew/stremio_wevbiew.rs @@ -16,7 +16,7 @@ pub struct WebView { pub channel: RefCell, Arc>>)>>, notice: nwg::Notice, compute: RefCell>>, - message: Arc>>, + message_queue: Arc>>, } impl WebView { @@ -75,7 +75,8 @@ impl PartialUi for WebView { .get_webview() .expect("Cannot obtain webview from controller"); webview - .navigate("https://www.boyanpetrov.rip/stremio/index.html") + // .navigate("https://www.boyanpetrov.rip/stremio/index.html") + .navigate("http://app.strem.io/shell-v4.4/") .expect("Cannot load the webUI"); webview .add_script_to_execute_on_document_created( @@ -108,9 +109,9 @@ impl PartialUi for WebView { } let sender = data.notice.sender(); - let message = data.message.clone(); + let message = data.message_queue.clone(); *data.compute.borrow_mut() = Some(thread::spawn(move || loop { - if let Ok(msg) = rx.try_recv() { + if let Ok(msg) = rx.recv() { let mut message = message.lock().unwrap(); message.push(msg); sender.notice(); @@ -137,14 +138,14 @@ impl PartialUi for WebView { } } E::OnNotice => { - let msg = self.message.clone(); + let message_queue = self.message_queue.clone(); if let Some(controller) = self.controller.get() { let webview = controller.get_webview().expect("Cannot get vebview"); - let mut msg = msg.lock().unwrap(); - for msg in msg.iter() { + let mut message_queue = message_queue.lock().unwrap(); + for msg in message_queue.iter() { webview.post_web_message_as_string(msg).ok(); } - *msg = vec![]; + *message_queue = vec![]; } } _ => {}