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

Playback Spotify tracks via Tidal #34

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

InfinityMod
Copy link

Combines to best of both worlds. Spotify playlists and their tracks from the Iris GUI can now be played easily via Tidal.
Songs are proxied from Spotify to Tidal before playback.

The option is deactivated in default but can be activated by enabling it via the settings:

[tidal]
...
spotify_proxy = true

Additionally, a Spotify client-id and client-secret have to be set:

[tidal]
...
spotify_client_id = **
spotify_client_secret = **

The function also works with free Spotify accounts.

…them via Tidal in the chosen quality. Is only enabled by setting: tidal -> spotify_proxy = true.

Also tidal -> spotify_client_id and tidal -> spotify_client_secret have to be added additionally inside the config. Works with free spotify accounts.
@tehkillerbee
Copy link
Owner

This is a very interesting feature that I am looking forward to test out. Does this only work with other web extensions or only Iris?

My only concern is the dependency on spotify.

@InfinityMod
Copy link
Author

InfinityMod commented Mar 5, 2021

Sure, basically the feature is very easy and does the following:

  1. Observe if besides tidal:.... also spotify:track:... elements are requested to be played back in mopidy. This request can also be initialized by another frontend.
  2. It gets the track information (artists, titel) from Spotify, which is why additional Spotify credentials are needed.
  3. Requesting the song from Tidal by performing a full search of the artists and the title.
  4. Adding the tidal song to the playlist.

The Spotify -> Tidal match routine is yet very easy (some would say: the low-hanging fruit), but works for me at least in 90% of the cases. It can obviously be improved later on.

@tehkillerbee
Copy link
Owner

@InfinityMod Very useful! Apologize that I have not merged this pull request. I have not had much time to test it out yet.

@erikcvisser
Copy link

@InfinityMod thanks for this PR - I have implemented it on top of the latest version of @tehkillerbee (using the OAuth flow), which works.
One question: I also use Iris as frontend, which benefits from having Mopidy-Spotify enabled (for getting new releases, trending playlists, etc). However, as your changes now register 'spotify' as URI scheme as well, Mopidy fails to start whenever Mopidy-Spotify is enabled - as it recognizes that 'spotify' has already been registered. Did you work around this? Or did you simply disable the Mopidy-Spotify extension?

@blacklight
Copy link
Collaborator

Hey folks, now that mopidy-spotify is apparently dead is there any way to get this PR approved (it's been open for >1 year), or are there still blockers on the way?

@tehkillerbee
Copy link
Owner

@blacklight I never merged this PR, as I did not have a way to test it fully (I do not have spotify) - and since I wanted to avoid dependency on other streaming services. But since mopidy-spotify is apparently dead, it might make sense to revive this PR after all.

It is important however, that mopidy-tidal does not break if these external services stops working (API changes etc.). Do we know if the spotipy will be affected similarly to libspotify?

@DavisNT
Copy link

DavisNT commented May 22, 2022

@tehkillerbee Looks like Spotify has had a not-very-developer-friendly API management in the past: https://jod.al/2016/02/18/guide-to-poor-api-management/

I think we could make sure (and test) that any exceptions or invalid results from spotipy cause proper failure (error about adding Spotify tracks propagated to upper layers of Mopidy, but no cascading failure).

I would guess the track lookup/matching could also be improved (e.g. by matching album and track length, if technically possible).

@blacklight
Copy link
Collaborator

Do we know if the spotipy will be affected similarly to libspotify?

This is actually an interesting question, and after several years of headaches with mopidy-spotify I can probably contribute my $0.02:

  • It's unlikely that spotipy will be affected by the same fate of libspotify. The reason is that spotipy is "just" a wrapper around Spotify's Web API. Spotify spent a lot of energy investing on the Web API as their ONLY API, zillions of integrations have already been built on it, and as long as the Web API doesn't get killed, spotipy should keep working.

  • However, being "just" a wrapper around the Web API (which btw doesn't support direct music playback), I'm wondering how the playback is actually working in this PR? That's the part in mopidy-spotify that is covered by libspotify. The only alternative playback backend that I know of is Librespot, which unlike libspotify is a Spotify Connect native client. But I don't see any references of Librespot in this PR. So I'm genuinely wondering how Spotify playback is supposed to work in this PR with spotipy alone :)

@DavisNT
Copy link

DavisNT commented May 22, 2022

  • So I'm genuinely wondering how Spotify playback is supposed to work in this PR with spotipy alone :)

These lines of code explain it - it just gets song title and artist from Spotify, searches them in Tidal and uses first search result.

@blacklight
Copy link
Collaborator

@DavisNT got it - so basically it uses spotipy only to retrieve the track metadata (which is covered by the Web API alone) and then it just bridges the information to Tidal which takes it on from there.

If the playback happens entirely on Tidal's side then I don't see any big risks of too much reliance on Spotify.

I agree that metadata matching could be improved though. In my experience Spotify's metadata has its own peculiarities. Like using the ; separator for multi-artist tracks, often in random order, and often they run "experiments" like e.g. including the producer in the artists' list. Things are even more problematic with classical music tracks, where original composer, director/orchestra/soloist are often grouped in a quite messy way under Artist. Oh, and then there's the arbitrary - Remaster suffix of some tracks that may not match the track name on other platforms. So probably the matching could be a bit more clever and e.g. split artists by ; and apply some matching score to the results, or strip the - Remaster suffixes from the results, or (probably the quickest win) match by duration.

@2e0byo
Copy link
Collaborator

2e0byo commented Aug 16, 2022

From previous experience building a general purpose matcher against spotify, duration is the killer feature which makes things useable. Other than that I just used levenshtein distance for title and artist. It was good enough most of the time. Solving the problem in the general case is probably impossibly hard.

@tehkillerbee
Copy link
Owner

I think it is time to revive this MR yet again. I will look into testing it with the latest mopidy_tidal as it could be a nice addition if spotify tracks/playlists are available through Tidal.

Still not 100% sold on integrating it into mopidy_tidal. Perhaps it should live as a separate plugin? Anyways, Ill try to rebase and get it running so we have a starting point.

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.

6 participants