1
0
mirror of https://github.com/clementine-player/Clementine synced 2025-02-01 20:06:53 +01:00

Refactor album cover fetching for last.fm radio.

Waits 5s on first tune to hopefully get the first album cover; nice side effect of letting the stream started notification fade.
This commit is contained in:
John Maguire 2010-02-26 14:50:02 +00:00
parent 44ca7adf14
commit b82301013a
2 changed files with 49 additions and 47 deletions

View File

@ -12,8 +12,9 @@
#include <lastfm/ws.h> #include <lastfm/ws.h>
#include <lastfm/XmlQuery> #include <lastfm/XmlQuery>
#include <QSettings>
#include <QMenu> #include <QMenu>
#include <QSettings>
#include <QTimer>
using boost::scoped_ptr; using boost::scoped_ptr;
using lastfm::XmlQuery; using lastfm::XmlQuery;
@ -276,29 +277,33 @@ void LastFMService::LoadNext(const QUrl &) {
return; return;
} }
scoped_ptr<QueuedTrack> track(playlist_.dequeue()); lastfm::Track track = playlist_.dequeue();
for (QMap<QNetworkReply*, QueuedTrack*>::iterator it = image_requests_.begin(); last_track_ = track;
it != image_requests_.end(); ++it) {
if (it.value() == track.get()) {
// Cancel pending album cover request.
it.key()->abort();
image_requests_.erase(it);
break;
}
}
last_track_ = track->track;
if (playlist_.empty()) { if (playlist_.empty()) {
FetchMoreTracks(); FetchMoreTracks();
} }
next_metadata_ = track;
if (initial_tune_) {
QTimer::singleShot(5000, this,
SLOT(StreamMetadataReady()));
} else {
StreamMetadataReady();
}
emit StreamReady(last_url_, last_track_.url());
}
void LastFMService::StreamMetadataReady() {
Song metadata; Song metadata;
metadata.InitFromLastFM(last_track_); metadata.InitFromLastFM(next_metadata_);
if (!track->image.isNull()) { QImage track_image = GetImageForTrack(next_metadata_);
metadata.set_image(track->image); if (!track_image.isNull()) {
metadata.set_image(track_image);
} else {
qDebug() << "No image ready";
} }
emit StreamMetadataFound(last_url_, metadata); emit StreamMetadataFound(last_url_, metadata);
emit StreamReady(last_url_, last_track_.url());
} }
void LastFMService::TunerError(lastfm::ws::Error error) { void LastFMService::TunerError(lastfm::ws::Error error) {
@ -596,13 +601,10 @@ void LastFMService::FetchMoreTracksFinished() {
t.setAlbum(q["album"].text()); t.setAlbum(q["album"].text());
t.setDuration(q["duration"].text().toInt() / 1000); t.setDuration(q["duration"].text().toInt() / 1000);
const QString& image = q["image"].text(); const QString& image = q["image"].text();
QueuedTrack* queued_track = new QueuedTrack;
queued_track->track = t;
if (!image.isEmpty()) { if (!image.isEmpty()) {
FetchImage(queued_track, image); FetchImage(t, image);
} }
playlist_ << queued_track; playlist_ << t;
qDebug() << "Adding track to playlist: " << t.title();
} }
TunerTrackAvailable(); TunerTrackAvailable();
@ -610,8 +612,13 @@ void LastFMService::FetchMoreTracksFinished() {
} }
void LastFMService::Tune(const lastfm::RadioStation& station) { void LastFMService::Tune(const lastfm::RadioStation& station) {
qDeleteAll(playlist_);
playlist_.clear(); playlist_.clear();
// Remove all the old image requests.
QHash<lastfm::Track, QNetworkReply*>::iterator it = image_requests_.begin();
while (it != image_requests_.end()) {
it.value()->deleteLater();
it = image_requests_.erase(it);
}
QMap<QString, QString> params; QMap<QString, QString> params;
params["method"] = "radio.tune"; params["method"] = "radio.tune";
@ -631,25 +638,23 @@ void LastFMService::TuneFinished() {
reply->deleteLater(); reply->deleteLater();
} }
void LastFMService::FetchImage(QueuedTrack* track, const QString& image_url) { void LastFMService::FetchImage(const lastfm::Track& track, const QString& image_url) {
QUrl url(image_url); QUrl url(image_url);
QNetworkReply* reply = network_.get(QNetworkRequest(url)); QNetworkReply* reply = network_.get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), SLOT(FetchImageFinished())); image_requests_[track] = reply;
image_requests_[reply] = track;
} }
void LastFMService::FetchImageFinished() { QImage LastFMService::GetImageForTrack(const lastfm::Track& track) {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); QNetworkReply* reply = image_requests_.take(track);
if (!reply) { if (reply) {
qWarning() << "Invalid reply on track image fetch."; // QNetworkReply::isFinished() only in Qt 4.6 :-(
return; QVariant content_length = reply->header(QNetworkRequest::ContentLengthHeader);
if (!content_length.isNull() && content_length.toInt() == reply->bytesAvailable()) {
QImage image = QImage::fromData(reply->readAll());
reply->deleteLater();
return image;
}
reply->deleteLater();
} }
// The response might be too late to matter. return QImage();
if (image_requests_.contains(reply)) {
QueuedTrack* track = image_requests_.take(reply);
QImage image = QImage::fromData(reply->readAll());
track->image = image;
}
reply->deleteLater();
} }

View File

@ -108,14 +108,9 @@ class LastFMService : public RadioService {
void FetchMoreTracksFinished(); void FetchMoreTracksFinished();
void TuneFinished(); void TuneFinished();
void FetchImageFinished(); void StreamMetadataReady();
private: private:
struct QueuedTrack {
lastfm::Track track;
QImage image;
};
RadioItem* CreateStationItem(ItemType type, const QString& name, RadioItem* CreateStationItem(ItemType type, const QString& name,
const QString& icon, RadioItem* parent); const QString& icon, RadioItem* parent);
QString ErrorString(lastfm::ws::Error error) const; QString ErrorString(lastfm::ws::Error error) const;
@ -131,12 +126,14 @@ class LastFMService : public RadioService {
const QIcon& icon, RadioItem *list); const QIcon& icon, RadioItem *list);
void Tune(const lastfm::RadioStation& station); void Tune(const lastfm::RadioStation& station);
void FetchImage(QueuedTrack* track, const QString& image_url); void FetchImage(const lastfm::Track& track, const QString& image_url);
QImage GetImageForTrack(const lastfm::Track& track);
private: private:
lastfm::Audioscrobbler* scrobbler_; lastfm::Audioscrobbler* scrobbler_;
lastfm::Track last_track_; lastfm::Track last_track_;
QQueue<QueuedTrack*> playlist_; lastfm::Track next_metadata_;
QQueue<lastfm::Track> playlist_;
LastFMConfigDialog* config_; LastFMConfigDialog* config_;
LastFMStationDialog* station_dialog_; LastFMStationDialog* station_dialog_;
@ -159,7 +156,7 @@ class LastFMService : public RadioService {
RadioItem* neighbours_list_; RadioItem* neighbours_list_;
QNetworkAccessManager network_; QNetworkAccessManager network_;
QMap<QNetworkReply*, QueuedTrack*> image_requests_; QHash<lastfm::Track, QNetworkReply*> image_requests_;
}; };
#endif // LASTFMSERVICE_H #endif // LASTFMSERVICE_H