bbye98 / minim

A collection of music service (iTunes, Qobuz, Spotify, TIDAL) APIs for media information retrieval and semi-automated music tagging.
https://bbye98.github.io/minim/
GNU General Public License v3.0
46 stars 4 forks source link

Is it possible to get preview for tracks in Tidal service? #12

Closed project-owner closed 7 months ago

project-owner commented 7 months ago

Is it possible to get preview for tracks in Tidal service? I was not able to get it with PrivateAPI.

Thanks!

bbye98 commented 7 months ago

Yes, using either PrivateAPI.get_track_playback_info(..., asset_presentation="PREVIEW") or PrivateAPI.get_track_stream(..., asset_presentation="PREVIEW").

project-owner commented 7 months ago

It throws exception:

        self.private_api = PrivateAPI(client_id=client_id, client_secret=client_secret, save=False)
        d = self.private_api.get_track_playback_info(55391659, audio_quality="LOW", asset_presentation="PREVIEW")
        print(d)

Exception has occurred: RuntimeError
401.6004 OpenApi clients can not access this endpoint
  File "C:\github\minim\src\minim\tidal.py", line 2288, in _request
    raise RuntimeError(emsg)
  File "C:\github\minim\src\minim\tidal.py", line 2198, in _get_json
    return self._request("get", url, **kwargs).json()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\github\minim\src\minim\tidal.py", line 7280, in get_track_playback_info
    return self._get_json(
           ^^^^^^^^^^^^^^^
  File "C:\github\minim-client\tidalservice.py", line 74, in __init__
    d = self.private_api.get_track_playback_info(55391659, audio_quality="LOW", asset_presentation="PREVIEW")
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
project-owner commented 7 months ago

I need a link/URL to a preview stream. All other services (iTunes, Qobuz, Spotify) provide that.

bbye98 commented 7 months ago

From your error message, it looks like you're trying to use client credentials from the new open TIDAL API with the private TIDAL API. That's likely the culprit.

Additionally, I believe that even with valid client credentials, the TIDAL account must have a streaming plan or you will get a Asset is not ready for playback error. This is likely because TIDAL recently removed the free tier.

Edit: I threw together a quick implementation in commit c21f491 where you might use a x-tidal-token instead of going through OAuth 2.0 authorization. Now, the playback information is retrieved correctly even if the user (logged in or not) doesn't have a TIDAL streaming plan:

client = tidal.PrivateAPI(access_token=<len 16 str>, overwrite=True, save=False)
info = client.get_track_playback_info(55391659)

You will get a dict as a response. The preview URL can be found in the manifest once you base-64 decode it, i.e., json.loads(base64.b64decode(info["manifest"]))["urls"].

project-owner commented 7 months ago

Great! I'm not sure where I can get the access token. In the doc you mentioned that you can get it using clientID/client secret:

Minim can obtain user access tokens via the authorization code with proof key for code exchange (PKCE) 
and device code flows. These OAuth 2.0 authorization flows require valid client credentials (client ID and 
client secret) to either be provided to this class’s constructor as keyword arguments or be stored as 
TIDAL_PRIVATE_CLIENT_ID and TIDAL_PRIVATE_CLIENT_SECRET in the operating system’s environment variables.

What should I do to use that token? Thanks!

bbye98 commented 7 months ago

The easiest way to get a x-tidal-token is by inspecting the GET request your browser makes to the /playbackinfo endpoint when you play a track through a TIDAL Embed (any track > three dots > Share > Copy embed code). One of the values in the header will be a x-tidal-token unique to your browsing session.

You could also try finding one online. I know that back in the day, the only way to access the private TIDAL API was to use a x-tidal-token, so there should be a few floating around out there.

Note that the x-tidal-token is NOT the same as an OAuth 2.0 access token.

bbye98 commented 7 months ago

Hi @project-owner! As I haven't heard back from you in a while, I'm going to go ahead and close this issue. Feel free to reopen it or start a new issue if you have any further questions.