Debug, mise à jour des playlists Open Home.
This commit is contained in:
@@ -435,6 +435,7 @@ impl ControlPoint {
|
||||
Arc::clone(&runtime),
|
||||
event_bus.clone(),
|
||||
oh_event_tx,
|
||||
Arc::clone(&playlist_bindings),
|
||||
)?;
|
||||
|
||||
// Worker thread to process MediaServerEvent and trigger queue refreshes
|
||||
@@ -2669,6 +2670,7 @@ fn spawn_openhome_event_runtime(
|
||||
runtime: Arc<RuntimeState>,
|
||||
event_bus: RendererEventBus,
|
||||
event_tx: Sender<RendererEvent>,
|
||||
playlist_bindings: Arc<Mutex<HashMap<RendererId, PlaylistBinding>>>,
|
||||
) -> io::Result<()> {
|
||||
let listener = TcpListener::bind("0.0.0.0:0")?;
|
||||
let listener_addr = listener
|
||||
@@ -2689,6 +2691,7 @@ fn spawn_openhome_event_runtime(
|
||||
notify_rx,
|
||||
event_tx,
|
||||
listener_addr.port(),
|
||||
playlist_bindings,
|
||||
);
|
||||
|
||||
thread::Builder::new()
|
||||
@@ -2707,6 +2710,7 @@ struct OpenHomeEventRuntime {
|
||||
http_timeout: Duration,
|
||||
subscriptions: HashMap<OpenHomeSubscriptionKey, OpenHomeSubscriptionState>,
|
||||
path_index: HashMap<String, OpenHomeSubscriptionKey>,
|
||||
playlist_bindings: Arc<Mutex<HashMap<RendererId, PlaylistBinding>>>,
|
||||
}
|
||||
|
||||
impl OpenHomeEventRuntime {
|
||||
@@ -2717,6 +2721,7 @@ impl OpenHomeEventRuntime {
|
||||
notify_rx: Receiver<OpenHomeIncomingNotify>,
|
||||
event_tx: Sender<RendererEvent>,
|
||||
listener_port: u16,
|
||||
playlist_bindings: Arc<Mutex<HashMap<RendererId, PlaylistBinding>>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
registry,
|
||||
@@ -2728,6 +2733,7 @@ impl OpenHomeEventRuntime {
|
||||
http_timeout: Duration::from_secs(5),
|
||||
subscriptions: HashMap::new(),
|
||||
path_index: HashMap::new(),
|
||||
playlist_bindings,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2889,30 +2895,27 @@ impl OpenHomeEventRuntime {
|
||||
.any(|(name, _)| is_id_array_property(name))
|
||||
{
|
||||
if self.runtime.uses_openhome_playlist(&entry.renderer.id) {
|
||||
self.runtime
|
||||
.invalidate_openhome_cache(&entry.renderer.id);
|
||||
// Check if this renderer has an active playlist binding
|
||||
// If it does, skip sync because refresh_attached_queue_for() handles it
|
||||
let has_active_binding = {
|
||||
let bindings = self.playlist_bindings.lock().unwrap();
|
||||
bindings.contains_key(&entry.renderer.id)
|
||||
};
|
||||
|
||||
match openhome_renderer_from_registry(&self.registry, &entry.renderer.id) {
|
||||
Ok(renderer) => match renderer.openhome_playlist_len() {
|
||||
Ok(queue_len) => {
|
||||
self.event_bus.broadcast(RendererEvent::QueueUpdated {
|
||||
id: entry.renderer.id.clone(),
|
||||
queue_length: queue_len,
|
||||
});
|
||||
}
|
||||
Err(err) => {
|
||||
warn!(
|
||||
renderer = entry.renderer.friendly_name.as_str(),
|
||||
error = %err,
|
||||
"Failed to read OpenHome playlist length after IdArray event"
|
||||
);
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
if !has_active_binding {
|
||||
// Synchronize the local queue with the renderer's playlist state
|
||||
// This ensures our local mirror stays in sync when the renderer
|
||||
// playlist changes from other control points or manual edits
|
||||
if let Err(err) = sync_openhome_playlist(
|
||||
&self.registry,
|
||||
&self.runtime,
|
||||
&self.event_bus,
|
||||
&entry.renderer.id,
|
||||
) {
|
||||
warn!(
|
||||
renderer = entry.renderer.friendly_name.as_str(),
|
||||
error = %err,
|
||||
"Failed to build OpenHome renderer after IdArray event"
|
||||
"Failed to sync OpenHome playlist after IdArray event"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,12 +445,26 @@ impl QueueBackend for OpenHomeQueue {
|
||||
"LCS computed: minimizing OpenHome playlist operations"
|
||||
);
|
||||
|
||||
for idx in (0..self.track_ids.len()).rev() {
|
||||
if !keep_current[idx] {
|
||||
let track_id = self.track_ids[idx];
|
||||
self.playlist.delete_id(track_id)?;
|
||||
self.track_ids.remove(idx);
|
||||
self.items.remove(idx);
|
||||
// If we're replacing everything (keep=0), use delete_all() instead of
|
||||
// individual delete_id() calls. This is much more robust for live playlists
|
||||
// where track IDs can become invalid between refresh and deletion.
|
||||
if items_to_keep == 0 && items_to_delete > 0 {
|
||||
debug!(
|
||||
renderer = self.renderer_id.0.as_str(),
|
||||
"Using delete_all() for complete replacement (more robust for live playlists)"
|
||||
);
|
||||
self.playlist.delete_all()?;
|
||||
self.track_ids.clear();
|
||||
self.items.clear();
|
||||
} else {
|
||||
// Selective deletion when keeping some items
|
||||
for idx in (0..self.track_ids.len()).rev() {
|
||||
if !keep_current[idx] {
|
||||
let track_id = self.track_ids[idx];
|
||||
self.playlist.delete_id(track_id)?;
|
||||
self.track_ids.remove(idx);
|
||||
self.items.remove(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ impl OhPlaylistClient {
|
||||
}
|
||||
}
|
||||
|
||||
info!(
|
||||
debug!(
|
||||
control_url = self.control_url.as_str(),
|
||||
track_count = entries.len(),
|
||||
expected_count = ids.len(),
|
||||
@@ -562,7 +562,7 @@ impl OhProductClient {
|
||||
let sources = self.source_xml()?;
|
||||
|
||||
// Log all available sources for diagnostics
|
||||
info!(
|
||||
debug!(
|
||||
control_url = self.control_url.as_str(),
|
||||
source_count = sources.len(),
|
||||
"OpenHome Product sources available"
|
||||
@@ -594,7 +594,7 @@ impl OhProductClient {
|
||||
|
||||
// Log current source state
|
||||
let current_source = sources.get(current_index as usize);
|
||||
info!(
|
||||
debug!(
|
||||
control_url = self.control_url.as_str(),
|
||||
current_index,
|
||||
current_source_name = current_source.map(|s| s.name.as_str()).unwrap_or("unknown"),
|
||||
|
||||
Reference in New Issue
Block a user