Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMPORTANT] SpotifyLocalAPI not working #254

Closed
StepIg opened this issue Jul 19, 2018 · 47 comments
Labels

Comments

@StepIg
Copy link

@StepIg StepIg commented Jul 19, 2018

With the last version, has worked one time, but no more. Play and pause doesn't work.

@StepIg

This comment has been minimized.

Copy link
Author

@StepIg StepIg commented Jul 19, 2018

Also on Example project, once connected to Spotify, doesn't receive Title, Artist, Album.
Previous and Skip buttons are working ok.
Spotify version 1.0.85.257.gOf8531bd

@hng0vrboy

This comment has been minimized.

Copy link

@hng0vrboy hng0vrboy commented Jul 19, 2018

I can confirm that with the latest Spotify release and the latest API release, Play does not work anymore.

@phICE9

This comment has been minimized.

Copy link

@phICE9 phICE9 commented Jul 19, 2018

I am also having problems with play or PlayUrl function

@sakertooth

This comment has been minimized.

Copy link

@sakertooth sakertooth commented Jul 19, 2018

I'm having the same issue

@TippeTiTop

This comment has been minimized.

Copy link

@TippeTiTop TippeTiTop commented Jul 19, 2018

same here
play, pause etc. doesn't work
yesterday i was able to fix it with the solution provided in #253
[Spotify version 1.0.85.257.gOf8531bd]

@Inzaniity

This comment has been minimized.

Copy link

@Inzaniity Inzaniity commented Jul 19, 2018

LocalAPI Seems to broken. GetStatus() reuturns always Null. It hast been down since yesterday evening.

@renatopda8

This comment has been minimized.

Copy link
Contributor

@renatopda8 renatopda8 commented Jul 19, 2018

The OAuth key request to "http://open.spotify.com/token" is always returning an invalid token.

@RobertRoxenhall

This comment has been minimized.

Copy link

@RobertRoxenhall RobertRoxenhall commented Jul 19, 2018

Yeah same issue here. Can we get an updated version again? :)

@JohnnyCrazy

This comment has been minimized.

Copy link
Owner

@JohnnyCrazy JohnnyCrazy commented Jul 19, 2018

Uhhhh, gimme some minutes here, seems like they disabled the OAuth Token, which maybe means local API is dead. Will report back once I find out more...

@JohnnyCrazy

This comment has been minimized.

Copy link
Owner

@JohnnyCrazy JohnnyCrazy commented Jul 19, 2018

Well, it seems like they either disabled the Token generation, or sending a User-Agent with the spotify version is not enough anymore. Independently, there is nothing we can do atm because it's an unofficial API and they can just introduce some secret header field which we could not find in ages.

Also, with their changes to the WebAPI which now also allows managing devices & streaming, it's reasonable that they disabled the local API. It was mainly used for the old web-player which is now completely based on the new WebAPI.

There is not much we can do at the current state...

@RobertRoxenhall

This comment has been minimized.

Copy link

@RobertRoxenhall RobertRoxenhall commented Jul 19, 2018

No... just no. I have this (well had actually) working solution and we're going live tomorrow morning and then I need to be able to control Spotify from a tablet (among other things).

Well, guess I'll have to rebuild it to use the web-api and control the playback that way. Guess I should see it from the bright side. Now atleast I have the entire night to fix it. Had it happened tomorrow I'd be ******.

Thank you for the quick update! (I was hoping someone at Spotify accidentally uploaded a test version of their token generator and would fix it shortly)

@StepIg

This comment has been minimized.

Copy link
Author

@StepIg StepIg commented Jul 19, 2018

Why skip and previous still working?

@JohnnyCrazy

This comment has been minimized.

Copy link
Owner

@JohnnyCrazy JohnnyCrazy commented Jul 19, 2018

@StepIg Because they emulate media keys, no spotify api involved

@hng0vrboy

This comment has been minimized.

Copy link

@hng0vrboy hng0vrboy commented Jul 19, 2018

So by using the web api, we can control and play songs on the spotify instance running on a windows machine? (So basically the same thing that the LocalAPI did when we called the play method?)

@StepIg

This comment has been minimized.

Copy link
Author

@StepIg StepIg commented Jul 19, 2018

@JohnnyCrazy Because they emulate media keys, no spotify api involved
Is then possible to use same method for play and pause keys?

@rollersteaam

This comment has been minimized.

Copy link
Contributor

@rollersteaam rollersteaam commented Jul 19, 2018

@StepIg It definitely would be, but it doesn't sound viable anyway considering you can't even request song URIs to play now. It's possible that you could use the Play and Pause media keys solution combined with the web API approach (if it lets you play URIs through it) to control Spotify Desktop client playback.

@rollersteaam

This comment has been minimized.

Copy link
Contributor

@rollersteaam rollersteaam commented Jul 19, 2018

So my jaw just dropped after spending about 5 hours finding this solution to the problem and actually hearing music go through my headphones when I clicked my program's play button.

Assuming we can no longer use the local API (I hope this is temporary), I've made a new class that implements the same interface as my class that used the SpotifyLocalAPI. This new class uses SpotifyWebAPI.

On initialisation we need to request authentication from the Spotify API. Normally this would be hard or tedious to do, except @JohnnyCrazy has already implemented a way in his SpotifyWebAPI example inside the 'Example' folder in this repository.

This is a small adaptation of his example into an async function that you can basically just copy and paste into your project for initialisation of your new web API class.

// The new using statements...
using SpotifyAPI.Web;
using SpotifyAPI.Web.Auth;
using SpotifyAPI.Web.Enums;
SpotifyWebAPI spotify;

async void ResolveAuth()
{
    WebAPIFactory webApiFactory = new WebAPIFactory(
        "http://localhost",
        8000,
// Spotify API Client ID goes here, you SHOULD get your own at https://developer.spotify.com/dashboard/

// It should be noted, "http://localhost:8000" must be whitelisted in your dashboard after getting your own client key
        "26d287105e31491889f3cd293d85bfea",
        Scope.UserReadPrivate | Scope.UserReadEmail | Scope.PlaylistReadPrivate | Scope.UserLibraryRead |
        Scope.UserReadPrivate | Scope.UserFollowRead | Scope.UserReadBirthdate | Scope.UserTopRead | Scope.PlaylistReadCollaborative |
        Scope.UserReadRecentlyPlayed | Scope.UserReadPlaybackState | Scope.UserModifyPlaybackState,
        new SpotifyAPI.ProxyConfig());
 
    try
    {
        spotify = await webApiFactory.GetWebApi();
    }
    catch (Exception ex)
    {
        throw;
    }
 
    if (spotify == null)
        return;
}

Now for when we want to play a song, we have to use the functions in SpotifyWebAPI. Intellisense will be able to show you a good amount of information, but for playing a specific URI, here is an example.

        public void Play()
        {
            // Spotify ResumePlayback has a huge amount of parameters.

            // By using "uris: " and defining a new list of strings, we are specifying that we want to give only the
            // parameter "uris" input, and nothing else (because all parameters here are optional.)

            // the parameter uris is simple, it is a list of song uri's you want to play.

            // Offset has to be passed in here (although I pass in its default optional parameter value) as
            // the compiler won't be able to differentiate between the two different overloads for the method ResumePlayback.

            // For many functions in the web API, they will want 'contexts' and 'device ids'. These are basically all optional
            // so adapting these functions to replace your local API is probably doable.
            spotify.ResumePlayback(uris: new List<string> { "spotify:track:0cWPe8mPRyLMxxe94eRVzs" }, offset: "");
        }

If you read the comments you'll understand that I tried to explain some of the web API's jargon that you may have not read up on because you've relied on the local API for a while, so to follow up on my comments, here is an example of how to PAUSE playback, just to show how easy it is.

        public void Pause()
        {
            spotify.PausePlayback();
        }

But intellisense shows you can also pass in a device ID string. Completely optional, as shown in the method's summary.

So what if I want to just resume playback instead of play a new song?

        public void Play()
        {
            // Again, we have to state offset's parameter value so it differentiates between the two overloads of the method.
            // Just pass in an empty string, as that is its default optional parameter value.
            spotify.ResumePlayback(offset: "");
        }
@JohnnyCrazy

This comment has been minimized.

Copy link
Owner

@JohnnyCrazy JohnnyCrazy commented Jul 19, 2018

Nice writeup @rollersteaam 👍

2 notes:

  • spotify = await webApiFactory.GetWebApi(); will get you a ready-to-use OAuth token, but sadly it's only valid for 30 minutes, and you cant refresh it. There are some alternatives here
  • I don't think it's temporary, this would be weird for spotify since they, most of the time, are good at deploying stuff. But let's see 😅
@StepIg

This comment has been minimized.

Copy link
Author

@StepIg StepIg commented Jul 19, 2018

Then, local API is dead like we knew it yesterday?

@Gruhlum

This comment has been minimized.

Copy link
Contributor

@Gruhlum Gruhlum commented Jul 19, 2018

@rollersteaam I tried PausePlayback() and ResumePlayback() but both gave me error "403 - Not available for the current user"
I have Scope.UserReadPlaybackState and Scope.UserModifyPlaybackState.

Edit: Maybe it's because I don't have premium?

And shouldn't the offset for:
spotify.ResumePlayback(offset: "");
be an int and not string?

@JohnnyCrazy JohnnyCrazy changed the title Pause and play doesn't work [IMPORTANT] SpotifyLocalAPI not working Jul 19, 2018
@rollersteaam

This comment has been minimized.

Copy link
Contributor

@rollersteaam rollersteaam commented Jul 19, 2018

@Gruhlum It's probably more coherent to state offset as 0 instead of as an empty string, but because both work I'm assuming it treats an empty string as having no offset anyway. I'm not sure how a string could define some form of offset but who knows

As for your problem, I didn't have the issue and I have Spotify premium, so it's possible, although it wouldn't make much sense since web players for Spotify should allow free users to still interact and play specific tracks. However, IIRC from the free version of Spotify on mobile, you cannot play specific tracks and are forced to play through "shuffle play," meaning if your device ID links to a mobile I suppose it's not going to let you. Again, why would it cause that issue on PausePlayback() though?

@rollersteaam

This comment has been minimized.

Copy link
Contributor

@rollersteaam rollersteaam commented Jul 19, 2018

@JohnnyCrazy Thank you for linking alternatives to the authentication solution. Creating some form of server could be a really interesting project to tackle so I can get better with that sort of stuff, but it seems potentially tedious. Considering authentication for a user takes only a second with the trade-off of a web browser showing, it's not disastrous for my project, and since I'm mainly making it for myself I guess I don't really care.

Here's to hoping I can actually code a new wrapper for the web API. Thanks Spotify.

@h-philip

This comment has been minimized.

Copy link
Contributor

@h-philip h-philip commented Jul 19, 2018

@StepIg

This comment has been minimized.

Copy link
Author

@StepIg StepIg commented Jul 19, 2018

With permium all continues working?

@StepIg

This comment has been minimized.

Copy link
Author

@StepIg StepIg commented Jul 20, 2018

@DanielGilbert Done all regarding what playing, elapsed time, etc...
Continue looking for play a list and also for make auth without show the browser

both SOLVED

@JohnnyCrazy

This comment has been minimized.

Copy link
Owner

@JohnnyCrazy JohnnyCrazy commented Jul 20, 2018

Okay, seems like it's official.

I will think about the future of the project. Probably it will focus on the web API. But I also like the idea of modifying the Spotify client files to make a custom websocket helper. I will keep you updated

@jscholes

This comment has been minimized.

Copy link

@jscholes jscholes commented Jul 21, 2018

can connect using webAPI, but do not accept commands until play is pressed on spotify. After this, commands are accepted by spotify

Try explicitly transferring playback to the desktop client to wake it up (docs here).

@JohnnyCrazy

This comment has been minimized.

Copy link
Owner

@JohnnyCrazy JohnnyCrazy commented Jul 26, 2018

Okay, small plan for the future:

  1. Remove the local API from this project and make sure we're getting the Web API .NET Standard ready. This was a highly requested feature and without the local API it should be done quite quick.

  2. Remove the current Authentication stuff I build around spotify flows and extract it into a new project SpotifyAPI.Butler with a better API, and maybe even cross platform support.
    I already had a look at a cross platform webserver which looks promising. For the API, I thought of the following:

var butler = new SpotifyAPIButler(clientID, clientSecret, 3000);
// or for short lived tokens
var butler = new SpotifyAPIButler(clientID, 3000);

butler.OnAuthorizationCode+= OnAuthorizationCode; // (token, refreshToken)
butler.OnImplicitGrant += OnImplicitGrant; // (token)

butler.Start() // open users browser
var newToken = butler.RefreshToken(refreshToken) // maybe not even necessary

The API maybe will stay close to the old one, but definitely with better error handling and cross platform support.

And generally speaking: There is no secure way of using the Spotify Web API with long lasting tokens on the client side without a backend. The only option is: Every user has to create a developer application themselves and add the necessary clientId and clientSecret into the Desktop App. That's the only secure way.

@jscholes

This comment has been minimized.

Copy link

@jscholes jscholes commented Jul 27, 2018

You're building an abstraction and my gut feeling is that someone should be able to gauge what it's for at a first glance of its name. Unless I'm missing something the word butler doesn't relate to authorization in any way. It's your library though - I only came here for discussion of the locally-hosted Spotify API which I used in one of my own Python-based projects ;)

@StepIg

This comment has been minimized.

Copy link
Author

@StepIg StepIg commented Jul 27, 2018

Now SpotifyLocalAPI.RunSpotify() doesn't run on Windows 10.

@xTheChosen0ne

This comment has been minimized.

Copy link

@xTheChosen0ne xTheChosen0ne commented Aug 8, 2018

Dat is jetzt natürlich nicht so geil 😆

@mmartain

This comment has been minimized.

Copy link

@mmartain mmartain commented Aug 9, 2018

Hope this can get fixed. I am using the events from the local player. Any ideas for a workaround?

@StepIg

This comment has been minimized.

Copy link
Author

@StepIg StepIg commented Aug 9, 2018

@mmartain
I've moved my code from events to timers taking needed info about tracks time, etc... from the webAPI. And all is ok.

@JohnnyCrazy

This comment has been minimized.

Copy link
Owner

@JohnnyCrazy JohnnyCrazy commented Aug 9, 2018

There will be no fix. The local API will be removed with the next commit, the project will have the following structure:

  • SpotifyAPI.Web (NuGet Package)
  • SpotifyAPI.Web.Auth (NuGet Package)
  • SpotifyAPI.Web.Example
  • SpotifyAPI.Web.Tests

I'm currently reworking SpotifyAPI.Web.Auth with a better internal HTTP Server and an additional "auth-method", where users have to register their own spotify dev application. This will be the only "secure" authentication method.

@JohnnyCrazy

This comment has been minimized.

Copy link
Owner

@JohnnyCrazy JohnnyCrazy commented Aug 24, 2018

Hi everyone,

3.0.0 has been published and the local API is not a part of this project anymore (expect the docs). I tried some approaches, like hooking into the spotify clients JS code, but in the end these are all hacky solutions. The WebAPI is really powerful and I think most of the functionalities should be portable.

Please visit #276 for a short changelog and if you have any arising questions, feel free to post them there! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.