Play the next track in a last.fm stream, and handle the end of stream properly
This commit is contained in:
parent
9e285efea7
commit
9206cad0cf
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@ class LastFMService : public RadioService {
|
|||
RadioItem* CreateRootItem(RadioItem* parent);
|
||||
void LazyPopulate(RadioItem *item);
|
||||
QList<RadioItem::PlaylistData> 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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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() {}
|
||||
};
|
||||
|
|
|
@ -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_;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ class RadioPlaylistItem : public PlaylistItem {
|
|||
bool StartLoading();
|
||||
QUrl Url();
|
||||
|
||||
bool LoadNext();
|
||||
|
||||
void SetTemporaryMetadata(const Song& metadata);
|
||||
void ClearTemporaryMetadata();
|
||||
|
||||
|
|
|
@ -22,7 +22,9 @@ class RadioService : public QObject {
|
|||
virtual void LazyPopulate(RadioItem* item) = 0;
|
||||
|
||||
virtual QList<RadioItem::PlaylistData> DataForItem(RadioItem* item) = 0;
|
||||
|
||||
virtual void StartLoading(const QUrl& url) = 0;
|
||||
virtual void LoadNext(const QUrl& url) = 0;
|
||||
|
||||
signals:
|
||||
void LoadingStarted();
|
||||
|
|
Loading…
Reference in New Issue