mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-16 19:31:02 +01:00
Support for playing tracks from Spotify
This commit is contained in:
parent
c1041ed6d4
commit
5aca9b7984
@ -224,6 +224,8 @@ void SpotifyClient::HandleMessage(const spotify_pb::SpotifyMessage& message) {
|
||||
LoadImage(QStringFromStdString(message.image_request().id()));
|
||||
} else if (message.has_sync_playlist_request()) {
|
||||
SyncPlaylist(message.sync_playlist_request());
|
||||
} else if (message.has_browse_album_request()) {
|
||||
BrowseAlbum(QStringFromStdString(message.browse_album_request().uri()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -856,3 +858,45 @@ void SpotifyClient::ImageLoaded(sp_image* image, void* userdata) {
|
||||
SpotifyClient* me = reinterpret_cast<SpotifyClient*>(userdata);
|
||||
me->TryImageAgain(image);
|
||||
}
|
||||
|
||||
void SpotifyClient::BrowseAlbum(const QString& uri) {
|
||||
// Get a link object from the URI
|
||||
sp_link* link = sp_link_create_from_string(uri.toStdString().c_str());
|
||||
if (!link) {
|
||||
SendPlaybackError("Invalid Album URI");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the track from the link
|
||||
sp_album* album = sp_link_as_album(link);
|
||||
if (!album) {
|
||||
SendPlaybackError("Spotify URI was not an album");
|
||||
sp_link_release(link);
|
||||
return;
|
||||
}
|
||||
|
||||
sp_albumbrowse* browse =
|
||||
sp_albumbrowse_create(session_, album, &AlbumBrowseComplete, this);
|
||||
pending_album_browses_[browse] = uri;
|
||||
}
|
||||
|
||||
void SpotifyClient::AlbumBrowseComplete(sp_albumbrowse* result, void* userdata) {
|
||||
SpotifyClient* me = reinterpret_cast<SpotifyClient*>(userdata);
|
||||
|
||||
if (!me->pending_album_browses_.contains(result))
|
||||
return;
|
||||
|
||||
QString uri = me->pending_album_browses_.take(result);
|
||||
|
||||
spotify_pb::SpotifyMessage message;
|
||||
spotify_pb::BrowseAlbumResponse* msg = message.mutable_browse_album_response();
|
||||
|
||||
msg->set_uri(DataCommaSizeFromQString(uri));
|
||||
|
||||
const int count = sp_albumbrowse_num_tracks(result);
|
||||
for (int i=0 ; i<count ; ++i) {
|
||||
me->ConvertTrack(sp_albumbrowse_track(result, i), msg->add_track());
|
||||
}
|
||||
|
||||
me->handler_->SendMessage(message);
|
||||
}
|
||||
|
@ -92,6 +92,9 @@ private:
|
||||
// Spotify image callbacks.
|
||||
static void SP_CALLCONV ImageLoaded(sp_image* image, void* userdata);
|
||||
|
||||
// Spotify album browse callbacks.
|
||||
static void SP_CALLCONV AlbumBrowseComplete(sp_albumbrowse* result, void* userdata);
|
||||
|
||||
// Request handlers.
|
||||
void Login(const QString& username, const QString& password);
|
||||
void Search(const spotify_pb::SearchRequest& req);
|
||||
@ -99,6 +102,7 @@ private:
|
||||
void SyncPlaylist(const spotify_pb::SyncPlaylistRequest& req);
|
||||
void StartPlayback(const spotify_pb::PlaybackRequest& req);
|
||||
void LoadImage(const QString& id_b64);
|
||||
void BrowseAlbum(const QString& uri);
|
||||
|
||||
void SendPlaylistList();
|
||||
|
||||
@ -158,6 +162,7 @@ private:
|
||||
QList<PendingImageRequest> pending_image_requests_;
|
||||
QMap<sp_image*, int> image_callbacks_registered_;
|
||||
QMap<sp_search*, spotify_pb::SearchRequest> pending_searches_;
|
||||
QMap<sp_albumbrowse*, QString> pending_album_browses_;
|
||||
|
||||
int media_length_msec_;
|
||||
};
|
||||
|
@ -128,6 +128,15 @@ message ImageResponse {
|
||||
optional bytes data = 2;
|
||||
}
|
||||
|
||||
message BrowseAlbumRequest {
|
||||
required string uri = 1;
|
||||
}
|
||||
|
||||
message BrowseAlbumResponse {
|
||||
required string uri = 1;
|
||||
repeated Track track = 2;
|
||||
}
|
||||
|
||||
message SpotifyMessage {
|
||||
optional LoginRequest login_request = 1;
|
||||
optional LoginResponse login_response = 2;
|
||||
@ -142,4 +151,6 @@ message SpotifyMessage {
|
||||
optional ImageResponse image_response = 11;
|
||||
optional SyncPlaylistRequest sync_playlist_request = 12;
|
||||
optional SyncPlaylistProgress sync_playlist_progress = 13;
|
||||
optional BrowseAlbumRequest browse_album_request = 14;
|
||||
optional BrowseAlbumResponse browse_album_response = 15;
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "internet/internetmodel.h"
|
||||
#include "internet/spotifyserver.h"
|
||||
#include "internet/spotifyservice.h"
|
||||
#include "playlist/songmimedata.h"
|
||||
#include "spotifyblob/common/spotifymessagehandler.h"
|
||||
|
||||
SpotifySearchProvider::SpotifySearchProvider(QObject* parent)
|
||||
: SearchProvider(parent),
|
||||
@ -44,6 +46,8 @@ SpotifyServer* SpotifySearchProvider::server() {
|
||||
SLOT(SearchFinishedSlot(spotify_pb::SearchResponse)));
|
||||
connect(server_, SIGNAL(ImageLoaded(QString,QImage)),
|
||||
SLOT(ArtLoadedSlot(QString,QImage)));
|
||||
connect(server_, SIGNAL(AlbumBrowseResults(spotify_pb::BrowseAlbumResponse)),
|
||||
SLOT(AlbumBrowseResponse(spotify_pb::BrowseAlbumResponse)));
|
||||
connect(server_, SIGNAL(destroyed()), SLOT(ServerDestroyed()));
|
||||
|
||||
return service_->server();
|
||||
@ -134,7 +138,48 @@ void SpotifySearchProvider::ArtLoadedSlot(const QString& id, const QImage& image
|
||||
}
|
||||
|
||||
void SpotifySearchProvider::LoadTracksAsync(int id, const Result& result) {
|
||||
emit TracksLoaded(id, NULL);
|
||||
switch (result.type_) {
|
||||
case Result::Type_Track: {
|
||||
SongMimeData* mime_data = new SongMimeData;
|
||||
mime_data->songs = SongList() << result.metadata_;
|
||||
emit TracksLoaded(id, mime_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case Result::Type_Album: {
|
||||
SpotifyServer* s = server();
|
||||
if (!s) {
|
||||
emit TracksLoaded(id, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
QString uri = result.metadata_.url().toString();
|
||||
|
||||
pending_tracks_[uri] = id;
|
||||
s->AlbumBrowse(uri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpotifySearchProvider::AlbumBrowseResponse(const spotify_pb::BrowseAlbumResponse& response) {
|
||||
QString uri = QStringFromStdString(response.uri());
|
||||
QMap<QString, int>::iterator it = pending_tracks_.find(uri);
|
||||
if (it == pending_tracks_.end())
|
||||
return;
|
||||
|
||||
const int orig_id = it.value();
|
||||
pending_tracks_.erase(it);
|
||||
|
||||
SongMimeData* mime_data = new SongMimeData;
|
||||
|
||||
for (int i=0 ; i<response.track_size() ; ++i) {
|
||||
Song song;
|
||||
SpotifyService::SongFromProtobuf(response.track(i), &song);
|
||||
mime_data->songs << song;
|
||||
}
|
||||
|
||||
emit TracksLoaded(orig_id, mime_data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,8 @@ private slots:
|
||||
void SearchFinishedSlot(const spotify_pb::SearchResponse& response);
|
||||
void ArtLoadedSlot(const QString& id, const QImage& image);
|
||||
|
||||
void AlbumBrowseResponse(const spotify_pb::BrowseAlbumResponse& response);
|
||||
|
||||
private:
|
||||
struct PendingState {
|
||||
int orig_id_;
|
||||
@ -54,6 +56,7 @@ private:
|
||||
|
||||
QMap<QString, PendingState> queries_;
|
||||
QMap<QString, int> pending_art_;
|
||||
QMap<QString, int> pending_tracks_;
|
||||
};
|
||||
|
||||
#endif // SPOTIFYSEARCHPROVIDER_H
|
||||
|
@ -134,6 +134,8 @@ void SpotifyServer::HandleMessage(const spotify_pb::SpotifyMessage& message) {
|
||||
}
|
||||
} else if (message.has_sync_playlist_progress()) {
|
||||
emit SyncPlaylistProgress(message.sync_playlist_progress());
|
||||
} else if (message.has_browse_album_response()) {
|
||||
emit AlbumBrowseResults(message.browse_album_response());
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,3 +216,11 @@ void SpotifyServer::LoadImage(const QString& id) {
|
||||
req->set_id(DataCommaSizeFromQString(id));
|
||||
SendMessage(message);
|
||||
}
|
||||
|
||||
void SpotifyServer::AlbumBrowse(const QString& uri) {
|
||||
spotify_pb::SpotifyMessage message;
|
||||
spotify_pb::BrowseAlbumRequest* req = message.mutable_browse_album_request();
|
||||
|
||||
req->set_uri(DataCommaSizeFromQString(uri));
|
||||
SendMessage(message);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
void StartPlayback(const QString& uri, quint16 port);
|
||||
void Search(const QString& text, int limit, int limit_album = 0);
|
||||
void LoadImage(const QString& id);
|
||||
void AlbumBrowse(const QString& uri);
|
||||
|
||||
int server_port() const;
|
||||
|
||||
@ -61,6 +62,7 @@ signals:
|
||||
void SearchResults(const spotify_pb::SearchResponse& response);
|
||||
void ImageLoaded(const QString& id, const QImage& image);
|
||||
void SyncPlaylistProgress(const spotify_pb::SyncPlaylistProgress& progress);
|
||||
void AlbumBrowseResults(const spotify_pb::BrowseAlbumResponse& response);
|
||||
|
||||
private slots:
|
||||
void NewConnection();
|
||||
|
Loading…
Reference in New Issue
Block a user