From 20ed7ecb0216bce12a44e92b9b482b06ce8840e1 Mon Sep 17 00:00:00 2001 From: Glenn Thompson Date: Thu, 9 Apr 2026 17:12:15 +0100 Subject: [PATCH] Tune sync delay to 10s, fix countdown during transitions, add buffer bloat monitor - Set *browser-buffer-seconds* to 10 (5s=23s early, 23s=14s late) - Hide countdown timer during title transition window (titles mismatch) - Add client-side buffer bloat monitor: logs buffer size every 30s, auto-reconnects if buffer exceeds 15s to prevent drift - Reduce buffer monitor log spam (only log when >5s, check every 30s) - Update cl-streamer submodule ref --- cl-streamer | 2 +- parenscript/stream-player.lisp | 12 ++++++------ stream-harmony.lisp | 29 ++++++++++++++++------------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/cl-streamer b/cl-streamer index 8a5dde5..cc4215d 160000 --- a/cl-streamer +++ b/cl-streamer @@ -1 +1 @@ -Subproject commit 8a5dde598370b13965317f456999a85096832be6 +Subproject commit cc4215d1c663c5aed4e9758c755a944016fa6aaa diff --git a/parenscript/stream-player.lisp b/parenscript/stream-player.lisp index 958059a..ef98b42 100644 --- a/parenscript/stream-player.lisp +++ b/parenscript/stream-player.lisp @@ -779,12 +779,12 @@ (when (and (not (ps:@ audio-element paused)) (not *is-reconnecting*)) (let ((ahead (get-buffer-ahead audio-element))) - (when (and ahead (> ahead 0)) - (ps:chain console (log (+ "[BUFFER] " (ps:chain ahead (to-fixed 1)) "s ahead"))) - (when (> ahead *max-buffer-seconds*) - (ps:chain console (log (+ "[BUFFER] Bloat detected (" (ps:chain ahead (to-fixed 1)) "s), resetting stream"))) - (reconnect-stream)))))) - 10000))) + (when (and ahead (> ahead 5)) + (ps:chain console (log (+ "[BUFFER] " (ps:chain ahead (to-fixed 1)) "s ahead")))) + (when (and ahead (> ahead *max-buffer-seconds*)) + (ps:chain console (log (+ "[BUFFER] Bloat detected (" (ps:chain ahead (to-fixed 1)) "s), resetting stream"))) + (reconnect-stream))))) + 30000))) ;; Attach event listeners to audio element (defun attach-audio-listeners (audio-element) diff --git a/stream-harmony.lisp b/stream-harmony.lisp index 1ef8eb4..c9b0c19 100644 --- a/stream-harmony.lisp +++ b/stream-harmony.lisp @@ -212,23 +212,26 @@ (listeners (cl-streamer:pipeline-listener-count *harmony-pipeline*)) (track-id (or (find-track-by-title display-title) (find-track-by-file-path (getf track-info :file)))) + (pipeline-title (getf track-info :display-title)) (raw-remaining (cl-streamer/harmony:pipeline-track-remaining *harmony-pipeline*)) - ;; Adjust for browser buffer delay - listener is further behind than pipeline - (remaining (when raw-remaining - (let ((adjusted (+ raw-remaining cl-streamer::*browser-buffer-seconds*))) - (max 0 (floor adjusted)))))) - ;; Diagnostic: log when listener-title differs from pipeline title - (let ((pipeline-title (getf track-info :display-title))) + (titles-match (or (null listener-title) + (null pipeline-title) + (string= listener-title pipeline-title))) + ;; Only show remaining when titles match (delay has passed). + ;; During the transition window the countdown would be inaccurate. + (remaining (when (and raw-remaining titles-match) + (max 0 (floor raw-remaining))))) + ;; Diagnostic: log when listener-title differs from pipeline title (when (and listener-title pipeline-title (not (string= listener-title pipeline-title))) (log:info "[SYNC-DIAG] API returning ~S (pipeline has ~S, delay=~As)" - listener-title pipeline-title cl-streamer::*browser-buffer-seconds*))) - `((:listenurl . ,(format nil "~A/~A" *stream-base-url* mount)) - (:title . ,display-title) - (:listeners . ,(or listeners 0)) - (:track-id . ,track-id) - (:favorite-count . ,(or (get-track-favorite-count display-title) 0)) - ,@(when remaining `((:remaining . ,remaining))))))) + listener-title pipeline-title cl-streamer::*browser-buffer-seconds*)) + `((:listenurl . ,(format nil "~A/~A" *stream-base-url* mount)) + (:title . ,display-title) + (:listeners . ,(or listeners 0)) + (:track-id . ,track-id) + (:favorite-count . ,(or (get-track-favorite-count display-title) 0)) + ,@(when remaining `((:remaining . ,remaining))))))) ;;; ---- Pipeline Lifecycle ----