From f7ea06c70adff77b1bc9c673834e50e639653a5d Mon Sep 17 00:00:00 2001 From: Deivid Soto Date: Tue, 2 Jun 2026 19:42:05 +0200 Subject: [PATCH] fix(stream): honor client network-caching in the M3U playlist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit playlistHandler hardcoded #EXTVLCOPT:network-caching=30000, so VLC pre-buffered ~30 s before starting playback even on a fast, range-served LAN/Tailscale source — the "VLC loads the whole movie before playing" regression. Read the value from a networkCaching query param (clamped 500–60000ms) and default to 3000 when absent. The web sends a network-aware value (small on LAN/Tailscale, larger on the CF funnel); older web clients fall back to the modest default instead of the old 30 s wall. --- internal/engine/stream_server.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/internal/engine/stream_server.go b/internal/engine/stream_server.go index dd21862..b8a68cd 100644 --- a/internal/engine/stream_server.go +++ b/internal/engine/stream_server.go @@ -790,6 +790,21 @@ func (ss *StreamServer) playlistHandler(w http.ResponseWriter, r *http.Request) resumeSec := sanitize(q.Get("resumeSec")) title := sanitize(q.Get("title")) streamURL := q.Get("streamUrl") + // VLC network buffer (ms). The web sends a network-aware value (small on + // LAN/Tailscale, larger on the CF funnel); clamp to a sane range. Older web + // clients that don't pass it get a modest default — the old flat 30000 made + // VLC pre-buffer ~30 s before playback even on a fast, range-served source. + networkCaching := 3000 + if v := sanitize(q.Get("networkCaching")); v != "" { + if n, err := strconv.Atoi(v); err == nil { + if n < 500 { + n = 500 + } else if n > 60000 { + n = 60000 + } + networkCaching = n + } + } // Only accept http(s) URLs to prevent file:// or other URI schemes in the playlist. if streamURL != "" && !strings.HasPrefix(streamURL, "http://") && !strings.HasPrefix(streamURL, "https://") { streamURL = "" @@ -819,7 +834,7 @@ func (ss *StreamServer) playlistHandler(w http.ResponseWriter, r *http.Request) if resumeSec != "" && resumeSec != "0" { b.WriteString(fmt.Sprintf("#EXTVLCOPT:start-time=%s\n", resumeSec)) } - b.WriteString("#EXTVLCOPT:network-caching=30000\n") + b.WriteString(fmt.Sprintf("#EXTVLCOPT:network-caching=%d\n", networkCaching)) b.WriteString(streamURL + "\n") w.Header().Set("Content-Type", "audio/x-mpegurl")