mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-08 02:17:25 +02:00
fix(stream): keep the headroom in the estimated content length
5686c352c changed the estimate from bitRate / 8 * 1024 to * 1000, reading the 1024 as a unit mistake. It was headroom: the body also carries the ID3 tag, the Xing frame and frame padding, so a nominal-size estimate is short, and net/http aborts a response that writes past its declared Content-Length. Measured on a live server, a 429s track at 64kbps was estimated at 3,439,840 bytes against a 3,441,569-byte body, and the stream was cut with 'http: wrote more than the declared Content-Length'. Restores the 1024, says why next to it, and turns the test into one that asserts the headroom rather than a formula.
This commit is contained in:
parent
8dee15501f
commit
79fc6fed60
2 changed files with 9 additions and 3 deletions
|
|
@ -146,8 +146,11 @@ func (s *Stream) Duration() float32 { return s.mf.Duration }
|
|||
func (s *Stream) ContentType() string { return mime.TypeByExtension("." + s.format) }
|
||||
func (s *Stream) Name() string { return s.mf.Title + "." + s.format }
|
||||
func (s *Stream) ModTime() time.Time { return s.mf.UpdatedAt }
|
||||
|
||||
// EstimatedContentLength deliberately overshoots by 2.4%: the body also carries tags and
|
||||
// padding, and net/http aborts a response that writes past its declared length.
|
||||
func (s *Stream) EstimatedContentLength() int {
|
||||
return int(s.mf.Duration * float32(s.bitRate) / 8 * 1000)
|
||||
return int(s.mf.Duration * float32(s.bitRate) / 8 * 1024)
|
||||
}
|
||||
|
||||
// Serve writes the stream to the HTTP response. For seekable streams it uses http.ServeContent
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing/iotest"
|
||||
"time"
|
||||
|
||||
|
|
@ -184,7 +185,7 @@ var _ = Describe("MediaStreamer", func() {
|
|||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("estimates the content length from a bitrate in kilobits of 1000 bits", func() {
|
||||
It("estimates a content length above the nominal size, so the body never outruns it", func() {
|
||||
hundredSeconds := *mf
|
||||
hundredSeconds.Duration = 100
|
||||
s := stream.NewStream(&hundredSeconds, "mp3", 128, io.NopCloser(bytes.NewReader(nil)))
|
||||
|
|
@ -193,7 +194,9 @@ var _ = Describe("MediaStreamer", func() {
|
|||
|
||||
_, _ = s.Serve(ctx, w, r)
|
||||
|
||||
Expect(w.Header().Get("Content-Length")).To(Equal("1600000"))
|
||||
length, err := strconv.Atoi(w.Header().Get("Content-Length"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(length).To(BeNumerically(">", 100*128*1000/8))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue