From 76df3bb7faae8e0fc2fa651ce65dea5c93c04f0b Mon Sep 17 00:00:00 2001 From: Deluan Date: Thu, 24 Sep 2026 16:42:35 -0400 Subject: [PATCH] fix(stream): compute the estimated content length in kilobits of 1000 bits estimateContentLength=true announced Duration * bitRate / 8 * 1024 bytes, but a bitrate in kbps is 1000 bits per second, so the header overstated the body by 2.4%. A client that trusts it waits for bytes that never arrive: on a 285s track at 128kbps it asked for 4,669,440 bytes of a 4,561,876 byte body. Reported in #6170. --- core/stream/media_streamer.go | 2 +- core/stream/media_streamer_test.go | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/core/stream/media_streamer.go b/core/stream/media_streamer.go index 6db2f6338..01b67030a 100644 --- a/core/stream/media_streamer.go +++ b/core/stream/media_streamer.go @@ -147,7 +147,7 @@ func (s *Stream) ContentType() string { return mime.TypeByExtension("." + s.form func (s *Stream) Name() string { return s.mf.Title + "." + s.format } func (s *Stream) ModTime() time.Time { return s.mf.UpdatedAt } func (s *Stream) EstimatedContentLength() int { - return int(s.mf.Duration * float32(s.bitRate) / 8 * 1024) + return int(s.mf.Duration * float32(s.bitRate) / 8 * 1000) } // Serve writes the stream to the HTTP response. For seekable streams it uses http.ServeContent diff --git a/core/stream/media_streamer_test.go b/core/stream/media_streamer_test.go index e06599208..e74fb10d4 100644 --- a/core/stream/media_streamer_test.go +++ b/core/stream/media_streamer_test.go @@ -183,6 +183,18 @@ var _ = Describe("MediaStreamer", func() { _, err = io.ReadAll(resp.Body) Expect(err).To(HaveOccurred()) }) + + It("estimates the content length from a bitrate in kilobits of 1000 bits", func() { + hundredSeconds := *mf + hundredSeconds.Duration = 100 + s := stream.NewStream(&hundredSeconds, "mp3", 128, io.NopCloser(bytes.NewReader(nil))) + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodGet, "/?estimateContentLength=true", nil) + + _, _ = s.Serve(ctx, w, r) + + Expect(w.Header().Get("Content-Length")).To(Equal("1600000")) + }) }) })