From 7fbb2c418bc8830b48984f9a497245c88b89f8e7 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Nov 2025 05:58:27 +0000 Subject: [PATCH] Fix progressive cache support in PlaylistSource The PlaylistSource decoder was hitting EOF prematurely when reading files that were still being downloaded (progressive cache). Instead of stopping, it now checks if the download is still ongoing and waits 100ms before retrying. This preserves the progressive cache behavior: playback can start as soon as the prebuffer (512KB) is ready, and the decoder will gracefully wait for more data to be written as the download continues. Changes: - Modified decode_and_emit_track() to accept cache and pk parameters - When EOF is reached (read == 0), check if download is ongoing - If download is ongoing, wait 100ms and retry instead of stopping - Only break the loop when download is complete and EOF is reached Fixes the issue where the decoder would stop prematurely on partially downloaded files. --- pmoaudio-ext/src/sources/playlist_source.rs | 27 +++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/pmoaudio-ext/src/sources/playlist_source.rs b/pmoaudio-ext/src/sources/playlist_source.rs index bdb39fd6..93fd6c3d 100644 --- a/pmoaudio-ext/src/sources/playlist_source.rs +++ b/pmoaudio-ext/src/sources/playlist_source.rs @@ -237,11 +237,15 @@ impl NodeLogic for PlaylistSourceLogic { tracing::debug!("PlaylistSourceLogic: decoding track: {:?}", file_path); // Décoder et émettre les chunks PCM + // Passer le cache et pk pour gérer le cache progressif + let cache_pk = track.cache_pk(); if let Err(e) = decode_and_emit_track( &file_path, self.chunk_frames, &output, &stop_token, + &self.cache, + cache_pk, ) .await { @@ -264,11 +268,16 @@ impl NodeLogic for PlaylistSourceLogic { // ═══════════════════════════════════════════════════════════════════════════ /// Décode un fichier et émet ses chunks audio +/// +/// Gère le cache progressif : si EOF est atteint et que le download est toujours en cours, +/// attend et réessaie au lieu de terminer immédiatement. async fn decode_and_emit_track( path: &PathBuf, chunk_frames: usize, output: &[mpsc::Sender>], stop_token: &CancellationToken, + cache: &Arc, + cache_pk: &str, ) -> Result<(), AudioError> { // Ouvrir et décoder let file = File::open(path) @@ -320,9 +329,23 @@ async fn decode_and_emit_track( let read = read_result.map_err(|e| { AudioError::IoError(format!("I/O error while decoding: {}", e)) })?; - if read == 0 && pending.is_empty() { - break; + + // Si EOF atteint (read == 0) + if read == 0 { + // Vérifier si le download est toujours en cours (cache progressif) + if cache.get_download(cache_pk).await.is_some() { + // Download en cours - attendre un peu et réessayer + tracing::trace!("decode_and_emit_track: EOF reached but download ongoing, waiting..."); + tokio::time::sleep(Duration::from_millis(100)).await; + continue; // Retry la lecture + } + + // Download terminé - c'est vraiment la fin du fichier + if pending.is_empty() { + break; + } } + if read > 0 { pending.extend_from_slice(&read_buf[..read]); }