Gestion des renderes openhome
This commit is contained in:
@@ -23,6 +23,7 @@ use pmocontrol::{
|
||||
ControlPoint, DeviceRegistryRead, PlaybackPositionInfo, PlaybackState, RendererEvent,
|
||||
RendererId, RendererInfo,
|
||||
};
|
||||
use pmocontrol::openhome_renderer::{format_seconds, map_openhome_state};
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
// Logging simple (tracing_subscriber est déjà utilisé dans les autres exemples)
|
||||
@@ -53,6 +54,7 @@ fn main() -> io::Result<()> {
|
||||
" [{}] {} | model={} | udn={} | location={} | online={}",
|
||||
idx, info.friendly_name, info.model_name, info.udn, info.location, info.online
|
||||
);
|
||||
print_openhome_summary(" ", info, &cp);
|
||||
}
|
||||
|
||||
// 3. Optionnel : sélection d'un renderer par index (filtrage des événements)
|
||||
@@ -126,6 +128,7 @@ fn event_matches_id(event: &RendererEvent, id: &RendererId) -> bool {
|
||||
RendererEvent::MuteChanged { id: eid, .. } => eid == id,
|
||||
RendererEvent::MetadataChanged { id: eid, .. } => eid == id,
|
||||
RendererEvent::QueueUpdated { id: eid, .. } => eid == id,
|
||||
RendererEvent::BindingChanged { id: eid, .. } => eid == id,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +168,60 @@ fn format_position(pos: &PlaybackPositionInfo) -> String {
|
||||
format!("track={} rel_time={} duration={}", track, rel, dur)
|
||||
}
|
||||
|
||||
fn print_openhome_summary(prefix: &str, info: &RendererInfo, cp: &ControlPoint) {
|
||||
if !info.capabilities.has_oh_playlist
|
||||
&& !info.capabilities.has_oh_info
|
||||
&& !info.capabilities.has_oh_time
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let registry = cp.registry();
|
||||
let reg = registry.read().unwrap();
|
||||
let playlist_client = reg.oh_playlist_client_for_renderer(&info.id);
|
||||
let info_client = reg.oh_info_client_for_renderer(&info.id);
|
||||
let time_client = reg.oh_time_client_for_renderer(&info.id);
|
||||
drop(reg);
|
||||
|
||||
if playlist_client.is_none() && info_client.is_none() && time_client.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
println!("{prefix}OpenHome:");
|
||||
|
||||
if let Some(client) = playlist_client {
|
||||
match client.id_array() {
|
||||
Ok(ids) => println!("{prefix} Playlist tracks : {}", ids.len()),
|
||||
Err(err) => println!("{prefix} Playlist tracks : <error {err}>"),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(client) = info_client {
|
||||
match client.transport_state() {
|
||||
Ok(state) => {
|
||||
let logical = map_openhome_state(&state);
|
||||
println!(
|
||||
"{prefix} Transport state : {} ({:?})",
|
||||
state, logical
|
||||
);
|
||||
}
|
||||
Err(err) => println!("{prefix} Transport state : <error {err}>"),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(client) = time_client {
|
||||
match client.position() {
|
||||
Ok(pos) => println!(
|
||||
"{prefix} Position : {}/{} (tracks={})",
|
||||
format_seconds(pos.elapsed_secs),
|
||||
format_seconds(pos.duration_secs),
|
||||
pos.track_count
|
||||
),
|
||||
Err(err) => println!("{prefix} Position : <error {err}>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Affiche un RendererEvent avec horodatage.
|
||||
fn print_event(event: &RendererEvent) {
|
||||
let ts = now_hms();
|
||||
|
||||
@@ -329,13 +329,7 @@ impl CliConfig {
|
||||
}
|
||||
|
||||
fn pick_renderer(renderers: Vec<RendererInfo>) -> Option<RendererInfo> {
|
||||
let mut candidates: Vec<RendererInfo> = renderers
|
||||
.into_iter()
|
||||
.filter(|info| match info.protocol {
|
||||
RendererProtocol::OpenHomeOnly => false,
|
||||
RendererProtocol::UpnpAvOnly | RendererProtocol::Hybrid => true,
|
||||
})
|
||||
.collect();
|
||||
let mut candidates: Vec<RendererInfo> = renderers;
|
||||
|
||||
if candidates.is_empty() {
|
||||
return None;
|
||||
|
||||
@@ -302,13 +302,7 @@ impl CliConfig {
|
||||
}
|
||||
|
||||
fn pick_renderer(renderers: Vec<RendererInfo>) -> Option<RendererInfo> {
|
||||
let mut candidates: Vec<RendererInfo> = renderers
|
||||
.into_iter()
|
||||
.filter(|info| match info.protocol {
|
||||
RendererProtocol::OpenHomeOnly => false,
|
||||
RendererProtocol::UpnpAvOnly | RendererProtocol::Hybrid => true,
|
||||
})
|
||||
.collect();
|
||||
let mut candidates: Vec<RendererInfo> = renderers;
|
||||
|
||||
if candidates.is_empty() {
|
||||
return None;
|
||||
|
||||
@@ -18,6 +18,8 @@ use pmocontrol::{
|
||||
ControlPoint, MusicRenderer, PlaybackState, PlaybackStatus, RendererCapabilities,
|
||||
RendererProtocol, TransportControl, VolumeControl,
|
||||
};
|
||||
use pmocontrol::model::RendererInfo;
|
||||
use pmocontrol::openhome_renderer::{format_seconds, map_openhome_state};
|
||||
use std::env;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
@@ -83,6 +85,7 @@ fn main() -> Result<()> {
|
||||
);
|
||||
print_backend(" ", r);
|
||||
print_capabilities(" ", &info.capabilities, &info.protocol);
|
||||
print_openhome_details(" ", info, &cp);
|
||||
}
|
||||
|
||||
// 5. Select renderer
|
||||
@@ -98,6 +101,7 @@ fn main() -> Result<()> {
|
||||
println!(" Protocol : {:?}", info.protocol);
|
||||
print_backend(" ", renderer);
|
||||
print_capabilities(" ", &info.capabilities, &info.protocol);
|
||||
print_openhome_details(" ", info, &cp);
|
||||
|
||||
if let Some(upnp) = renderer.as_upnp() {
|
||||
println!(
|
||||
@@ -224,6 +228,60 @@ fn print_capabilities(prefix: &str, caps: &RendererCapabilities, proto: &Rendere
|
||||
println!("{prefix} OH Radio : {}", caps.has_oh_radio);
|
||||
}
|
||||
|
||||
fn print_openhome_details(prefix: &str, info: &RendererInfo, cp: &ControlPoint) {
|
||||
if !info.capabilities.has_oh_playlist
|
||||
&& !info.capabilities.has_oh_info
|
||||
&& !info.capabilities.has_oh_time
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let registry = cp.registry();
|
||||
let reg = registry.read().unwrap();
|
||||
let playlist_client = reg.oh_playlist_client_for_renderer(&info.id);
|
||||
let info_client = reg.oh_info_client_for_renderer(&info.id);
|
||||
let time_client = reg.oh_time_client_for_renderer(&info.id);
|
||||
drop(reg);
|
||||
|
||||
if playlist_client.is_none() && info_client.is_none() && time_client.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
println!("{prefix}OpenHome:");
|
||||
|
||||
if let Some(client) = playlist_client {
|
||||
match client.id_array() {
|
||||
Ok(ids) => println!("{prefix} Playlist tracks : {}", ids.len()),
|
||||
Err(err) => println!("{prefix} Playlist tracks : <error {err}>"),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(client) = info_client {
|
||||
match client.transport_state() {
|
||||
Ok(state) => {
|
||||
let logical = map_openhome_state(&state);
|
||||
println!(
|
||||
"{prefix} Transport state : {} ({:?})",
|
||||
state, logical
|
||||
);
|
||||
}
|
||||
Err(err) => println!("{prefix} Transport state : <error {err}>"),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(client) = time_client {
|
||||
match client.position() {
|
||||
Ok(pos) => println!(
|
||||
"{prefix} Position : {}/{} (tracks={})",
|
||||
format_seconds(pos.elapsed_secs),
|
||||
format_seconds(pos.duration_secs),
|
||||
pos.track_count
|
||||
),
|
||||
Err(err) => println!("{prefix} Position : <error {err}>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_backend(prefix: &str, renderer: &MusicRenderer) {
|
||||
let backend = match renderer {
|
||||
MusicRenderer::Upnp(_) => "UpnpRenderer (UPnP AV / DLNA)",
|
||||
|
||||
Reference in New Issue
Block a user