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

Implements PKCE Authorization to enable access to HiRess files. #221

Merged
merged 25 commits into from
Jan 27, 2024
Merged

Implements PKCE Authorization to enable access to HiRess files. #221

merged 25 commits into from
Jan 27, 2024

Conversation

exislow
Copy link
Contributor

@exislow exislow commented Jan 23, 2024

This is a straight forward user interactions based PKCE authorization implementation, which fixes #188 and #217.

You simply use login_pkce() and follow the instructions.

Feel free to comment and / or merge.

Due to lack of time no tests have been implemented but comments / doc strings are in place.

@exislow exislow mentioned this pull request Jan 23, 2024
@tehkillerbee
Copy link
Collaborator

Thanks, will look at this ASAP, need to test with a HiFi enabled account.

@exislow
Copy link
Contributor Author

exislow commented Jan 23, 2024

Thanks, will look at this ASAP, need to test with a HiFi enabled account.

Let me know if you need any help on this.

@exislow
Copy link
Contributor Author

exislow commented Jan 25, 2024

@tehkillerbee: Any updates on this?

fn_print(url_login)

# Get redirect URL from user input.
url_redirect: str = input("Paste 'Ooops' page URL here and press <ENTER>:")
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a way to get this url programmatically rather than require the copy paste?

If not, can we then make other called functions non-private?

Copy link
Contributor

Choose a reason for hiding this comment

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

Didn't realise that my pending comment needed to actually be set as a review, also, did not necessarily mean to review, rather just leave a comment.
I actually mean to submit this days ago. Apologies for taking so long to realise my mistake

@tehkillerbee
Copy link
Collaborator

@tehkillerbee: Any updates on this?

Sorry, I have been occupied by other responsibilities. I will take a look at it no later than this weekend.

@tehkillerbee
Copy link
Collaborator

tehkillerbee commented Jan 26, 2024

@exislow I got a chance testing this today with a HiFi enabled account. However, I get requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url .. when I call get_url() on a track, no matter what I do and irrespective of the Quality configured.

@exislow
Copy link
Contributor Author

exislow commented Jan 26, 2024

@exislow I got a chance testing this today with a HiFi enabled account. However, I get requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url .. when I call get_url() on a track, no matter what I do and irrespective of the Quality configured.

Just double checked this. I cannot re-produce it. Whether with a PKCE nor with a OAuth authorized token. Can you please more verbose? I need the full error log and the TIDAL link to the track you are working with. In my case get_url() on a track works as expected!

@tehkillerbee
Copy link
Collaborator

tehkillerbee commented Jan 26, 2024

@exislow I got a chance testing this today with a HiFi enabled account. However, I get requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url .. when I call get_url() on a track, no matter what I do and irrespective of the Quality configured.

Just double checked this. I cannot re-produce it. Whether with a PKCE nor with a OAuth authorized token. Can you please more verbose? I need the full error log and the TIDAL link to the track you are working with. In my case get_url() on a track works as expected!

In the response I get "401 Asset is not ready for playback"

This issue only occurs with PKCE not with normal OAuth.

Which track/album have you tested with? I did try a few, at least one of them should have HiRes

import tidalapi
from tidalapi import Quality

session = tidalapi.Session()
# Will run until you visit the printed url and link your account
session.login_pkce()

# Override the required playback quality, if necessary
# Note: Set the quality according to your subscription.
# Normal: Quality.low_320k
# HiFi: Quality.high_lossless
# HiFi+ Quality.hi_res_lossless
session.audio_quality = Quality.hi_res_lossless.value

album = session.album(110827651) # Let's Rock // The Black Keys
tracks = album.tracks()
# list album tracks
for track in tracks:
    print(track.name)
    print(track.get_url())
    for artist in track.artists:
        print(' by: ', artist.name)

@tehkillerbee
Copy link
Collaborator

tehkillerbee commented Jan 26, 2024

Sorry for closing this PR, that was an accident and I have reopened it. Anyways see my notes below after doing some testing:

@exislow I got a chance testing this today with a HiFi enabled account. However, I get requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url .. when I call get_url() on a track, no matter what I do and irrespective of the Quality configured.

Just double checked this. I cannot re-produce it. Whether with a PKCE nor with a OAuth authorized token. Can you please more verbose? I need the full error log and the TIDAL link to the track you are working with. In my case get_url() on a track works as expected!

When a streaming link is requested, no Auth error is given so that part works fine. But it does NOT work with direct URL on my side, unless I switch back to standard Oauth.

I think this just confirms what we already know from the tidal2 documentation lists, i.e. MPEG-Dash is allowed but normal https is not: https://github.com/arnesongit/plugin.audio.tidal2

@exislow
Copy link
Contributor Author

exislow commented Jan 26, 2024

Sorry for closing this PR, that was an accident and I have reopened it. Anyways see my notes below after doing some testing:

@exislow I got a chance testing this today with a HiFi enabled account. However, I get requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url .. when I call get_url() on a track, no matter what I do and irrespective of the Quality configured.

Just double checked this. I cannot re-produce it. Whether with a PKCE nor with a OAuth authorized token. Can you please more verbose? I need the full error log and the TIDAL link to the track you are working with. In my case get_url() on a track works as expected!

When a streaming link is requested, no Auth error is given so that part works fine. But it does NOT work with direct URL on my side, unless I switch back to standard Oauth.

I think this just confirms what we already know from the tidal2 documentation lists, i.e. MPEG-Dash is allowed but normal https is not: https://github.com/arnesongit/plugin.audio.tidal2

Ohh sorry, I thought this was already clear: HiRes ONLY works with MPEG-DASH. This is why have built an MPEG-DASH parses for https://github.com/exislow/tidal-dl-ng/blob/a348909897b8a4453ec0b8764f564a4970b6e238/tidal_dl_ng/download.py#L390-L451

By the way, this works:

import tidalapi
from tidalapi import Quality

session = tidalapi.Session()
# Will run until you visit the printed url and link your account
session.login_pkce()

# Override the required playback quality, if necessary
# Note: Set the quality according to your subscription.
# Normal: Quality.low_320k
# HiFi: Quality.high_lossless
# HiFi+ Quality.hi_res_lossless
session.audio_quality = Quality.hi_res_lossless

album = session.album(110827651) # Let's Rock // The Black Keys
tracks = album.tracks()
# list album tracks
for track in tracks:
    print(track.name)
    # Only MPEG-DASH works for HiRes
    #print(track.get_url())
    print(track.stream())
    for artist in track.artists:
        print(' by: ', artist.name)

# TOTO - Rosana https://tidal.com/browse/track/542179
media = session.track(542179)
print(media.stream())

@tehkillerbee
Copy link
Collaborator

tehkillerbee commented Jan 26, 2024

Ohh sorry, I thought this was already clear: HiRes ONLY works with MPEG-DASH.

Ok, you mentioned that you managed to download a HiRes FLAC file in an earlier comment so I assumed get_url() was used. And you also mentioned using get_url() successfully in the comments in this PR so I thought I was doing something wrong. But good to know it works as expected with MPEG-DASH.

I noticed tidal2 uses a similar approach to parse the MPEG-DASH stream so it can be passed on to ffmpeg. I'll probably look into implementing something similar, either directly in tidalapi or in the projects relying on it for streaming (mopidy-tidal)

@exislow
Copy link
Contributor Author

exislow commented Jan 26, 2024

Oh I actually never mentioned get_url() nor used it. Sorry for the confusion.

@exislow
Copy link
Contributor Author

exislow commented Jan 27, 2024

How can I help to get this PR accepted and create a new release of tidalapi?

@tehkillerbee
Copy link
Collaborator

tehkillerbee commented Jan 27, 2024

@exislow You'd need to rebase to master, then we can merge it.

Regarding next release, I was planning to add MPEG-DASH parsing as well, similar to how it is done with tidal2.

EDIT: On second thought, I think we'll skip that for now so v0.7.4 can be released immediately after merging this PR, in case you need it right away.

dependabot bot and others added 3 commits January 27, 2024 16:46
@exislow
Copy link
Contributor Author

exislow commented Jan 27, 2024

@tehkillerbee: Rebase is done.

Regarding the release: When are you going to implement the MPEG-DASH parser? And why it is not possible to have two releases: One now and another after the parser is implemented? Release don't cost anything, right? Would be happy if you could release this ASAP. A lot of user waiting for HiRes support for a long time already. Thanks :-)

@tehkillerbee
Copy link
Collaborator

tehkillerbee commented Jan 27, 2024

Regarding the release: When are you going to implement the MPEG-DASH parser?

See my comment above. :-)

I think we'll stick to PKCE login for now and worry about MPEG-DASH later and/or leave it up to the users to implement in their own libraries so there is nothing stopping us to release v0.7.4

@tehkillerbee tehkillerbee merged commit 4a08d05 into tamland:master Jan 27, 2024
4 of 5 checks passed
@exislow
Copy link
Contributor Author

exislow commented Jan 27, 2024

Ohh sorry, haven't seen the edited part, since I was only checking the mail notification. Thank you for your effort!

self.process_auth_token(json)

# Swap the client_id and secret
#self.client_enable_hires()
Copy link
Collaborator

Choose a reason for hiding this comment

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

@exislow Any reason this was not enabled in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It works with and without this. To avoid a possible break of existing functions I have decided to comment it out. But if you are sure, that all tests are running correct with an OAuth2 token you could also enable line 494. If you like I can also get you a pull request for this. Just let me know, how you decide.

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.

Support for 24bit 192kHz
3 participants