Skip to content

spclient: Specify base url for metadata requests#1528

Merged
roderickvd merged 5 commits into
librespot-org:devfrom
tdgroot:specify_metadata_base_url
Aug 11, 2025
Merged

spclient: Specify base url for metadata requests#1528
roderickvd merged 5 commits into
librespot-org:devfrom
tdgroot:specify_metadata_base_url

Conversation

@tdgroot

@tdgroot tdgroot commented Aug 7, 2025

Copy link
Copy Markdown
Contributor

This fixes #1527

Copilot AI review requested due to automatic review settings August 7, 2025 10:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds the ability to specify a custom base URL for metadata requests in the SpClient, addressing issue #1527. The change allows metadata requests to use a specific Spotify client endpoint while maintaining existing behavior for other requests.

  • Adds an optional base_url field to RequestOptions struct
  • Updates the request method to use the custom base URL when provided
  • Modifies get_metadata method to use a hardcoded Spotify client URL

Comment thread core/src/spclient.rs Outdated
Comment thread core/src/spclient.rs Outdated
@tdgroot tdgroot force-pushed the specify_metadata_base_url branch 2 times, most recently from 89b3880 to 24447ff Compare August 7, 2025 10:30
Comment thread core/src/spclient.rs Outdated

@sodagunz sodagunz left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

kingosticks
kingosticks previously approved these changes Aug 7, 2025
@BuckAMayzing

Copy link
Copy Markdown

I'm not sure how difficult the release pipeline is for this project, but this one is blocking at least two downstream apps from upgrading on their end to repair playback. @tdgroot - Is there any chance this'll be shipped soon?

@lemon-sh

lemon-sh commented Aug 7, 2025

Copy link
Copy Markdown
Contributor

I'm not sure how difficult the release pipeline is for this project, but this one is blocking at least two downstream apps from upgrading on their end to repair playback. @tdgroot - Is there any chance this'll be shipped soon?

Once this is merged, downstream developers are free to use the dev branch of librespot if they wish to. It's not easy to make a release of a project of this complexity, and keep in mind that this is a community project and nobody is getting paid for working on librespot. There's also #1521 that needs to be resolved (PR #1524) before the next release.

@photovoltex photovoltex left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a huge fan of the change itself (we might have to merge it for the current moment tho). Anyhow, is anyone encountering the 500 error even anymore? Currently it seems the 500 is resolved and it just can't find the audio files in a track anymore.

This workaround also did break during the in the middle of the day devgianlu/go-librespot#189 (comment)

Comment thread core/src/spclient.rs Outdated
@BuckAMayzing

Copy link
Copy Markdown

I'm not sure how difficult the release pipeline is for this project, but this one is blocking at least two downstream apps from upgrading on their end to repair playback. @tdgroot - Is there any chance this'll be shipped soon?

Once this is merged, downstream developers are free to use the dev branch of librespot if they wish to. It's not easy to make a release of a project of this complexity, and keep in mind that this is a community project and nobody is getting paid for working on librespot. There's also #1521 that needs to be resolved (PR #1524) before the next release.

No sweat; I was only getting a feel for viability.

@lemon-sh

lemon-sh commented Aug 7, 2025

Copy link
Copy Markdown
Contributor

I'm not a huge fan of the change itself (we might have to merge it for the current moment tho). Anyhow, is anyone encountering the 500 error even anymore? Currently it seems the 500 is resolved and it just can't find the audio files in a track anymore.

I just tried it right now, still hitting 500.

[2025-08-07T18:44:48Z ERROR librespot_playback::player] Unable to load audio item: Error { kind: Unavailable, error: StatusCode(500) }
[2025-08-07T18:44:48Z ERROR librespot_playback::player] Skipping to next track, unable to load track <SpotifyId("spotify:track:0I7OQmvpngDuiYxwyA4S54")>: ()
[2025-08-07T18:44:48Z ERROR librespot_connect::spirc] could not dispatch player event: Invalid state { context is not available. type: Default }

@kingosticks

Copy link
Copy Markdown
Contributor

An alternative we could do is to explicitly add the fallback AP to the list we get from apresolve. Our normal retry logic would then (eventually) use it. It feels like a more logical fix, but it'll perform worse than this workaround. I think what's here is a good hotfix.

@roderickvd

Copy link
Copy Markdown
Member

An alternative we could do is to explicitly add the fallback AP to the list we get from apresolve. Our normal retry logic would then (eventually) use it.

Yes, that seems robust.

It feels like a more logical fix, but it'll perform worse than this workaround. I think what's here is a good hotfix.

Generally we should mirror what the official clients do. From glancing at the fix over at go-librespot it seems that the official clients also go for https://spclient.wg.spotify.com. In that case it may not even be a hotfix... regardless, yeah, good to have this but we first need to see those HTTP/500's calming down.

@kingosticks

kingosticks commented Aug 8, 2025

Copy link
Copy Markdown
Contributor

but we first need to see those HTTP/500's calming down.

Using the 'normal' endpoints, I sometimes get 500 error responses and other times get what looks like a good response, except crucially the returned file list is empty. In the latter case, my alternative doesn't help at all; and in the other case it doesn't work that well (because the retry logic is actually to repeat each AP 3 times with total of 10 retries, so takes a couple of tracks to cycle through to the fallback. And then all spclient requests are using the fallback, which isn't necessary). The workaround provided here is better.

EDIT:
And yes, the official client just straight away uses spclient.wg.spotify.com for /metadata. It doesn't even bother trying to use the other APs first (but it still uses them for everything else). I guess they managed to break it and just hacked that fix in. Perhaps they'll revert it later on, and we won't notice that (until they break spclient.wg.spotify.com!), Either way, I think we should merge this ASAP.

@roderickvd

Copy link
Copy Markdown
Member

How is this working for everyone now? From the comments that blocking apresolve works, which will also fallback to what we’re “hacking” together here, I believe this should work also.

Then there’s #1529 and I’m wondering whether those access points would work without this hack?

@kingosticks

kingosticks commented Aug 8, 2025

Copy link
Copy Markdown
Contributor

I don't think dealer vs dealer-g2 makes any difference here, you get the same (half-broken) spclient APs either way. My comment about the ports in #1529 was wrong - sorry.

curl "https://apresolve.spotify.com/?&type=dealer&type=spclient"
{
  "dealer":["gew1-dealer.spotify.com:443","guc3-dealer.spotify.com:443","gue1-dealer.spotify.com:443","gae2-dealer.spotify.com:443"],
  "spclient":["gew1-spclient.spotify.com:443","guc3-spclient.spotify.com:443","gue1-spclient.spotify.com:443","gae2-spclient.spotify.com:443"]
}
curl "https://apresolve.spotify.com/?&type=dealer-g2&type=spclient"
{
"dealer-g2":["gew1-dealer.g2.spotify.com:443","guc3-dealer.g2.spotify.com:443","gew4-dealer.g2.spotify.com:443","gae2-dealer.g2.spotify.com:443"],
"spclient":["gew1-spclient.spotify.com:443","guc3-spclient.spotify.com:443","gue1-spclient.spotify.com:443","gae2-spclient.spotify.com:443"]
}

@kingosticks

Copy link
Copy Markdown
Contributor

Also, blocking apresolve behaves slightly differently to the workaround here. Blocking it forces all spclient access to go through the fallback, instead of just /metatdata endpoint. Although the fallback does appear to work with all endpoints we use, I found at least one endpoint that doesn't work with the fallback: /storage-resolve/v2/files/audio/interactive/2 (used by Spotify's client, while we successfully use /storage-resolve/files/audio/interactive instead).

@roderickvd

Copy link
Copy Markdown
Member

OK. @tdgroot could you get back on @photovoltex's review comment and change those RequestOptions into a const? This and a changelog entry and we'd be good to merge.

@tdgroot

tdgroot commented Aug 8, 2025

Copy link
Copy Markdown
Contributor Author

@roderickvd Sure, I'll try to find some time tomorrow morning and make the requested changes!

@tdgroot

tdgroot commented Aug 9, 2025

Copy link
Copy Markdown
Contributor Author

@roderickvd branch has been updated, LMK what you think :)

@roderickvd

Copy link
Copy Markdown
Member

Yes, looks good to me, thanks. @photovoltex you agree your review comment was resolved as you wanted?

@photovoltex

Copy link
Copy Markdown
Member

Yeah, seems good to me. Even tho a changelog entry is still missing.

@tdgroot

tdgroot commented Aug 9, 2025

Copy link
Copy Markdown
Contributor Author

@photovoltex @roderickvd added changelog entry

@roderickvd

Copy link
Copy Markdown
Member

Your changelog entry specifies [core] but it should be [spclient], right?

After resolving the conflict, would you also help out and touch up this entry:

[core] stream_from_cdn now accepts the URL as a &str instead of CdnUrl (breaking)

⬇️ change to:

[spclient] stream_from_cdn now takes the URL as TryInto<Uri> instead of CdnUrl (breaking)

Then when I find some time and camping internet access I will help out out a release. 🥳

@roderickvd

Copy link
Copy Markdown
Member

Kudos for the quick reverse engineering!

In the end we want to provide a working, stable Spotify library (and reference player) to the community. A lot of users and distributions out there are depending on us to get it fixed. (With caveats of voluntary open source work and all.)

What would be the cons of releasing this “hotfix” in v0.7 these days (with a whole bag of other goodies from the past months) and then being open to a v0.7.1 or v0.8 quickly after? Gives us time to vet @photovoltex’s new code and service the community.

@photovoltex

Copy link
Copy Markdown
Member

Sounds good to me. A quicker solution is probably better for now than to wait another day. Will create a PR for it later down the line then.

@kingosticks

kingosticks commented Aug 10, 2025

Copy link
Copy Markdown
Contributor

Hotfix asap sounds good to me too. You could still put the extended-metadata change into dev almost straight afterwards, and get confidence/exposure on that without having to rush.

@wknightbor

Copy link
Copy Markdown

Hi all,
Compiled with 'cargo build --release --features alsa-backend' on Fedora 40 686.
No more connection errors, but there is only noise instead of sound.
0.60 worked without such issue.
Thanks

@kingosticks

Copy link
Copy Markdown
Contributor

Hi all,
Compiled with 'cargo build --release --features alsa-backend' on Fedora 40 686.
No more connection errors, but there is only noise instead of sound.
0.60 worked without such issue.
Thanks

Whatever that is, it isn't related to this issue. Can you open a new issue for your problem. It would be even better if you can git bisect to find the commit that causes the issue, if any.

@roderickvd

Copy link
Copy Markdown
Member

@tdgroot don’t want to rush you, so just let us know when you’ve got time to resolve the merge conflict in the changelog, or would like us to do it for you.

This will allocate less strings and makes it possible to have const
request option values.

Also document why the metadata base url workaround is needed.
@tdgroot tdgroot force-pushed the specify_metadata_base_url branch from bcfc88d to 8dfc619 Compare August 11, 2025 10:39
@tdgroot

tdgroot commented Aug 11, 2025

Copy link
Copy Markdown
Contributor Author

@roderickvd finally found some time. Just rebased my branch on dev

@roderickvd roderickvd merged commit ba3d501 into librespot-org:dev Aug 11, 2025
13 checks passed
@roderickvd

Copy link
Copy Markdown
Member

Awesome thanks. Letting this cook for a few hours (and when I have enough time) before we push a release.

@kingosticks

Copy link
Copy Markdown
Contributor

Brilliant, thank you @tdgroot.

@Jimi-Ultra

Copy link
Copy Markdown

Awesome thanks. Letting this cook for a few hours (and when I have enough time) before we push a release.

hi there,

sorry for asking. but i am using mopidy with the spotify-extension in a docker container.
based on my dependencies (docker-image > mopidy-spotify > librespot) it would be nice if the whole chain would get an update.

so all in all is there going to be a release of a new librespot version soon?
Or should i try to work with the adjustments of the merge, what is not in the latest release of librespot in the moment?

best regards

@roderickvd

Copy link
Copy Markdown
Member

I am out for a few days now, and plan to do a release after.

@kingosticks

kingosticks commented Aug 17, 2025

Copy link
Copy Markdown
Contributor

Awesome thanks. Letting this cook for a few hours (and when I have enough time) before we push a release.

hi there,

sorry for asking. but i am using mopidy with the spotify-extension in a docker container.
based on my dependencies (docker-image > mopidy-spotify > librespot) it would be nice if the whole chain would get an update.

so all in all is there going to be a release of a new librespot version soon?
Or should i try to work with the adjustments of the merge, what is not in the latest release of librespot in the moment?

best regards

Everything to fix the recent issues is checked into the dev branch, you can look at the recently method PRs to see the other fix went in. So using the latest dev branch will work, if building that is feasible for you, until the release is cut.

For the specific Mopidy-Spotify usecase, you can grab a fixed binary from
https://github.com/kingosticks/gst-plugins-rs-build/releases/tag/gst-plugin-spotify_0.15.0-alpha.1-2 or build one yourself from the details provided there. If you want further specific Mopidy-Spotify help then feel free to post at Mopidy's support channels.

paulfariello pushed a commit to paulfariello/librespot that referenced this pull request Sep 23, 2025
CreatorMetaSky pushed a commit to StreamMediaSpace/librespot-zig that referenced this pull request Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Getting status code 500s since Ads API sunset