From c92ad696deb5bceeb34558fbefb04b4c8dd8f69e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Nov 2025 06:15:27 +0000 Subject: [PATCH] Fix playback delay by adding tracks to playlist before draining When a file was already in cache, FlacCacheSink would drain all remaining segments (which can take 13+ seconds - the full track duration) BEFORE adding the track to the playlist. This caused a long delay before playback could start. The fix reorders operations to: 1. Copy metadata to cache (fast) 2. Add pk to playlist IMMEDIATELY (fast) 3. Drain remaining segments (slow, but playback already started) This ensures the playlist receives tracks immediately, allowing playback to start without waiting for segment drainage to complete. Fixes the 13-second delay when playing already-cached files. --- pmoaudio-ext/src/sinks/flac_cache_sink.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/pmoaudio-ext/src/sinks/flac_cache_sink.rs b/pmoaudio-ext/src/sinks/flac_cache_sink.rs index 79cd09cb..54ca97b9 100755 --- a/pmoaudio-ext/src/sinks/flac_cache_sink.rs +++ b/pmoaudio-ext/src/sinks/flac_cache_sink.rs @@ -164,16 +164,8 @@ impl NodeLogic for FlacCacheSinkLogic { let (_chunks, _samples, _duration_sec, stop_reason) = pump_result?; - // Si le fichier était déjà en cache (ChannelClosed), drainer les segments restants - // jusqu'au prochain TrackBoundary ou EndOfStream - let stop_reason = if matches!(stop_reason, StopReason::ChannelClosed) { - tracing::debug!("File was already in cache, draining remaining segments"); - drain_until_track_boundary(&mut rx, &stop_token).await? - } else { - stop_reason - }; - // Copier les métadonnées du TrackBoundary dans le cache + // IMPORTANT: Faire ceci AVANT d'ajouter à la playlist pour que les métadonnées soient disponibles if let Some(src_metadata) = track_metadata { let dest_metadata = self.cache.track_metadata(&pk); @@ -216,7 +208,8 @@ impl NodeLogic for FlacCacheSinkLogic { } } - // Ajouter à la playlist si enregistrée + // Ajouter à la playlist IMMÉDIATEMENT (avant le drainage!) + // Ceci permet à la lecture de commencer pendant que les segments sont drainés #[cfg(feature = "playlist")] if let Some(ref playlist_handle) = self.playlist_handle { playlist_handle.push(pk.clone()).await.map_err(|e| { @@ -224,6 +217,16 @@ impl NodeLogic for FlacCacheSinkLogic { })?; } + // Si le fichier était déjà en cache (ChannelClosed), drainer les segments restants + // jusqu'au prochain TrackBoundary ou EndOfStream + // IMPORTANT: Faire ceci APRÈS l'ajout à la playlist pour ne pas bloquer la lecture + let stop_reason = if matches!(stop_reason, StopReason::ChannelClosed) { + tracing::debug!("File was already in cache, draining remaining segments"); + drain_until_track_boundary(&mut rx, &stop_token).await? + } else { + stop_reason + }; + // Vérifier le stop_reason pour savoir si on continue match stop_reason { StopReason::TrackBoundary(_metadata) => {