Play the next track in a last.fm stream, and handle the end of stream properly

This commit is contained in:
David Sansome 2009-12-26 22:59:11 +00:00
parent 9e285efea7
commit 9206cad0cf
8 changed files with 64 additions and 10 deletions

View File

@ -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;
}
}

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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() {}
};

View File

@ -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_;
}

View File

@ -27,6 +27,8 @@ class RadioPlaylistItem : public PlaylistItem {
bool StartLoading();
QUrl Url();
bool LoadNext();
void SetTemporaryMetadata(const Song& metadata);
void ClearTemporaryMetadata();

View File

@ -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();