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)
|
LastFMService::LastFMService(QObject* parent)
|
||||||
: RadioService("Last.fm", parent),
|
: RadioService("Last.fm", parent),
|
||||||
tuner_(NULL)
|
tuner_(NULL),
|
||||||
|
initial_tune_(false)
|
||||||
{
|
{
|
||||||
lastfm::ws::ApiKey = "75d20fb472be99275392aefa2760ea09";
|
lastfm::ws::ApiKey = "75d20fb472be99275392aefa2760ea09";
|
||||||
lastfm::ws::SharedSecret = "d3072b60ae626be12be69448f5c46e70";
|
lastfm::ws::SharedSecret = "d3072b60ae626be12be69448f5c46e70";
|
||||||
@ -147,13 +148,35 @@ void LastFMService::StartLoading(const QUrl& url) {
|
|||||||
emit LoadingStarted();
|
emit LoadingStarted();
|
||||||
|
|
||||||
delete tuner_;
|
delete tuner_;
|
||||||
|
|
||||||
last_url_ = url;
|
last_url_ = url;
|
||||||
|
initial_tune_ = true;
|
||||||
tuner_ = new lastfm::RadioTuner(lastfm::RadioStation(url));
|
tuner_ = new lastfm::RadioTuner(lastfm::RadioStation(url));
|
||||||
|
|
||||||
connect(tuner_, SIGNAL(trackAvailable()), SLOT(TunerTrackAvailable()));
|
connect(tuner_, SIGNAL(trackAvailable()), SLOT(TunerTrackAvailable()));
|
||||||
connect(tuner_, SIGNAL(error(lastfm::ws::Error)), SLOT(TunerError(lastfm::ws::Error)));
|
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) {
|
void LastFMService::TunerError(lastfm::ws::Error error) {
|
||||||
|
qDebug() << "Last.fm error" << error;
|
||||||
|
if (!initial_tune_)
|
||||||
|
return;
|
||||||
|
|
||||||
emit LoadingFinished();
|
emit LoadingFinished();
|
||||||
|
|
||||||
if (error == lastfm::ws::NotEnoughContent) {
|
if (error == lastfm::ws::NotEnoughContent) {
|
||||||
@ -162,7 +185,6 @@ void LastFMService::TunerError(lastfm::ws::Error error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit StreamError(ErrorString(error));
|
emit StreamError(ErrorString(error));
|
||||||
qDebug() << "Last.fm error" << error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LastFMService::ErrorString(lastfm::ws::Error error) const {
|
QString LastFMService::ErrorString(lastfm::ws::Error error) const {
|
||||||
@ -195,12 +217,10 @@ QString LastFMService::ErrorString(lastfm::ws::Error error) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LastFMService::TunerTrackAvailable() {
|
void LastFMService::TunerTrackAvailable() {
|
||||||
emit LoadingFinished();
|
if (initial_tune_) {
|
||||||
|
emit LoadingFinished();
|
||||||
|
|
||||||
lastfm::Track track = tuner_->takeNextTrack();
|
LoadNext(last_url_);
|
||||||
emit StreamReady(last_url_, track.url());
|
initial_tune_ = false;
|
||||||
|
}
|
||||||
Song metadata;
|
|
||||||
metadata.InitFromLastFM(track);
|
|
||||||
emit StreamMetadataFound(last_url_, metadata);
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,9 @@ class LastFMService : public RadioService {
|
|||||||
RadioItem* CreateRootItem(RadioItem* parent);
|
RadioItem* CreateRootItem(RadioItem* parent);
|
||||||
void LazyPopulate(RadioItem *item);
|
void LazyPopulate(RadioItem *item);
|
||||||
QList<RadioItem::PlaylistData> DataForItem(RadioItem* item);
|
QList<RadioItem::PlaylistData> DataForItem(RadioItem* item);
|
||||||
|
|
||||||
void StartLoading(const QUrl& url);
|
void StartLoading(const QUrl& url);
|
||||||
|
void LoadNext(const QUrl& url);
|
||||||
|
|
||||||
void Authenticate(const QString& username, const QString& password);
|
void Authenticate(const QString& username, const QString& password);
|
||||||
|
|
||||||
@ -49,6 +51,7 @@ class LastFMService : public RadioService {
|
|||||||
LastFMConfig* config_;
|
LastFMConfig* config_;
|
||||||
lastfm::RadioTuner* tuner_;
|
lastfm::RadioTuner* tuner_;
|
||||||
QUrl last_url_;
|
QUrl last_url_;
|
||||||
|
bool initial_tune_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LASTFMSERVICE_H
|
#endif // LASTFMSERVICE_H
|
||||||
|
@ -17,7 +17,7 @@ Player::Player(Playlist* playlist, QObject* parent)
|
|||||||
SetVolume(settings_.value("volume", 50).toInt());
|
SetVolume(settings_.value("volume", 50).toInt());
|
||||||
|
|
||||||
connect(engine_, SIGNAL(stateChanged(Engine::State)), SLOT(EngineStateChanged(Engine::State)));
|
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() {
|
void Player::Next() {
|
||||||
@ -32,6 +32,20 @@ void Player::Next() {
|
|||||||
PlayAt(i);
|
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() {
|
void Player::PlayPause() {
|
||||||
switch (engine_->state()) {
|
switch (engine_->state()) {
|
||||||
case Engine::Paused:
|
case Engine::Paused:
|
||||||
|
@ -27,6 +27,7 @@ class Player : public QObject {
|
|||||||
void Stop();
|
void Stop();
|
||||||
void SetVolume(int value);
|
void SetVolume(int value);
|
||||||
|
|
||||||
|
void TrackEnded();
|
||||||
void StreamReady(const QUrl& original_url, const QUrl& media_url);
|
void StreamReady(const QUrl& original_url, const QUrl& media_url);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -39,6 +39,10 @@ class PlaylistItem {
|
|||||||
virtual bool StartLoading() { return false; }
|
virtual bool StartLoading() { return false; }
|
||||||
virtual QUrl Url() = 0;
|
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 SetTemporaryMetadata(const Song& metadata) {Q_UNUSED(metadata)}
|
||||||
virtual void ClearTemporaryMetadata() {}
|
virtual void ClearTemporaryMetadata() {}
|
||||||
};
|
};
|
||||||
|
@ -65,6 +65,14 @@ bool RadioPlaylistItem::StartLoading() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RadioPlaylistItem::LoadNext() {
|
||||||
|
if (service_) {
|
||||||
|
service_->LoadNext(url_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QUrl RadioPlaylistItem::Url() {
|
QUrl RadioPlaylistItem::Url() {
|
||||||
return url_;
|
return url_;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ class RadioPlaylistItem : public PlaylistItem {
|
|||||||
bool StartLoading();
|
bool StartLoading();
|
||||||
QUrl Url();
|
QUrl Url();
|
||||||
|
|
||||||
|
bool LoadNext();
|
||||||
|
|
||||||
void SetTemporaryMetadata(const Song& metadata);
|
void SetTemporaryMetadata(const Song& metadata);
|
||||||
void ClearTemporaryMetadata();
|
void ClearTemporaryMetadata();
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@ class RadioService : public QObject {
|
|||||||
virtual void LazyPopulate(RadioItem* item) = 0;
|
virtual void LazyPopulate(RadioItem* item) = 0;
|
||||||
|
|
||||||
virtual QList<RadioItem::PlaylistData> DataForItem(RadioItem* item) = 0;
|
virtual QList<RadioItem::PlaylistData> DataForItem(RadioItem* item) = 0;
|
||||||
|
|
||||||
virtual void StartLoading(const QUrl& url) = 0;
|
virtual void StartLoading(const QUrl& url) = 0;
|
||||||
|
virtual void LoadNext(const QUrl& url) = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void LoadingStarted();
|
void LoadingStarted();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user