Mise en place d'un bus d'événements pour les serveurs de médias.
This commit is contained in:
111
pmocontrol/examples/media_server_events_demo.rs
Normal file
111
pmocontrol/examples/media_server_events_demo.rs
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user