navidrome/server/subsonic
Deluan Quintão 95f67d2c4e
fix(share): reuse cached transcodes for share streams and zip downloads (#6262)
* fix(share): reuse cached transcodes when streaming from share links

Public share streams built the stream request with only the share's format
and bit rate, leaving sample rate, bit depth and channels at zero. Regular
playback resolves those through the transcode decider (e.g. 48000 Hz for
Opus), and they are part of the transcoding cache key, so a track already
transcoded during normal playback was transcoded again into a separate,
identical cache entry when played through a share link.

The public router now resolves share stream requests with the same
TranscodeDecider.ResolveRequest used by the Subsonic stream endpoint, so
both paths produce the same request and share cache entries.

Fixes #6261

* fix(archiver): reuse cached transcodes when zipping downloads

Zip downloads (album, artist, playlist and share) built the stream request
with only the format and bit rate, leaving sample rate, bit depth and
channels at zero. Those are part of the transcoding cache key, so a track
already transcoded for playback was transcoded again into a separate cache
entry when downloaded in a zip, and vice versa.

The archiver now resolves each request with TranscodeDecider.ResolveRequest,
the same as single-song downloads and streams. This also applies the
decider's defaults, so a zip requested without a bit rate uses the target
format's default bit rate instead of leaving it to ffmpeg.

* fix(archiver): name zip entries after the resolved transcoding format

The transcode decider can pick a different format than the one requested
(for example a player's forced transcoding, or a fallback to the default
downsampling format when the requested one can't be produced). Zip entry
names and the playlist M3U were still built from the requested format, so
an entry could end in .mp3 or .flac while holding Opus data.

Each track's request is now resolved before its entry name is built, and
the name uses the resolved format.
2026-10-03 08:58:54 -07:00
..
e2e fix(share): reuse cached transcodes for share streams and zip downloads (#6262) 2026-10-03 08:58:54 -07:00
responses feat(subsonic): OpenSubsonic API key authentication (#6219) 2026-09-27 21:56:58 -04:00
album_lists.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
album_lists_test.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
api.go feat(subsonic): OpenSubsonic API key authentication (#6219) 2026-09-27 21:56:58 -04:00
api_suite_test.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
api_test.go fix(share): enforce per-user ownership on share reads 2026-06-05 15:50:59 -04:00
auth_limiter.go fix(subsonic): rate limit failed authentication attempts (#6185) 2026-09-20 22:02:23 -04:00
auth_limiter_test.go fix(subsonic): rate limit failed authentication attempts (#6185) 2026-09-20 22:02:23 -04:00
bookmarks.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
bookmarks_test.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
browsing.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
browsing_test.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
helpers.go fix(archiver): give same-named albums their own folder in artist zips (#6225) 2026-09-25 16:19:30 -04:00
helpers_test.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
jukebox.go refactor(server): drop redundant error return from req.Strings parsing (#5812) 2026-07-18 19:30:04 -04:00
library_scanning.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
library_scanning_test.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
lyrics.go fix(subsonic): emit agent-specific cueLine values (#5679) 2026-06-28 18:14:18 -04:00
lyrics_test.go fix(scanner): stop logging expected lyrics sniff misses as warnings (#5702) 2026-07-02 09:46:57 -04:00
media_annotation.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
media_annotation_test.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
media_retrieval.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
media_retrieval_test.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
middlewares.go feat(subsonic): OpenSubsonic API key authentication (#6219) 2026-09-27 21:56:58 -04:00
middlewares_test.go feat(subsonic): OpenSubsonic API key authentication (#6219) 2026-09-27 21:56:58 -04:00
opensubsonic.go feat(subsonic): OpenSubsonic API key authentication (#6219) 2026-09-27 21:56:58 -04:00
opensubsonic_test.go feat(subsonic): OpenSubsonic API key authentication (#6219) 2026-09-27 21:56:58 -04:00
playlists.go fix(subsonic): update the playlist changed timestamp when renaming a smart playlist (#6082) 2026-09-03 16:07:53 -04:00
playlists_test.go fix(subsonic): update the playlist changed timestamp when renaming a smart playlist (#6082) 2026-09-03 16:07:53 -04:00
radio.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
radio_test.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
searching.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
searching_test.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
sharing.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
sonic_similarity.go feat(subsonic): add sonicSimilarity extension as plugin capability (#5419) 2026-04-27 17:50:09 -04:00
stream.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
system.go feat(subsonic): OpenSubsonic API key authentication (#6219) 2026-09-27 21:56:58 -04:00
system_test.go feat(subsonic): OpenSubsonic API key authentication (#6219) 2026-09-27 21:56:58 -04:00
transcode.go refactor(persistence): stateless repositories with per-call context (#6149) 2026-09-25 18:06:10 -04:00
transcode_test.go fix(jellyfin): match Jellyfin on login SessionInfo, item types and universal streams (#6161) 2026-09-17 23:48:39 -04:00
users.go refactor: multiple syntax updates for Go 1.26 2026-05-19 18:02:36 -03:00
users_test.go refactor: rename EnableCoverArtUpload to EnableArtworkUpload 2026-03-27 19:33:46 -04:00