1
0
mirror of https://github.com/strawberrymusicplayer/strawberry synced 2025-02-02 18:46:46 +01:00

Use original image format when saving images from Subsonic and Tidal

Fixes #435
This commit is contained in:
Jonas Kvinge 2020-05-12 18:50:57 +02:00
parent 84ec4bdc79
commit 7e22e0e552
5 changed files with 93 additions and 33 deletions

View File

@ -387,7 +387,7 @@ QUrl AlbumCoverChoiceController::SaveCoverToFileAutomatic(const Song *song, cons
QUrl AlbumCoverChoiceController::SaveCoverToFileAutomatic(const Song::Source source, const QString &artist, const QString &album, const QString &album_id, const QString &album_dir, const QUrl &cover_url, const QImage &image, const bool overwrite) { QUrl AlbumCoverChoiceController::SaveCoverToFileAutomatic(const Song::Source source, const QString &artist, const QString &album, const QString &album_id, const QString &album_dir, const QUrl &cover_url, const QImage &image, const bool overwrite) {
QString filepath = app_->album_cover_loader()->CoverFilePath(source, artist, album, album_id, album_dir, cover_url); QString filepath = app_->album_cover_loader()->CoverFilePath(source, artist, album, album_id, album_dir, cover_url, "jpg");
if (filepath.isEmpty()) return QUrl(); if (filepath.isEmpty()) return QUrl();
QUrl new_cover_url(QUrl::fromLocalFile(filepath)); QUrl new_cover_url(QUrl::fromLocalFile(filepath));

View File

@ -98,27 +98,32 @@ void AlbumCoverLoader::ReloadSettings() {
} }
QString AlbumCoverLoader::AlbumCoverFilename(QString artist, QString album) { QString AlbumCoverLoader::AlbumCoverFilename(QString artist, QString album, const QString &extension) {
artist.remove('/'); artist.remove('/');
album.remove('/'); album.remove('/');
QString filename = artist + "-" + album + ".jpg"; QString filename = artist + "-" + album;
filename = Utilities::UnicodeToAscii(filename.toLower()); filename = Utilities::UnicodeToAscii(filename.toLower());
filename = filename.replace(' ', '-'); filename = filename.replace(' ', '-');
filename = filename.replace("--", "-"); filename = filename.replace("--", "-");
filename = filename.remove(OrganiseFormat::kInvalidFatCharacters); filename = filename.remove(OrganiseFormat::kInvalidFatCharacters);
filename = filename.trimmed(); filename = filename.simplified();
if (!extension.isEmpty()) {
filename.append('.');
filename.append(extension);
}
return filename; return filename;
} }
QString AlbumCoverLoader::CoverFilePath(const Song &song, const QString &album_dir, const QUrl &cover_url) { QString AlbumCoverLoader::CoverFilePath(const Song &song, const QString &album_dir, const QUrl &cover_url, const QString &extension) {
return CoverFilePath(song.source(), song.effective_albumartist(), song.album(), song.album_id(), album_dir, cover_url); return CoverFilePath(song.source(), song.effective_albumartist(), song.album(), song.album_id(), album_dir, cover_url, extension);
} }
QString AlbumCoverLoader::CoverFilePath(const Song::Source source, const QString &artist, QString album, const QString &album_id, const QString &album_dir, const QUrl &cover_url) { QString AlbumCoverLoader::CoverFilePath(const Song::Source source, const QString &artist, QString album, const QString &album_id, const QString &album_dir, const QUrl &cover_url, const QString &extension) {
album.remove(Song::kAlbumRemoveDisc); album.remove(Song::kAlbumRemoveDisc);
@ -130,7 +135,7 @@ QString AlbumCoverLoader::CoverFilePath(const Song::Source source, const QString
path = Song::ImageCacheDir(source); path = Song::ImageCacheDir(source);
} }
if (path.right(1) == QDir::separator()) { if (path.right(1) == QDir::separator() || path.right(1) == '/') {
path.chop(1); path.chop(1);
} }
@ -142,13 +147,17 @@ QString AlbumCoverLoader::CoverFilePath(const Song::Source source, const QString
QString filename; QString filename;
if (source == Song::Source_Collection && cover_album_dir_ && cover_filename_ == CollectionSettingsPage::SaveCover_Pattern && !cover_pattern_.isEmpty()) { if (source == Song::Source_Collection && cover_album_dir_ && cover_filename_ == CollectionSettingsPage::SaveCover_Pattern && !cover_pattern_.isEmpty()) {
filename = CoverFilenameFromVariable(artist, album) + ".jpg"; filename = CoverFilenameFromVariable(artist, album);
filename.remove(OrganiseFormat::kInvalidFatCharacters); filename.remove(OrganiseFormat::kInvalidFatCharacters);
if (cover_lowercase_) filename = filename.toLower(); if (cover_lowercase_) filename = filename.toLower();
if (cover_replace_spaces_) filename.replace(QRegExp("\\s"), "-"); if (cover_replace_spaces_) filename.replace(QRegExp("\\s"), "-");
if (!extension.isEmpty()) {
filename.append('.');
filename.append(extension);
}
} }
else { else {
filename = CoverFilenameFromSource(source, cover_url, artist, album, album_id); filename = CoverFilenameFromSource(source, cover_url, artist, album, album_id, extension);
} }
QString filepath(path + "/" + filename); QString filepath(path + "/" + filename);
@ -157,7 +166,7 @@ QString AlbumCoverLoader::CoverFilePath(const Song::Source source, const QString
} }
QString AlbumCoverLoader::CoverFilenameFromSource(const Song::Source source, const QUrl &cover_url, const QString &artist, const QString &album, const QString &album_id) { QString AlbumCoverLoader::CoverFilenameFromSource(const Song::Source source, const QUrl &cover_url, const QString &artist, const QString &album, const QString &album_id, const QString &extension) {
QString filename; QString filename;
@ -171,7 +180,7 @@ QString AlbumCoverLoader::CoverFilenameFromSource(const Song::Source source, con
case Song::Source_Subsonic: case Song::Source_Subsonic:
case Song::Source_Qobuz: case Song::Source_Qobuz:
if (!album_id.isEmpty()) { if (!album_id.isEmpty()) {
filename = album_id + ".jpg"; filename = album_id;
break; break;
} }
// fallthrough // fallthrough
@ -181,20 +190,29 @@ QString AlbumCoverLoader::CoverFilenameFromSource(const Song::Source source, con
case Song::Source_Device: case Song::Source_Device:
case Song::Source_Stream: case Song::Source_Stream:
case Song::Source_Unknown: case Song::Source_Unknown:
filename = Utilities::Sha1CoverHash(artist, album).toHex() + ".jpg"; filename = Utilities::Sha1CoverHash(artist, album).toHex();
break; break;
} }
if (!extension.isEmpty()) {
filename.append('.');
filename.append(extension);
}
return filename; return filename;
} }
QString AlbumCoverLoader::CoverFilenameFromVariable(const QString &artist, const QString &album) { QString AlbumCoverLoader::CoverFilenameFromVariable(const QString &artist, const QString &album, const QString &extension) {
QString filename(cover_pattern_); QString filename(cover_pattern_);
filename.replace("%albumartist", artist); filename.replace("%albumartist", artist);
filename.replace("%artist", artist); filename.replace("%artist", artist);
filename.replace("%album", album); filename.replace("%album", album);
if (!extension.isEmpty()) {
filename.append('.');
filename.append(extension);
}
return filename; return filename;
} }

View File

@ -61,12 +61,13 @@ class AlbumCoverLoader : public QObject {
void ExitAsync(); void ExitAsync();
void Stop() { stop_requested_ = true; } void Stop() { stop_requested_ = true; }
static QString AlbumCoverFilename(QString artist, QString album); static QString AlbumCoverFilename(QString artist, QString album, const QString &extension);
QString CoverFilenameFromSource(const Song::Source source, const QUrl &cover_url, const QString &artist, const QString &album, const QString &album_id); QString CoverFilenameFromSource(const Song::Source source, const QUrl &cover_url, const QString &artist, const QString &album, const QString &album_id, const QString &extension);
QString CoverFilenameFromVariable(const QString &artist, const QString &album); QString CoverFilenameFromVariable(const QString &artist, const QString &album, const QString &extension = QString());
QString CoverFilePath(const Song &song, const QString &album_dir, const QUrl &cover_url); QString CoverFilePath(const Song &song, const QString &album_dir, const QUrl &cover_url, const QString &extension = QString());
QString CoverFilePath(const Song::Source source, const QString &artist, QString album, const QString &album_id, const QString &album_dir, const QUrl &cover_url);
QString CoverFilePath(const Song::Source source, const QString &artist, QString album, const QString &album_id, const QString &album_dir, const QUrl &cover_url, const QString &extension = QString());
quint64 LoadImageAsync(const AlbumCoverLoaderOptions &options, const Song &song); quint64 LoadImageAsync(const AlbumCoverLoaderOptions &options, const Song &song);
virtual quint64 LoadImageAsync(const AlbumCoverLoaderOptions &options, const QUrl &art_automatic, const QUrl &art_manual, const QUrl &song_url = QUrl(), const Song song = Song(), const QImage &embedded_image = QImage()); virtual quint64 LoadImageAsync(const AlbumCoverLoaderOptions &options, const QUrl &art_automatic, const QUrl &art_manual, const QUrl &song_url = QUrl(), const Song song = Song(), const QImage &embedded_image = QImage());

View File

@ -29,6 +29,7 @@
#include <QUrl> #include <QUrl>
#include <QRegExp> #include <QRegExp>
#include <QImage> #include <QImage>
#include <QImageReader>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QNetworkReply> #include <QNetworkReply>
@ -748,32 +749,53 @@ void SubsonicRequest::AlbumCoverReceived(QNetworkReply *reply, const QString alb
} }
if (reply->error() != QNetworkReply::NoError) { if (reply->error() != QNetworkReply::NoError) {
Error(QString("%1 (%2)").arg(reply->errorString()).arg(reply->error())); Error(QString("%1 (%2) for %3").arg(reply->errorString()).arg(reply->error()).arg(url.toString()));
album_covers_requests_sent_.remove(album_id); if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
AlbumCoverFinishCheck(); AlbumCoverFinishCheck();
return; return;
} }
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
Error(QString("Received HTTP code %1 for %2.").arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()).arg(url.toString()));
if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
AlbumCoverFinishCheck();
return;
}
QString mimetype = reply->header(QNetworkRequest::ContentTypeHeader).toString();
if (!QImageReader::supportedMimeTypes().contains(mimetype.toUtf8())) {
Error(QString("Unsupported mimetype for image reader %1 for %2").arg(mimetype).arg(url.toString()));
if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
AlbumCoverFinishCheck();
return;
}
QByteArray format = QImageReader::imageFormatsForMimeType(mimetype.toUtf8()).first();
QByteArray data = reply->readAll(); QByteArray data = reply->readAll();
if (data.isEmpty()) { if (data.isEmpty()) {
Error(QString("Received empty image data for %1").arg(url.toString())); Error(QString("Received empty image data for %1").arg(url.toString()));
album_covers_requests_sent_.remove(album_id); if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
AlbumCoverFinishCheck(); AlbumCoverFinishCheck();
return; return;
} }
QString fullfilename = filename + "." + format.toLower();
QImage image; QImage image;
if (image.loadFromData(data)) { if (image.loadFromData(data, format)) {
if (image.save(filename, "JPG")) { if (image.save(fullfilename, format)) {
while (album_covers_requests_sent_.contains(album_id)) { while (album_covers_requests_sent_.contains(album_id)) {
Song *song = album_covers_requests_sent_.take(album_id); Song *song = album_covers_requests_sent_.take(album_id);
song->set_art_automatic(QUrl::fromLocalFile(filename)); song->set_art_automatic(QUrl::fromLocalFile(fullfilename));
} }
} }
else {
Error(QString("Error saving image data to %1.").arg(fullfilename));
if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
}
} }
else { else {
album_covers_requests_sent_.remove(album_id); Error(QString("Error decoding image data from %1.").arg(url.toString()));
Error(QString("Error decoding image data from %1").arg(url.toString())); if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
} }
AlbumCoverFinishCheck(); AlbumCoverFinishCheck();

View File

@ -24,6 +24,7 @@
#include <QString> #include <QString>
#include <QUrl> #include <QUrl>
#include <QImage> #include <QImage>
#include <QImageReader>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QNetworkReply> #include <QNetworkReply>
#include <QJsonObject> #include <QJsonObject>
@ -1151,27 +1152,45 @@ void TidalRequest::AlbumCoverReceived(QNetworkReply *reply, const QString &album
return; return;
} }
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
Error(QString("Received HTTP code %1 for %2.").arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()).arg(url.toString()));
if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
AlbumCoverFinishCheck();
return;
}
QString mimetype = reply->header(QNetworkRequest::ContentTypeHeader).toString();
if (!QImageReader::supportedMimeTypes().contains(mimetype.toUtf8())) {
Error(QString("Unsupported mimetype for image reader %1 for %2").arg(mimetype).arg(url.toString()));
if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
AlbumCoverFinishCheck();
return;
}
QByteArray format = QImageReader::imageFormatsForMimeType(mimetype.toUtf8()).first();
QByteArray data = reply->readAll(); QByteArray data = reply->readAll();
if (data.isEmpty()) { if (data.isEmpty()) {
Error(QString("Received empty image data for %1").arg(url.toString())); Error(QString("Received empty image data for %1").arg(url.toString()));
album_covers_requests_sent_.remove(album_id); if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
AlbumCoverFinishCheck(); AlbumCoverFinishCheck();
return; return;
} }
QImage image; QImage image;
if (image.loadFromData(data)) { if (image.loadFromData(data, format)) {
if (image.save(filename, format)) {
if (image.save(filename, "JPG")) {
while (album_covers_requests_sent_.contains(album_id)) { while (album_covers_requests_sent_.contains(album_id)) {
Song *song = album_covers_requests_sent_.take(album_id); Song *song = album_covers_requests_sent_.take(album_id);
song->set_art_automatic(QUrl::fromLocalFile(filename)); song->set_art_automatic(QUrl::fromLocalFile(filename));
} }
} }
else {
Error(QString("Error saving image data to %1").arg(filename));
if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
}
} }
else { else {
album_covers_requests_sent_.remove(album_id); if (album_covers_requests_sent_.contains(album_id)) album_covers_requests_sent_.remove(album_id);
Error(QString("Error decoding image data from %1").arg(url.toString())); Error(QString("Error decoding image data from %1").arg(url.toString()));
} }