From 56e1f4c0fbb2cd9458a27d4a6587038edc46f541 Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Sat, 10 Jan 2026 14:58:45 +0100 Subject: [PATCH] Unified playback behavior and playlist binding detachment This commit ensures unified playback behavior across all backends by automatically playing the current track from the queue when available. It also detaches playlist bindings from source renderers during control point operations, improving consistency and reliability of music playback transitions. --- pmocontrol/src/control_point.rs | 9 +++++++++ pmocontrol/src/music_renderer/musicrenderer.rs | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pmocontrol/src/control_point.rs b/pmocontrol/src/control_point.rs index 08f44e8a..07b67053 100644 --- a/pmocontrol/src/control_point.rs +++ b/pmocontrol/src/control_point.rs @@ -1318,8 +1318,17 @@ impl ControlPoint { ); } + // 5b. Detach playlist binding from source renderer + self.detach_queue_playlist(source_renderer_id); + tracing::debug!( + source = source_renderer_id.0.as_str(), + "Detached playlist binding from source renderer" + ); + // 6. Start playback on destination renderer (if there was a current item) if source_snapshot.current_index.is_some() && !source_snapshot.items.is_empty() { + // play() détecte automatiquement la queue et joue le track courant + // (comportement unifié pour tous les backends) if let Err(e) = dest_renderer.play() { tracing::warn!( dest = dest_renderer_id.0.as_str(), diff --git a/pmocontrol/src/music_renderer/musicrenderer.rs b/pmocontrol/src/music_renderer/musicrenderer.rs index 682a6d30..71672f66 100644 --- a/pmocontrol/src/music_renderer/musicrenderer.rs +++ b/pmocontrol/src/music_renderer/musicrenderer.rs @@ -298,8 +298,24 @@ impl MusicRenderer { } /// Transport control: play + /// + /// Démarre ou reprend la lecture. Si une queue non vide existe, + /// joue le track courant de la queue automatiquement (comportement unifié pour tous les backends). pub fn play(&self) -> Result<(), ControlPointError> { - self.backend.lock().expect("Backend mutex poisoned").play() + // Vérifier si on a une queue non vide + let queue = self.queue.lock().expect("Queue mutex poisoned"); + let queue_not_empty = queue.len().unwrap_or(0) > 0; + drop(queue); // Libérer le lock avant l'appel au backend + + if queue_not_empty { + // Si on a des items dans la queue, jouer le track courant (ou le premier si aucun n'est sélectionné) + // peek_current() initialise automatiquement l'index à 0 si nécessaire + // Cela fonctionne pour tous les backends (UPnP interne, OpenHome, etc.) + self.play_current_from_queue() + } else { + // Queue vide : déléguer au backend (reprend la lecture en cours, etc.) + self.backend.lock().expect("Backend mutex poisoned").play() + } } /// Transport control: pause