From 04726d1ce0bc04d26a8eb44f24ed8d5701068f62 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Sun, 22 Dec 2024 21:45:50 +0100 Subject: [PATCH] main: continuously report play status to systemd --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index ecb54e6..a6ece72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -604,6 +604,7 @@ dependencies = [ "clap", "clap-verbosity-flag", "env_logger", + "futures", "log", "mpvipc-async", "sd-notify", diff --git a/Cargo.toml b/Cargo.toml index 514fb62..da3c11e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ axum = { version = "0.7.7", features = ["macros"] } clap = { version = "4.4.1", features = ["derive"] } clap-verbosity-flag = "2.2.2" env_logger = "0.10.0" +futures = "0.3.31" log = "0.4.20" mpvipc-async = { git = "https://git.pvv.ntnu.no/Projects/mpvipc-async.git", rev = "v0.1.0" } sd-notify = "0.4.3" diff --git a/src/main.rs b/src/main.rs index 8256bf4..aad9afa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,13 @@ use anyhow::Context; use axum::Router; use clap::Parser; use clap_verbosity_flag::Verbosity; +use futures::StreamExt; use mpv_setup::{connect_to_mpv, create_mpv_config_file, show_grzegorz_image}; -use mpvipc_async::Mpv; +use mpvipc_async::{Event, Mpv, MpvDataType, MpvExt}; use std::net::{IpAddr, SocketAddr}; use systemd_journal_logger::JournalLog; use tempfile::NamedTempFile; +use tokio::task::JoinHandle; mod api; mod mpv_setup; @@ -87,6 +89,66 @@ async fn setup_systemd_watchdog_thread() -> anyhow::Result<()> { Ok(()) } +fn systemd_update_play_status(playing: bool, current_song: &Option) { + sd_notify::notify( + false, + &[sd_notify::NotifyState::Status(&format!( + "{} {:?}", + if playing { "[PLAY]" } else { "[STOP]" }, + if let Some(song) = current_song { + song + } else { + "" + } + ))], + ) + .unwrap_or_else(|e| log::warn!("Failed to update systemd status with current song: {}", e)); +} + +async fn setup_systemd_notifier(mpv: Mpv) -> anyhow::Result> { + let handle = tokio::spawn(async move { + log::debug!("Starting systemd notifier thread"); + let mut event_stream = mpv.get_event_stream().await; + + mpv.observe_property(100, "media-title").await.unwrap(); + mpv.observe_property(100, "pause").await.unwrap(); + + let mut current_song: Option = mpv.get_property("media-title").await.unwrap(); + let mut playing = !mpv.get_property("pause").await.unwrap().unwrap_or(false); + + systemd_update_play_status(playing, ¤t_song); + + loop { + match event_stream.next().await { + Some(Ok(Event::PropertyChange { name, data, .. })) => { + match (name.as_str(), data) { + ("media-title", Some(MpvDataType::String(s))) => { + current_song = Some(s); + } + ("media-title", None) => { + current_song = None; + } + ("pause", Some(MpvDataType::Bool(b))) => { + playing = !b; + } + (event_name, _) => { + log::trace!( + "Received unexpected property change on systemd notifier thread: {}", + event_name + ); + } + } + + systemd_update_play_status(playing, ¤t_song) + } + _ => {} + } + } + }); + + Ok(handle) +} + async fn shutdown(mpv: Mpv, proc: Option) { log::info!("Shutting down"); sd_notify::notify(false, &[sd_notify::NotifyState::Stopping]).unwrap_or_else(|e| { @@ -142,6 +204,10 @@ async fn main() -> anyhow::Result<()> { .await .context("Failed to connect to mpv")?; + if systemd_mode { + setup_systemd_notifier(mpv.clone()).await?; + } + if let Err(e) = show_grzegorz_image(mpv.clone()).await { log::warn!("Could not show Grzegorz image: {}", e); }