main: continuously report play status to systemd

This commit is contained in:
Oystein Kristoffer Tveit 2024-12-22 21:45:50 +01:00
parent c8ee55ec92
commit 04726d1ce0
Signed by: oysteikt
GPG Key ID: 9F2F7D8250F35146
3 changed files with 69 additions and 1 deletions

1
Cargo.lock generated
View File

@ -604,6 +604,7 @@ dependencies = [
"clap",
"clap-verbosity-flag",
"env_logger",
"futures",
"log",
"mpvipc-async",
"sd-notify",

View File

@ -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"

View File

@ -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<String>) {
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<JoinHandle<()>> {
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<String> = mpv.get_property("media-title").await.unwrap();
let mut playing = !mpv.get_property("pause").await.unwrap().unwrap_or(false);
systemd_update_play_status(playing, &current_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, &current_song)
}
_ => {}
}
}
});
Ok(handle)
}
async fn shutdown(mpv: Mpv, proc: Option<tokio::process::Child>) {
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);
}