Mise en place d'un bus d'événements pour les serveurs de médias.

This commit is contained in:
2025-12-01 23:10:16 +01:00
parent ea1774f216
commit aeb9332387
12 changed files with 9436 additions and 9 deletions

View File

@@ -0,0 +1,111 @@
use std::collections::HashMap;
use std::thread;
use std::time::{Duration, Instant};
use anyhow::Result;
use crossbeam_channel::RecvTimeoutError;
use pmocontrol::{ControlPoint, MediaServerEvent, MediaServerInfo, ServerId};
const DISCOVERY_WAIT_SECS: u64 = 5;
const MONITOR_DURATION_SECS: u64 = 90;
fn main() -> Result<()> {
tracing_subscriber::fmt::init();
let cp = ControlPoint::spawn(5)?;
println!(
"ControlPoint started; waiting {}s for discovery...",
DISCOVERY_WAIT_SECS
);
thread::sleep(Duration::from_secs(DISCOVERY_WAIT_SECS));
let servers = cp.list_media_servers();
if servers.is_empty() {
println!("No media servers discovered.");
return Ok(());
}
println!("Discovered media servers:");
for info in &servers {
println!(
" - {} | model={} | udn={} | location={}",
info.friendly_name, info.model_name, info.udn, info.location
);
}
let mut cache: HashMap<ServerId, MediaServerInfo> = servers
.into_iter()
.map(|info| (info.id.clone(), info))
.collect();
let receiver = cp.media_server_events().subscribe();
let deadline = Instant::now() + Duration::from_secs(MONITOR_DURATION_SECS);
println!(
"Listening for ContentDirectory events for {} seconds...",
MONITOR_DURATION_SECS
);
while Instant::now() < deadline {
match receiver.recv_timeout(Duration::from_millis(500)) {
Ok(event) => {
print_event(&cp, &mut cache, &event);
}
Err(RecvTimeoutError::Timeout) => {}
Err(RecvTimeoutError::Disconnected) => {
println!("Event channel disconnected.");
break;
}
}
}
println!("Monitoring finished.");
Ok(())
}
fn print_event(cp: &ControlPoint, cache: &mut HashMap<ServerId, MediaServerInfo>, event: &MediaServerEvent) {
match event {
MediaServerEvent::GlobalUpdated {
server_id,
system_update_id,
} => {
let label = describe_server(cp, cache, server_id);
println!(
"[{}] Global content update (SystemUpdateID={})",
label,
system_update_id
.map(|id| id.to_string())
.unwrap_or_else(|| "<unknown>".into())
);
}
MediaServerEvent::ContainersUpdated {
server_id,
container_ids,
} => {
let label = describe_server(cp, cache, server_id);
println!(
"[{}] Containers updated: {}",
label,
if container_ids.is_empty() {
"<none>".into()
} else {
container_ids.join(", ")
}
);
}
}
}
fn describe_server(
cp: &ControlPoint,
cache: &mut HashMap<ServerId, MediaServerInfo>,
id: &ServerId,
) -> String {
if let Some(info) = cache.get(id) {
return format!("{} ({})", info.friendly_name, id.0);
}
if let Some(info) = cp.media_server(id) {
cache.insert(id.clone(), info.clone());
return format!("{} ({})", info.friendly_name, id.0);
}
format!("{} (unknown)", id.0)
}