diff --git a/src/lastfmservice.cpp b/src/lastfmservice.cpp index 2d0a85b42..09a6d2c3d 100644 --- a/src/lastfmservice.cpp +++ b/src/lastfmservice.cpp @@ -13,7 +13,8 @@ const char* LastFMService::kSettingsGroup = "Last.fm"; LastFMService::LastFMService(QObject* parent) : RadioService("Last.fm", parent), - tuner_(NULL) + tuner_(NULL), + initial_tune_(false) { lastfm::ws::ApiKey = "75d20fb472be99275392aefa2760ea09"; lastfm::ws::SharedSecret = "d3072b60ae626be12be69448f5c46e70"; @@ -147,13 +148,35 @@ void LastFMService::StartLoading(const QUrl& url) { emit LoadingStarted(); delete tuner_; + last_url_ = url; + initial_tune_ = true; tuner_ = new lastfm::RadioTuner(lastfm::RadioStation(url)); + connect(tuner_, SIGNAL(trackAvailable()), SLOT(TunerTrackAvailable())); connect(tuner_, SIGNAL(error(lastfm::ws::Error)), SLOT(TunerError(lastfm::ws::Error))); } +void LastFMService::LoadNext(const QUrl &) { + lastfm::Track track = tuner_->takeNextTrack(); + + if (track.isNull()) { + emit StreamFinished(); + return; + } + + emit StreamReady(last_url_, track.url()); + + Song metadata; + metadata.InitFromLastFM(track); + emit StreamMetadataFound(last_url_, metadata); +} + void LastFMService::TunerError(lastfm::ws::Error error) { + qDebug() << "Last.fm error" << error; + if (!initial_tune_) + return; + emit LoadingFinished(); if (error == lastfm::ws::NotEnoughContent) { @@ -162,7 +185,6 @@ void LastFMService::TunerError(lastfm::ws::Error error) { } emit StreamError(ErrorString(error)); - qDebug() << "Last.fm error" << error; } QString LastFMService::ErrorString(lastfm::ws::Error error) const { @@ -195,12 +217,10 @@ QString LastFMService::ErrorString(lastfm::ws::Error error) const { } void LastFMService::TunerTrackAvailable() { - emit LoadingFinished(); + if (initial_tune_) { + emit LoadingFinished(); - lastfm::Track track = tuner_->takeNextTrack(); - emit StreamReady(last_url_, track.url()); - - Song metadata; - metadata.InitFromLastFM(track); - emit StreamMetadataFound(last_url_, metadata); + LoadNext(last_url_); + initial_tune_ = false; + } } diff --git a/src/lastfmservice.h b/src/lastfmservice.h index f96502324..f48887c89 100644 --- a/src/lastfmservice.h +++ b/src/lastfmservice.h @@ -27,7 +27,9 @@ class LastFMService : public RadioService { RadioItem* CreateRootItem(RadioItem* parent); void LazyPopulate(RadioItem *item); QList DataForItem(RadioItem* item); + void StartLoading(const QUrl& url); + void LoadNext(const QUrl& url); void Authenticate(const QString& username, const QString& password); @@ -49,6 +51,7 @@ class LastFMService : public RadioService { LastFMConfig* config_; lastfm::RadioTuner* tuner_; QUrl last_url_; + bool initial_tune_; }; #endif // LASTFMSERVICE_H diff --git a/src/player.cpp b/src/player.cpp index 240e07a48..8ccf0ecf6 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -17,7 +17,7 @@ Player::Player(Playlist* playlist, QObject* parent) SetVolume(settings_.value("volume", 50).toInt()); connect(engine_, SIGNAL(stateChanged(Engine::State)), SLOT(EngineStateChanged(Engine::State))); - connect(engine_, SIGNAL(trackEnded()), SLOT(Next())); + connect(engine_, SIGNAL(trackEnded()), SLOT(TrackEnded())); } void Player::Next() { @@ -32,6 +32,20 @@ void Player::Next() { PlayAt(i); } +void Player::TrackEnded() { + int i = playlist_->current_item(); + if (i == -1) { + Stop(); + return; + } + + // Is this track a radio station (like Last.fm) that can have another track? + if (playlist_->item_at(i)->LoadNext()) + return; + + Next(); +} + void Player::PlayPause() { switch (engine_->state()) { case Engine::Paused: diff --git a/src/player.h b/src/player.h index ab15d42cc..1a89efbfc 100644 --- a/src/player.h +++ b/src/player.h @@ -27,6 +27,7 @@ class Player : public QObject { void Stop(); void SetVolume(int value); + void TrackEnded(); void StreamReady(const QUrl& original_url, const QUrl& media_url); signals: diff --git a/src/playlistitem.h b/src/playlistitem.h index 6a90f03f2..96a96cc99 100644 --- a/src/playlistitem.h +++ b/src/playlistitem.h @@ -39,6 +39,10 @@ class PlaylistItem { virtual bool StartLoading() { return false; } virtual QUrl Url() = 0; + // If the item is a radio station that can play another song after one has + // finished then it should do so and return true + virtual bool LoadNext() { return false; } + virtual void SetTemporaryMetadata(const Song& metadata) {Q_UNUSED(metadata)} virtual void ClearTemporaryMetadata() {} }; diff --git a/src/radioplaylistitem.cpp b/src/radioplaylistitem.cpp index d5bbb071c..3f2f9e0ec 100644 --- a/src/radioplaylistitem.cpp +++ b/src/radioplaylistitem.cpp @@ -65,6 +65,14 @@ bool RadioPlaylistItem::StartLoading() { return true; } +bool RadioPlaylistItem::LoadNext() { + if (service_) { + service_->LoadNext(url_); + return true; + } + return false; +} + QUrl RadioPlaylistItem::Url() { return url_; } diff --git a/src/radioplaylistitem.h b/src/radioplaylistitem.h index a47a9c1dd..4a9c8205d 100644 --- a/src/radioplaylistitem.h +++ b/src/radioplaylistitem.h @@ -27,6 +27,8 @@ class RadioPlaylistItem : public PlaylistItem { bool StartLoading(); QUrl Url(); + bool LoadNext(); + void SetTemporaryMetadata(const Song& metadata); void ClearTemporaryMetadata(); diff --git a/src/radioservice.h b/src/radioservice.h index 700f9ff9b..aa2d3a60c 100644 --- a/src/radioservice.h +++ b/src/radioservice.h @@ -22,7 +22,9 @@ class RadioService : public QObject { virtual void LazyPopulate(RadioItem* item) = 0; virtual QList DataForItem(RadioItem* item) = 0; + virtual void StartLoading(const QUrl& url) = 0; + virtual void LoadNext(const QUrl& url) = 0; signals: void LoadingStarted();