énorme refactoring de PMOcontrol step 1
This commit is contained in:
@@ -3,7 +3,7 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use pmocontrol::{
|
||||
ControlPoint, DeviceRegistryRead, MusicRenderer, PlaybackPosition, PlaybackPositionInfo,
|
||||
ControlPoint, DeviceRegistryRead, MusicRendererBackend, PlaybackPosition, PlaybackPositionInfo,
|
||||
PlaybackState, PlaybackStatus, TransportControl, VolumeControl,
|
||||
};
|
||||
|
||||
@@ -38,10 +38,10 @@ fn main() -> io::Result<()> {
|
||||
);
|
||||
}
|
||||
|
||||
let arylic_renderers: Vec<MusicRenderer> = renderers
|
||||
let arylic_renderers: Vec<MusicRendererBackend> = renderers
|
||||
.iter()
|
||||
.filter(|info| info.capabilities.has_arylic_tcp)
|
||||
.filter_map(|info| MusicRenderer::from_registry_info(info.clone(), ®istry))
|
||||
.filter_map(|info| MusicRendererBackend::from_renderer_info(info.clone(), ®istry))
|
||||
.collect();
|
||||
|
||||
if arylic_renderers.is_empty() {
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use pmocontrol::RendererProtocol;
|
||||
use pmocontrol::{ControlPoint, DeviceRegistryRead, MediaServerInfo, RendererInfo};
|
||||
use pmocontrol::{ControlPoint, DeviceRegistryRead, UpnpMediaServer, RendererInfo};
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
// Un tout petit logging optionnel
|
||||
@@ -21,7 +21,7 @@ fn main() -> std::io::Result<()> {
|
||||
let reg = reg.read().expect("registry poisoned");
|
||||
|
||||
let renderers: Vec<RendererInfo> = reg.list_renderers();
|
||||
let servers: Vec<MediaServerInfo> = reg.list_servers();
|
||||
let servers: Vec<UpnpMediaServer> = reg.list_servers();
|
||||
|
||||
println!("=====================");
|
||||
println!("Renderers detected : {}", renderers.len());
|
||||
@@ -29,7 +29,7 @@ fn main() -> std::io::Result<()> {
|
||||
let proto = match r.protocol {
|
||||
RendererProtocol::UpnpAvOnly => "UPnP AV",
|
||||
RendererProtocol::OpenHomeOnly => "OpenHome",
|
||||
RendererProtocol::Hybrid => "Hybrid",
|
||||
RendererProtocol::OpenHomeHybrid => "Hybrid",
|
||||
};
|
||||
|
||||
println!(
|
||||
|
||||
@@ -19,8 +19,8 @@ use crossterm::terminal::{
|
||||
};
|
||||
use pmocontrol::model::TrackMetadata;
|
||||
use pmocontrol::{
|
||||
ControlPoint, DeviceRegistryRead, MediaBrowser, MediaEntry, MediaServerEvent, MediaServerInfo,
|
||||
MusicServer, PlaybackItem, PlaybackPosition, PlaybackPositionInfo, PlaybackStatus,
|
||||
ControlPoint, DeviceRegistryRead, MediaBrowser, MediaEntry, MediaServerEvent, UpnpMediaServer,
|
||||
UpnpMediaServer, PlaybackItem, PlaybackPosition, PlaybackPositionInfo, PlaybackStatus,
|
||||
RendererEvent, RendererInfo, TransportControl, VolumeControl,
|
||||
};
|
||||
use ratatui::Terminal;
|
||||
@@ -102,7 +102,7 @@ fn main() -> Result<()> {
|
||||
|
||||
let servers = {
|
||||
let reg = registry.read().expect("registry poisoned");
|
||||
let list: Vec<MediaServerInfo> = reg
|
||||
let list: Vec<UpnpMediaServer> = reg
|
||||
.list_servers()
|
||||
.into_iter()
|
||||
.filter(|s| s.has_content_directory && s.content_directory_control_url.is_some())
|
||||
@@ -129,10 +129,10 @@ struct App {
|
||||
renderers: Vec<RendererInfo>,
|
||||
renderer_index: usize,
|
||||
renderer_info: Option<RendererInfo>,
|
||||
servers: Vec<MediaServerInfo>,
|
||||
servers: Vec<UpnpMediaServer>,
|
||||
server_index: usize,
|
||||
server_info: Option<MediaServerInfo>,
|
||||
music_server: Option<MusicServer>,
|
||||
server_info: Option<UpnpMediaServer>,
|
||||
music_server: Option<UpnpMediaServer>,
|
||||
browser: Option<BrowserState>,
|
||||
mode: Mode,
|
||||
ui_state: UiState,
|
||||
@@ -168,7 +168,7 @@ impl App {
|
||||
fn new(
|
||||
control_point: Arc<ControlPoint>,
|
||||
renderers: Vec<RendererInfo>,
|
||||
servers: Vec<MediaServerInfo>,
|
||||
servers: Vec<UpnpMediaServer>,
|
||||
) -> Self {
|
||||
Self {
|
||||
control_point,
|
||||
@@ -192,7 +192,7 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn renderer_id(&self) -> Option<pmocontrol::model::RendererId> {
|
||||
fn renderer_id(&self) -> Option<pmocontrol::model::ServiceId> {
|
||||
self.renderer_info.as_ref().map(|info| info.id.clone())
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ impl App {
|
||||
}
|
||||
KeyCode::Enter => {
|
||||
let info = self.servers[self.server_index].clone();
|
||||
match MusicServer::from_info(&info, Duration::from_secs(DEFAULT_TIMEOUT_SECS)) {
|
||||
match UpnpMediaServer::from_info(&info, Duration::from_secs(DEFAULT_TIMEOUT_SECS)) {
|
||||
Ok(server) => {
|
||||
let entries = server.browse_root()?;
|
||||
let browser = BrowserState::new(entries);
|
||||
@@ -947,7 +947,7 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn refresh_queue_snapshot(&mut self, renderer_id: &pmocontrol::model::RendererId) {
|
||||
fn refresh_queue_snapshot(&mut self, renderer_id: &pmocontrol::model::ServiceId) {
|
||||
if let Ok((queue, current_index)) = self.control_point.get_full_queue_snapshot(renderer_id)
|
||||
{
|
||||
self.queue_snapshot = queue;
|
||||
@@ -967,7 +967,7 @@ impl App {
|
||||
|
||||
fn peek_next_queue_item(
|
||||
&self,
|
||||
renderer_id: &pmocontrol::model::RendererId,
|
||||
renderer_id: &pmocontrol::model::ServiceId,
|
||||
) -> Option<PlaybackItem> {
|
||||
self.control_point
|
||||
.get_queue_snapshot(renderer_id)
|
||||
@@ -975,7 +975,7 @@ impl App {
|
||||
.and_then(|queue| queue.into_iter().next())
|
||||
}
|
||||
|
||||
fn get_renderer(&self) -> Result<pmocontrol::MusicRenderer> {
|
||||
fn get_renderer(&self) -> Result<pmocontrol::MusicRendererBackend> {
|
||||
let renderer_id = self
|
||||
.renderer_id()
|
||||
.ok_or_else(|| anyhow!("Renderer not selected"))?;
|
||||
@@ -1230,7 +1230,7 @@ impl NavigationState {
|
||||
|
||||
/// Collect playable items from MediaEntry list (including nested containers).
|
||||
fn collect_playable_items(
|
||||
server: &MusicServer,
|
||||
server: &UpnpMediaServer,
|
||||
entries: &[MediaEntry],
|
||||
) -> Result<Vec<PlaybackItem>> {
|
||||
let mut items = Vec::new();
|
||||
@@ -1255,7 +1255,7 @@ fn collect_playable_items(
|
||||
}
|
||||
|
||||
/// Convert MediaEntry to PlaybackItem.
|
||||
fn playback_item_from_entry(server: &MusicServer, entry: &MediaEntry) -> Option<PlaybackItem> {
|
||||
fn playback_item_from_entry(server: &UpnpMediaServer, entry: &MediaEntry) -> Option<PlaybackItem> {
|
||||
let resource = entry.resources.iter().find(|res| res.is_audio())?;
|
||||
let metadata = TrackMetadata {
|
||||
title: Some(entry.title.clone()),
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use pmocontrol::{
|
||||
ControlPoint, DeviceRegistryRead, MusicRenderer, PlaybackPosition, PlaybackPositionInfo,
|
||||
ControlPoint, DeviceRegistryRead, MusicRendererBackend, PlaybackPosition, PlaybackPositionInfo,
|
||||
PlaybackState, PlaybackStatus, VolumeControl,
|
||||
};
|
||||
|
||||
@@ -34,10 +34,10 @@ fn main() -> io::Result<()> {
|
||||
);
|
||||
}
|
||||
|
||||
let linkplay_renderers: Vec<MusicRenderer> = renderers
|
||||
let linkplay_renderers: Vec<MusicRendererBackend> = renderers
|
||||
.iter()
|
||||
.filter(|info| info.capabilities.has_linkplay_http)
|
||||
.filter_map(|info| MusicRenderer::from_registry_info(info.clone(), ®istry))
|
||||
.filter_map(|info| MusicRendererBackend::from_renderer_info(info.clone(), ®istry))
|
||||
.collect();
|
||||
|
||||
if linkplay_renderers.is_empty() {
|
||||
|
||||
@@ -10,8 +10,8 @@ use std::time::Duration;
|
||||
use anyhow::{Context, Result};
|
||||
use pmocontrol::model::TrackMetadata;
|
||||
use pmocontrol::{
|
||||
ControlPoint, DeviceRegistryRead, MediaBrowser, MediaEntry, MediaServerEvent, MediaServerInfo,
|
||||
MusicRenderer, MusicServer, PlaybackItem, PlaybackPosition, PlaybackPositionInfo, RendererInfo,
|
||||
ControlPoint, DeviceRegistryRead, MediaBrowser, MediaEntry, MediaServerEvent, UpnpMediaServer,
|
||||
MusicRendererBackend, UpnpMediaServer, PlaybackItem, PlaybackPosition, PlaybackPositionInfo, RendererInfo,
|
||||
};
|
||||
|
||||
const DEFAULT_TIMEOUT_SECS: u64 = 5;
|
||||
@@ -69,7 +69,7 @@ fn main() -> Result<()> {
|
||||
server_info.friendly_name, server_info.location, server_info.id.0
|
||||
);
|
||||
|
||||
let renderer_instance = MusicRenderer::from_registry_info(renderer.clone(), ®istry)
|
||||
let renderer_instance = MusicRendererBackend::from_renderer_info(renderer.clone(), ®istry)
|
||||
.expect("Selected renderer is not usable by MusicRenderer façade");
|
||||
let supports_set_next = renderer_instance
|
||||
.as_upnp()
|
||||
@@ -82,7 +82,7 @@ fn main() -> Result<()> {
|
||||
|
||||
let timeout = Duration::from_secs(config.timeout_secs);
|
||||
let server =
|
||||
MusicServer::from_info(&server_info, timeout).context("Failed to init MusicServer")?;
|
||||
UpnpMediaServer::from_info(&server_info, timeout).context("Failed to init MusicServer")?;
|
||||
|
||||
println!("Searching for a Live Playlist container in ContentDirectory...");
|
||||
let live_playlist_container = find_live_playlist_container(&server)
|
||||
@@ -355,8 +355,8 @@ fn pick_renderer(renderers: Vec<RendererInfo>) -> Option<RendererInfo> {
|
||||
Some(selected)
|
||||
}
|
||||
|
||||
fn pick_pmomusic_server(servers: Vec<MediaServerInfo>) -> Option<MediaServerInfo> {
|
||||
let mut candidates: Vec<MediaServerInfo> = servers
|
||||
fn pick_pmomusic_server(servers: Vec<UpnpMediaServer>) -> Option<UpnpMediaServer> {
|
||||
let mut candidates: Vec<UpnpMediaServer> = servers
|
||||
.into_iter()
|
||||
.filter(|info| info.has_content_directory)
|
||||
.filter(|info| info.content_directory_control_url.is_some())
|
||||
@@ -381,7 +381,7 @@ fn pick_pmomusic_server(servers: Vec<MediaServerInfo>) -> Option<MediaServerInfo
|
||||
Some(candidates.remove(0))
|
||||
}
|
||||
|
||||
fn is_pmomusic_server(info: &MediaServerInfo) -> bool {
|
||||
fn is_pmomusic_server(info: &UpnpMediaServer) -> bool {
|
||||
let name = info.friendly_name.to_ascii_lowercase();
|
||||
let model = info.model_name.to_ascii_lowercase();
|
||||
let manufacturer = info.manufacturer.to_ascii_lowercase();
|
||||
@@ -395,7 +395,7 @@ fn is_pmomusic_renderer(info: &RendererInfo) -> bool {
|
||||
}
|
||||
|
||||
/// Search for a container whose title contains "Live Playlist" using BFS.
|
||||
fn find_live_playlist_container(server: &MusicServer) -> Result<Option<MediaEntry>> {
|
||||
fn find_live_playlist_container(server: &UpnpMediaServer) -> Result<Option<MediaEntry>> {
|
||||
let root_entries = server
|
||||
.browse_root()
|
||||
.context("Failed to browse ContentDirectory root")?;
|
||||
@@ -477,7 +477,7 @@ fn find_live_playlist_container(server: &MusicServer) -> Result<Option<MediaEntr
|
||||
/// Collect playable items from a specific container.
|
||||
/// Retries with fewer items if the initial browse times out.
|
||||
fn collect_playable_items_from_container(
|
||||
server: &MusicServer,
|
||||
server: &UpnpMediaServer,
|
||||
container_id: &str,
|
||||
max_tracks: usize,
|
||||
) -> Result<Vec<PlaybackItem>> {
|
||||
@@ -532,7 +532,7 @@ fn collect_playable_items_from_container(
|
||||
Ok(items)
|
||||
}
|
||||
|
||||
fn playback_item_from_entry(server: &MusicServer, entry: &MediaEntry) -> Option<PlaybackItem> {
|
||||
fn playback_item_from_entry(server: &UpnpMediaServer, entry: &MediaEntry) -> Option<PlaybackItem> {
|
||||
// Skip live streams (we're looking for regular tracks in a live playlist)
|
||||
if entry.title.to_ascii_lowercase().contains("live stream") {
|
||||
return None;
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::time::{Duration, Instant};
|
||||
|
||||
use anyhow::Result;
|
||||
use crossbeam_channel::RecvTimeoutError;
|
||||
use pmocontrol::{ControlPoint, MediaServerEvent, MediaServerInfo, ServerId};
|
||||
use pmocontrol::{ControlPoint, MediaServerEvent, UpnpMediaServer, ServerId};
|
||||
|
||||
const DISCOVERY_WAIT_SECS: u64 = 5;
|
||||
const MONITOR_DURATION_SECS: u64 = 90;
|
||||
@@ -33,7 +33,7 @@ fn main() -> Result<()> {
|
||||
);
|
||||
}
|
||||
|
||||
let mut cache: HashMap<ServerId, MediaServerInfo> = servers
|
||||
let mut cache: HashMap<ServerId, UpnpMediaServer> = servers
|
||||
.into_iter()
|
||||
.map(|info| (info.id.clone(), info))
|
||||
.collect();
|
||||
@@ -64,7 +64,7 @@ fn main() -> Result<()> {
|
||||
|
||||
fn print_event(
|
||||
cp: &ControlPoint,
|
||||
cache: &mut HashMap<ServerId, MediaServerInfo>,
|
||||
cache: &mut HashMap<ServerId, UpnpMediaServer>,
|
||||
event: &MediaServerEvent,
|
||||
) {
|
||||
match event {
|
||||
@@ -101,7 +101,7 @@ fn print_event(
|
||||
|
||||
fn describe_server(
|
||||
cp: &ControlPoint,
|
||||
cache: &mut HashMap<ServerId, MediaServerInfo>,
|
||||
cache: &mut HashMap<ServerId, UpnpMediaServer>,
|
||||
id: &ServerId,
|
||||
) -> String {
|
||||
if let Some(info) = cache.get(id) {
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::time::{Duration, Instant};
|
||||
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use pmocontrol::{
|
||||
DeviceDescriptionProvider, DiscoveredEndpoint, HttpXmlDescriptionProvider, MusicRenderer,
|
||||
DeviceDescriptionProvider, DiscoveredEndpoint, HttpXmlDescriptionProvider, MusicRendererBackend,
|
||||
RendererInfo,
|
||||
control_point::ControlPoint,
|
||||
openhome_client::{
|
||||
@@ -86,7 +86,7 @@ fn auto_discover_renderer() -> Result<RendererInfo> {
|
||||
let mut openhome_infos = Vec::new();
|
||||
|
||||
for renderer in renderers {
|
||||
if let MusicRenderer::OpenHome(oh) = renderer {
|
||||
if let MusicRendererBackend::OpenHome(oh) = renderer {
|
||||
if seen.insert(oh.id().0.clone()) {
|
||||
openhome_infos.push(oh.info.clone());
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ use std::time::Duration;
|
||||
use anyhow::{Context, Result};
|
||||
use pmocontrol::model::TrackMetadata;
|
||||
use pmocontrol::{
|
||||
ControlPoint, DeviceRegistryRead, MediaBrowser, MediaEntry, MediaServerEvent, MediaServerInfo,
|
||||
MusicRenderer, MusicServer, PlaybackItem, PlaybackPosition, PlaybackPositionInfo, RendererInfo,
|
||||
ControlPoint, DeviceRegistryRead, MediaBrowser, MediaEntry, MediaServerEvent, UpnpMediaServer,
|
||||
MusicRendererBackend, UpnpMediaServer, PlaybackItem, PlaybackPosition, PlaybackPositionInfo, RendererInfo,
|
||||
};
|
||||
|
||||
const DEFAULT_TIMEOUT_SECS: u64 = 5;
|
||||
@@ -72,7 +72,7 @@ fn main() -> Result<()> {
|
||||
server_info.friendly_name, server_info.location, server_info.id.0
|
||||
);
|
||||
|
||||
let renderer_instance = MusicRenderer::from_registry_info(renderer.clone(), ®istry)
|
||||
let renderer_instance = MusicRendererBackend::from_renderer_info(renderer.clone(), ®istry)
|
||||
.expect("Selected renderer is not usable by MusicRenderer façade");
|
||||
let supports_set_next = renderer_instance
|
||||
.as_upnp()
|
||||
@@ -85,7 +85,7 @@ fn main() -> Result<()> {
|
||||
|
||||
let timeout = Duration::from_secs(config.timeout_secs);
|
||||
let server =
|
||||
MusicServer::from_info(&server_info, timeout).context("Failed to init MusicServer")?;
|
||||
UpnpMediaServer::from_info(&server_info, timeout).context("Failed to init MusicServer")?;
|
||||
|
||||
let root_entries = server
|
||||
.browse_root()
|
||||
@@ -322,8 +322,8 @@ fn pick_renderer(renderers: Vec<RendererInfo>) -> Option<RendererInfo> {
|
||||
Some(selected)
|
||||
}
|
||||
|
||||
fn pick_media_server(servers: Vec<MediaServerInfo>) -> Option<MediaServerInfo> {
|
||||
let mut candidates: Vec<MediaServerInfo> = servers
|
||||
fn pick_media_server(servers: Vec<UpnpMediaServer>) -> Option<UpnpMediaServer> {
|
||||
let mut candidates: Vec<UpnpMediaServer> = servers
|
||||
.into_iter()
|
||||
.filter(|info| info.has_content_directory)
|
||||
.filter(|info| info.content_directory_control_url.is_some())
|
||||
@@ -346,7 +346,7 @@ fn pick_media_server(servers: Vec<MediaServerInfo>) -> Option<MediaServerInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_pmomusic_server(info: &MediaServerInfo) -> bool {
|
||||
fn is_pmomusic_server(info: &UpnpMediaServer) -> bool {
|
||||
let name = info.friendly_name.to_ascii_lowercase();
|
||||
let header = info.server_header.to_ascii_lowercase();
|
||||
name.contains("pmomusic") || header.contains("pmomusic")
|
||||
@@ -359,7 +359,7 @@ fn is_pmomusic_renderer(info: &RendererInfo) -> bool {
|
||||
}
|
||||
|
||||
fn collect_playable_items_with_binding(
|
||||
server: &MusicServer,
|
||||
server: &UpnpMediaServer,
|
||||
entries: &[MediaEntry],
|
||||
max_tracks: usize,
|
||||
) -> Result<(Vec<PlaybackItem>, Option<String>)> {
|
||||
@@ -423,7 +423,7 @@ fn collect_playable_items_with_binding(
|
||||
}
|
||||
|
||||
fn gather_items_from_entry(
|
||||
server: &MusicServer,
|
||||
server: &UpnpMediaServer,
|
||||
entry: &MediaEntry,
|
||||
max_tracks: usize,
|
||||
depth: usize,
|
||||
@@ -464,7 +464,7 @@ fn gather_items_from_entry(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn playback_item_from_entry(server: &MusicServer, entry: &MediaEntry) -> Option<PlaybackItem> {
|
||||
fn playback_item_from_entry(server: &UpnpMediaServer, entry: &MediaEntry) -> Option<PlaybackItem> {
|
||||
if entry.title.to_ascii_lowercase().contains("live stream") {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ use pmocontrol::PlaybackPosition;
|
||||
use pmocontrol::model::RendererInfo;
|
||||
use pmocontrol::openhome_client::{OhInfoClient, OhPlaylistClient, OhTimeClient};
|
||||
use pmocontrol::{
|
||||
ControlPoint, MusicRenderer, PlaybackState, PlaybackStatus, RendererCapabilities,
|
||||
ControlPoint, MusicRendererBackend, PlaybackState, PlaybackStatus, RendererCapabilities,
|
||||
RendererProtocol, TransportControl, VolumeControl,
|
||||
};
|
||||
use std::env;
|
||||
@@ -37,7 +37,7 @@ fn main() -> Result<()> {
|
||||
thread::sleep(Duration::from_secs(5));
|
||||
|
||||
// 2. Snapshot of logical music renderers
|
||||
let mut renderers: Vec<MusicRenderer> = cp.list_music_renderers();
|
||||
let mut renderers: Vec<MusicRendererBackend> = cp.list_music_renderers();
|
||||
|
||||
// Filter out the in-dev PMOMusic renderer (if present)
|
||||
renderers.retain(|r| {
|
||||
@@ -276,20 +276,20 @@ fn print_openhome_details(prefix: &str, info: &RendererInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_backend(prefix: &str, renderer: &MusicRenderer) {
|
||||
fn print_backend(prefix: &str, renderer: &MusicRendererBackend) {
|
||||
let backend = match renderer {
|
||||
MusicRenderer::Upnp(_) => "UpnpRenderer (UPnP AV / DLNA)",
|
||||
MusicRenderer::LinkPlay(_) => "LinkPlayRenderer (LinkPlay HTTP)",
|
||||
MusicRenderer::ArylicTcp(_) => "ArylicTcpRenderer (ARylic TCP Protocol)",
|
||||
MusicRenderer::HybridUpnpArylic { .. } => {
|
||||
MusicRendererBackend::Upnp(_) => "UpnpRenderer (UPnP AV / DLNA)",
|
||||
MusicRendererBackend::LinkPlay(_) => "LinkPlayRenderer (LinkPlay HTTP)",
|
||||
MusicRendererBackend::ArylicTcp(_) => "ArylicTcpRenderer (ARylic TCP Protocol)",
|
||||
MusicRendererBackend::HybridUpnpArylic { .. } => {
|
||||
"Hybrid UpnpArylicRenderer (UPnP AV / DLNA + ARylic TCP Protocol)"
|
||||
}
|
||||
MusicRenderer::OpenHome(_) => "OpenHomeRenderer (native OpenHome stack)",
|
||||
MusicRendererBackend::OpenHome(_) => "OpenHomeRenderer (native OpenHome stack)",
|
||||
};
|
||||
println!("{prefix}Backend : {backend}");
|
||||
}
|
||||
|
||||
fn dump_renderer_state(renderer: &MusicRenderer, label: &str) -> Result<()> {
|
||||
fn dump_renderer_state(renderer: &MusicRendererBackend, label: &str) -> Result<()> {
|
||||
println!("\n[{label}]");
|
||||
|
||||
if let Ok(state) = renderer.playback_state() {
|
||||
@@ -344,7 +344,7 @@ fn dump_renderer_state(renderer: &MusicRenderer, label: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn progress_monitor(renderer: &MusicRenderer, label: &str, iterations: usize, interval_secs: u64) {
|
||||
fn progress_monitor(renderer: &MusicRendererBackend, label: &str, iterations: usize, interval_secs: u64) {
|
||||
println!(
|
||||
"\n[{label}] polling playback state/position {} times (every {} s)...",
|
||||
iterations, interval_secs
|
||||
@@ -370,7 +370,7 @@ fn progress_monitor(renderer: &MusicRenderer, label: &str, iterations: usize, in
|
||||
}
|
||||
}
|
||||
|
||||
fn volume_demo(renderer: &MusicRenderer) -> Result<()> {
|
||||
fn volume_demo(renderer: &MusicRendererBackend) -> Result<()> {
|
||||
// Try to get current volume
|
||||
let original = renderer.volume()?;
|
||||
println!(" Current music volume : {}", original);
|
||||
|
||||
Reference in New Issue
Block a user