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.
This commit is contained in:
Claude
2025-11-07 06:15:27 +00:00
parent 7fbb2c418b
commit c92ad696de

View File

@@ -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) => {