diff --git a/src/enclosure.cpp b/src/enclosure.cpp index e5af7aa6..d1e1a5e1 100644 --- a/src/enclosure.cpp +++ b/src/enclosure.cpp @@ -10,9 +10,16 @@ #include #include +#include +#include #include #include +#include +#include +#include +#include + #include "audiomanager.h" #include "database.h" #include "datamanager.h" @@ -237,6 +244,50 @@ Enclosure::Status Enclosure::status() const return m_status; } +QString Enclosure::cachedEmbeddedImage() const +{ + // if image is already cached, then return the path + QString cachedpath = StorageManager::instance().imagePath(path()); + if (QFileInfo::exists(cachedpath)) { + if (QFileInfo(cachedpath).size() != 0) { + return QUrl::fromLocalFile(cachedpath).toString(); + } + } + + if (m_status != Downloaded || path().isEmpty()) { + return QStringLiteral(""); + } + + const auto mime = QMimeDatabase().mimeTypeForFile(path()).name(); + if (mime != QStringLiteral("audio/mpeg")) { + return QStringLiteral(""); + } + + TagLib::MPEG::File f(path().toLatin1().data()); + if (!f.hasID3v2Tag()) { + return QStringLiteral(""); + } + + bool imageFound = false; + for (const auto &frame : f.ID3v2Tag()->frameListMap()["APIC"]) { + auto pictureFrame = dynamic_cast(frame); + QByteArray data(pictureFrame->picture().data(), pictureFrame->picture().size()); + if (!data.isEmpty()) { + QFile file(cachedpath); + file.open(QIODevice::WriteOnly); + file.write(data); + file.close(); + imageFound = true; + } + } + + if (imageFound) { + return cachedpath; + } else { + return QUrl::fromLocalFile(cachedpath).toString(); + } +} + qint64 Enclosure::playPosition() const { return m_playposition; diff --git a/src/enclosure.h b/src/enclosure.h index 6a44782a..d4f4fe2f 100644 --- a/src/enclosure.h +++ b/src/enclosure.h @@ -31,6 +31,7 @@ class Enclosure : public QObject Q_PROPERTY(double downloadProgress MEMBER m_downloadProgress NOTIFY downloadProgressChanged) Q_PROPERTY(QString formattedDownloadSize READ formattedDownloadSize NOTIFY downloadProgressChanged) Q_PROPERTY(QString path READ path CONSTANT) + Q_PROPERTY(QString cachedEmbeddedImage READ cachedEmbeddedImage CONSTANT) Q_PROPERTY(qint64 playPosition READ playPosition WRITE setPlayPosition NOTIFY playPositionChanged) Q_PROPERTY(QString formattedLeftDuration READ formattedLeftDuration NOTIFY playPositionChanged) Q_PROPERTY(QString formattedPlayPosition READ formattedPlayPosition NOTIFY playPositionChanged) @@ -58,6 +59,7 @@ public: QString path() const; QString url() const; Status status() const; + QString cachedEmbeddedImage() const; qint64 playPosition() const; qint64 duration() const; qint64 size() const; diff --git a/src/entry.cpp b/src/entry.cpp index 9423c89a..e5a69221 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -249,17 +249,27 @@ QString Entry::image() const { if (!m_image.isEmpty()) { return m_image; + } else if (m_hasenclosure && !m_enclosure->cachedEmbeddedImage().isEmpty()) { + // use embedded image if available + return m_enclosure->cachedEmbeddedImage(); } else { + // else fall back to feed image return m_feed->image(); } } QString Entry::cachedImage() const { - // First check for the feed image as fallback + // First check for the feed image, fall back if needed QString image = m_image; if (image.isEmpty()) { - image = m_feed->image(); + if (m_hasenclosure && !m_enclosure->cachedEmbeddedImage().isEmpty()) { + // use embedded image if available + return m_enclosure->cachedEmbeddedImage(); + } else { + // else fall back to feed image + image = m_feed->image(); + } } return Fetcher::instance().image(image); diff --git a/src/mpris2/mediaplayer2player.cpp b/src/mpris2/mediaplayer2player.cpp index bc0749c4..14734fab 100644 --- a/src/mpris2/mediaplayer2player.cpp +++ b/src/mpris2/mediaplayer2player.cpp @@ -390,7 +390,7 @@ QVariantMap MediaPlayer2Player::getMetadataOfCurrentTrack() result[QStringLiteral("xesam:artist")] = authors; } if (!entry->image().isEmpty()) { - result[QStringLiteral("mpris:artUrl")] = StorageManager::instance().imagePath(entry->image()); + result[QStringLiteral("mpris:artUrl")] = entry->cachedImage(); } return result;