Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

MythMusic: add some virtual functions to the MetaIO base class.

This adds some virtual functions to the base MetaIO class that derived classes
can override for accessing any embedded album art supported by the tag format.

Update the Id3 tagger to support reading, writing and removing any album art.
  • Loading branch information...
commit a52601a9155a4e8aa640eaa538aac68c082a81a6 1 parent 7b9a3a1
Paul Harrison authored
View
2  mythplugins/mythmusic/mythmusic/metadata.h
@@ -41,6 +41,8 @@ typedef struct AlbumArtImage
bool embedded;
} AlbumArtImage;
+typedef QList<AlbumArtImage*> AlbumArtList;
+
typedef QHash<QString,QString> MetadataMap;
class Metadata
View
41 mythplugins/mythmusic/mythmusic/metaio.h
@@ -4,10 +4,10 @@
// QT
#include <QString>
-#define MYTH_MUSICBRAINZ_ALBUMARTIST_UUID "89ad4ac3-39f7-470e-963a-56509c546377"
+// MythMusic
+#include "metadata.h"
-// No need to include all the Metadata stuff just for the abstract pointer....
-class Metadata;
+#define MYTH_MUSICBRAINZ_ALBUMARTIST_UUID "89ad4ac3-39f7-470e-963a-56509c546377"
class MetaIO
{
@@ -44,6 +44,41 @@ class MetaIO
*/
virtual Metadata* read(QString filename) = 0;
+ /*!
+ * \brief Does the tag support embedded cover art.
+ *
+ * \returns true if reading/writing embedded images are supported
+ */
+ virtual bool supportsEmbeddedImages(void)
+ {
+ return false;
+ }
+
+ /*!
+ * \brief Reads the list of embedded images in the tag
+ *
+ * \returns the list of embedded images
+ */
+ virtual AlbumArtList getAlbumArtList(const QString &filename)
+ {
+ (void)filename;
+ return AlbumArtList();
+ }
+
+ virtual bool writeAlbumArt(const QString &filename, const AlbumArtImage *albumart)
+ {
+ (void)filename;
+ (void)albumart;
+ return false;
+ }
+
+ virtual bool removeAlbumArt(const QString &filename, const AlbumArtImage *albumart)
+ {
+ (void)filename;
+ (void)albumart;
+ return false;
+ }
+
void readFromFilename(QString filename, QString &artist, QString &album,
QString &title, QString &genre, int &tracknum);
View
208 mythplugins/mythmusic/mythmusic/metaioid3.cpp
@@ -218,14 +218,6 @@ Metadata *MetaIOID3::read(QString filename)
// e.g. Lame under certain circumstances will always write a length of
// 27 hours
- // Album Art
- if (!tag->frameListMap()["APIC"].isEmpty())
- {
- QList<struct AlbumArtImage> albumart;
- albumart = readAlbumArt(tag);
- metadata->setEmbeddedAlbumArt(albumart);
- }
-
metadata->setCompilation(compilation);
TagLib::FileRef *fileref = new TagLib::FileRef(mpegfile);
@@ -304,6 +296,36 @@ QImage MetaIOID3::getAlbumArt(QString filename, ImageType type)
return picture;
}
+
+/*!
+ * \brief Read the albumart images from the file
+ *
+ * \param filename The filename for which we want to find the images.
+ */
+AlbumArtList MetaIOID3::getAlbumArtList(const QString &filename)
+{
+ AlbumArtList imageList;
+ QByteArray fname = filename.toLocal8Bit();
+ TagLib::MPEG::File *mpegfile = new TagLib::MPEG::File(fname.constData());
+
+ if (mpegfile)
+ {
+ TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();
+
+ if (!tag)
+ {
+ delete mpegfile;
+ return imageList;
+ }
+
+ imageList = readAlbumArt(tag);
+
+ delete mpegfile;
+ }
+
+ return imageList;
+}
+
/*!
* \brief Read the albumart image from the file
*
@@ -313,7 +335,7 @@ QImage MetaIOID3::getAlbumArt(QString filename, ImageType type)
*/
AlbumArtList MetaIOID3::readAlbumArt(TagLib::ID3v2::Tag *tag)
{
- QList<struct AlbumArtImage> artlist;
+ AlbumArtList artlist;
if (!tag->frameListMap()["APIC"].isEmpty())
{
@@ -335,34 +357,38 @@ AlbumArtList MetaIOID3::readAlbumArt(TagLib::ID3v2::Tag *tag)
continue;
}
- AlbumArtImage art;
+ AlbumArtImage *art = new AlbumArtImage();
if (frame->description().isEmpty())
- {
- art.description.clear();
- }
- else {
- art.description = TStringToQString(frame->description());
- }
+ art->description.clear();
+ else
+ art->description = TStringToQString(frame->description());
- art.embedded = true;
+ art->embedded = true;
+
+ QString ext = getExtFromMimeType(TStringToQString(frame->mimeType()).toLower());
switch (frame->type())
{
case AttachedPictureFrame::FrontCover :
- art.imageType = IT_FRONTCOVER;
+ art->imageType = IT_FRONTCOVER;
+ art->filename = QString("front") + ext;
break;
case AttachedPictureFrame::BackCover :
- art.imageType = IT_BACKCOVER;
+ art->imageType = IT_BACKCOVER;
+ art->filename = QString("back") + ext;
break;
case AttachedPictureFrame::Media :
- art.imageType = IT_CD;
+ art->imageType = IT_CD;
+ art->filename = QString("cd") + ext;
break;
case AttachedPictureFrame::LeafletPage :
- art.imageType = IT_INLAY;
+ art->imageType = IT_INLAY;
+ art->filename = QString("inlay") + ext;
break;
case AttachedPictureFrame::Other :
- art.imageType = IT_UNKNOWN;
+ art->imageType = IT_UNKNOWN;
+ art->filename = QString("unknown") + ext;
break;
default:
VERBOSE(VB_GENERAL, "Music Scanner - APIC tag found "
@@ -377,6 +403,22 @@ AlbumArtList MetaIOID3::readAlbumArt(TagLib::ID3v2::Tag *tag)
return artlist;
}
+QString MetaIOID3::getExtFromMimeType(const QString &mimeType)
+{
+ if (mimeType == "image/png")
+ return QString(".png");
+ else if (mimeType == "image/jpeg" || mimeType == "image/jpg")
+ return QString(".jpg");
+ else if (mimeType == "image/gif")
+ return QString(".gif");
+ else if (mimeType == "image/bmp")
+ return QString(".bmp");
+
+ VERBOSE(VB_GENERAL, QString("Music Scanner - Unknow image mimetype found - %1").arg(mimeType));
+
+ return QString();
+}
+
/*!
* \brief Find an APIC tag by type and optionally description
*
@@ -403,17 +445,58 @@ AttachedPictureFrame* MetaIOID3::findAPIC(TagLib::ID3v2::Tag *tag,
/*!
* \brief Write the albumart image to the file
*
- * \param tag The ID3v2 tag object in which to look for Album Art
+ * \param filename The music file to add the albumart
+ * \param albumart The Album Art image to write
* \returns True if successful
+ *
+ * \Note We always save the image in JPEG format
*/
-bool MetaIOID3::writeAlbumArt(TagLib::ID3v2::Tag *tag, QByteArray *image,
- const AttachedPictureFrame::Type &type,
- const QString &mimetype)
+bool MetaIOID3::writeAlbumArt(const QString &filename, const AlbumArtImage *albumart)
{
- if (!tag || !image)
+ if (filename.isEmpty() || !albumart)
+ return false;
+
+ // load the image into a QByteArray
+ QImage image(albumart->filename);
+ QByteArray imageData;
+ QBuffer buffer(&imageData);
+ buffer.open(QIODevice::WriteOnly);
+ image.save(&buffer, "JPEG");
+
+ AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
+ switch (albumart->imageType)
+ {
+ case IT_FRONTCOVER:
+ type = AttachedPictureFrame::FrontCover;
+ break;
+ case IT_BACKCOVER:
+ type = AttachedPictureFrame::BackCover;
+ break;
+ case IT_CD:
+ type = AttachedPictureFrame::Media;
+ break;
+ case IT_INLAY:
+ type = AttachedPictureFrame::LeafletPage;
+ break;
+ default:
+ type = AttachedPictureFrame::Other;
+ break;
+ }
+
+ TagLib::MPEG::File *mpegfile = OpenFile(filename);
+
+ if (!mpegfile)
return false;
- AttachedPictureFrame *apic = findAPIC(tag, type);
+ TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();
+
+ if (!tag)
+ {
+ delete mpegfile;
+ return false;
+ }
+
+ AttachedPictureFrame *apic = findAPIC(tag, type, QStringToTString(albumart->description));
if (!apic)
{
@@ -422,12 +505,77 @@ bool MetaIOID3::writeAlbumArt(TagLib::ID3v2::Tag *tag, QByteArray *image,
apic->setType(type);
}
+ QString mimetype = "image/jpeg";
+
TagLib::ByteVector bytevector;
- bytevector.setData(image->data(), image->size());
- delete image;
+ bytevector.setData(imageData.data(), imageData.size());
apic->setMimeType(QStringToTString(mimetype));
apic->setPicture(bytevector);
+ apic->setDescription(QStringToTString(albumart->description));
+
+ mpegfile->save();
+ delete mpegfile;
+
+ return true;
+}
+
+/*!
+ * \brief Remove the albumart image from the file
+ *
+ * \param filename The music file to remove the albumart
+ * \param albumart The Album Art image to remove
+ * \returns True if successful
+ */
+bool MetaIOID3::removeAlbumArt(const QString &filename, const AlbumArtImage *albumart)
+{
+ if (filename.isEmpty() || !albumart)
+ return false;
+
+ AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
+ switch (albumart->imageType)
+ {
+ case IT_FRONTCOVER:
+ type = AttachedPictureFrame::FrontCover;
+ break;
+ case IT_BACKCOVER:
+ type = AttachedPictureFrame::BackCover;
+ break;
+ case IT_CD:
+ type = AttachedPictureFrame::Media;
+ break;
+ case IT_INLAY:
+ type = AttachedPictureFrame::LeafletPage;
+ break;
+ default:
+ type = AttachedPictureFrame::Other;
+ break;
+ }
+
+ TagLib::MPEG::File *mpegfile = OpenFile(filename);
+
+ if (!mpegfile)
+ return false;
+
+ TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();
+
+ if (!tag)
+ {
+ delete mpegfile;
+ return false;
+ }
+
+ AttachedPictureFrame *apic = findAPIC(tag, type, QStringToTString(albumart->description));
+ if (!apic)
+ {
+ delete mpegfile;
+ return false;
+ }
+
+ tag->removeFrame(apic);
+
+ mpegfile->save();
+ delete mpegfile;
return true;
}
View
16 mythplugins/mythmusic/mythmusic/metaioid3.h
@@ -24,8 +24,6 @@ using TagLib::ID3v2::PopularimeterFrame;
using TagLib::ID3v2::AttachedPictureFrame;
using TagLib::MPEG::Properties;
-typedef QList<struct AlbumArtImage> AlbumArtList;
-
/*!
* \class MetaIOID3
*
@@ -44,23 +42,27 @@ class MetaIOID3 : public MetaIOTagLib
bool write(Metadata* mdata);
bool writeVolatileMetadata(const Metadata* mdata);
- bool writePlayCount(TagLib::ID3v2::Tag *tag, int playcount);
- bool writeRating(TagLib::ID3v2::Tag *tag, int rating);
- bool writeAlbumArt(TagLib::ID3v2::Tag *tag, QByteArray *image,
- const AttachedPictureFrame::Type &type,
- const QString &mimetype);
+ bool writeAlbumArt(const QString &filename, const AlbumArtImage *albumart);
+ bool removeAlbumArt(const QString &filename, const AlbumArtImage *albumart);
Metadata* read(QString filename);
+ AlbumArtList getAlbumArtList(const QString &filename);
static QImage getAlbumArt(QString filename, ImageType type);
+ bool supportsEmbeddedImages(void) { return true; }
+
private:
TagLib::MPEG::File *OpenFile(const QString &filename);
+ bool writePlayCount(TagLib::ID3v2::Tag *tag, int playcount);
+ bool writeRating(TagLib::ID3v2::Tag *tag, int rating);
+
AlbumArtList readAlbumArt(TagLib::ID3v2::Tag *tag);
UserTextIdentificationFrame* find(TagLib::ID3v2::Tag *tag, const String &description);
PopularimeterFrame* findPOPM(TagLib::ID3v2::Tag *tag, const String &email);
AttachedPictureFrame* findAPIC(TagLib::ID3v2::Tag *tag, const AttachedPictureFrame::Type &type,
const String &description = String::null);
+ QString getExtFromMimeType(const QString &mimeType);
};
#endif

0 comments on commit a52601a

Please sign in to comment.
Something went wrong with that request. Please try again.