feat(android): Sonos/UPnP queue plays leveled URLs, rendered a track ahead (M464 #5002)
release / go (push) Successful in 2m49s
release / web (push) Successful in 2m21s
release / govulncheck (push) Successful in 25s
release / integration (push) Successful in 5m54s
release / android (push) Successful in 8m10s
release / Build signed APK (releases and dev) (push) Successful in 8m35s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 1m42s
release / Verify release artifacts (tag releases only) (push) Skipped
release / go (push) Successful in 2m49s
release / web (push) Successful in 2m21s
release / govulncheck (push) Successful in 25s
release / integration (push) Successful in 5m54s
release / android (push) Successful in 8m10s
release / Build signed APK (releases and dev) (push) Successful in 8m35s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 1m42s
release / Verify release artifacts (tag releases only) (push) Skipped
Every URL the Sonos queue loader sends is minted with level=true and the track's album-play verdict from its neighbours in the queue; the server returns the plain stream when leveling is off or changes nothing. The playing track and the one after it are rendered ahead, and each time the renderer moves on, the next is. Server: a mint no longer prerenders on its own. A queue load mints every track, which would have started an ffmpeg render per track at once. The request now carries prerender, and at most two prerenders run at a time; past that they are dropped, since a fetch renders on demand anyway. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,11 @@ type castTokenRequest struct {
|
||||
// client holding the queue knows it.
|
||||
Level bool `json:"level,omitempty"`
|
||||
AsAlbum bool `json:"asAlbum,omitempty"`
|
||||
// Prerender says the speaker will fetch this track soon: the current
|
||||
// track at a queue load, or the next one as it starts. Only those are
|
||||
// rendered ahead; a queue load mints every track and renders none of
|
||||
// the rest until the speaker asks.
|
||||
Prerender bool `json:"prerender,omitempty"`
|
||||
}
|
||||
|
||||
type castTokenResponse struct {
|
||||
@@ -138,11 +143,11 @@ func (h *handlers) handleCastStreamToken(w http.ResponseWriter, r *http.Request)
|
||||
path = leveledStreamPath(trackUUID) + leveledQuery(g, token, exp)
|
||||
mime = "audio/flac"
|
||||
leveled = true
|
||||
// The speaker fetches the URL shortly; start rendering now so
|
||||
// the fetch finds the file ready.
|
||||
h.leveled.Prerender(library.LeveledSource{
|
||||
TrackID: req.TrackID, Path: track.FilePath, DurationMs: track.DurationMs,
|
||||
}, g)
|
||||
if req.Prerender {
|
||||
h.leveled.Prerender(library.LeveledSource{
|
||||
TrackID: req.TrackID, Path: track.FilePath, DurationMs: track.DurationMs,
|
||||
}, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user