main: continuously report play status to systemd
This commit is contained in:
parent
c8ee55ec92
commit
04726d1ce0
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -604,6 +604,7 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"clap-verbosity-flag",
|
"clap-verbosity-flag",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"futures",
|
||||||
"log",
|
"log",
|
||||||
"mpvipc-async",
|
"mpvipc-async",
|
||||||
"sd-notify",
|
"sd-notify",
|
||||||
|
@ -14,6 +14,7 @@ axum = { version = "0.7.7", features = ["macros"] }
|
|||||||
clap = { version = "4.4.1", features = ["derive"] }
|
clap = { version = "4.4.1", features = ["derive"] }
|
||||||
clap-verbosity-flag = "2.2.2"
|
clap-verbosity-flag = "2.2.2"
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
|
futures = "0.3.31"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
mpvipc-async = { git = "https://git.pvv.ntnu.no/Projects/mpvipc-async.git", rev = "v0.1.0" }
|
mpvipc-async = { git = "https://git.pvv.ntnu.no/Projects/mpvipc-async.git", rev = "v0.1.0" }
|
||||||
sd-notify = "0.4.3"
|
sd-notify = "0.4.3"
|
||||||
|
68
src/main.rs
68
src/main.rs
@ -2,11 +2,13 @@ use anyhow::Context;
|
|||||||
use axum::Router;
|
use axum::Router;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use clap_verbosity_flag::Verbosity;
|
use clap_verbosity_flag::Verbosity;
|
||||||
|
use futures::StreamExt;
|
||||||
use mpv_setup::{connect_to_mpv, create_mpv_config_file, show_grzegorz_image};
|
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 std::net::{IpAddr, SocketAddr};
|
||||||
use systemd_journal_logger::JournalLog;
|
use systemd_journal_logger::JournalLog;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
mod mpv_setup;
|
mod mpv_setup;
|
||||||
@ -87,6 +89,66 @@ async fn setup_systemd_watchdog_thread() -> anyhow::Result<()> {
|
|||||||
Ok(())
|
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, ¤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<tokio::process::Child>) {
|
async fn shutdown(mpv: Mpv, proc: Option<tokio::process::Child>) {
|
||||||
log::info!("Shutting down");
|
log::info!("Shutting down");
|
||||||
sd_notify::notify(false, &[sd_notify::NotifyState::Stopping]).unwrap_or_else(|e| {
|
sd_notify::notify(false, &[sd_notify::NotifyState::Stopping]).unwrap_or_else(|e| {
|
||||||
@ -142,6 +204,10 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.await
|
.await
|
||||||
.context("Failed to connect to mpv")?;
|
.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 {
|
if let Err(e) = show_grzegorz_image(mpv.clone()).await {
|
||||||
log::warn!("Could not show Grzegorz image: {}", e);
|
log::warn!("Could not show Grzegorz image: {}", e);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user