tamland / python-tidal

Python API for TIDAL music streaming service
GNU Lesser General Public License v3.0
413 stars 110 forks source link

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

Closed exislow closed 9 months ago

exislow commented 10 months ago

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.

tehkillerbee commented 10 months ago

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

exislow commented 10 months ago

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 commented 9 months ago

@tehkillerbee: Any updates on this?

tehkillerbee commented 9 months ago

@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 commented 9 months ago

@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 commented 9 months ago

@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 commented 9 months ago

@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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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

exislow commented 9 months ago

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

tehkillerbee commented 9 months ago

@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.

exislow commented 9 months ago

@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 commented 9 months ago

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

exislow commented 9 months ago

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