Ticket #2942: mythmusic_apic2.diff

File mythmusic_apic2.diff, 17.4 KB (added by myth@…, 5 years ago)

updated version that works on files with "Other" type images.

  • mythmusic/mythmusic/visualize.cpp

     
    389389    return false; 
    390390} 
    391391 
    392 QString AlbumArt::getImageFilename()  
    393 { 
    394     return m_pParent->metadata()->getAlbumArt(m_currImageType); 
    395 } 
    396  
    397392bool AlbumArt::draw(QPainter *p, const QColor &back) 
    398393{ 
    399394    if (!m_pParent->decoder()) 
     
    402397    // If the directory has changed (new album) or the size, reload 
    403398    if (needsUpdate()) 
    404399    { 
    405         QImage art(getImageFilename()); 
     400        QImage art(m_pParent->metadata()->getAlbumArt(m_currImageType)); 
    406401        if (art.isNull()) 
    407402        { 
    408403            m_cursize = m_size; 
  • mythmusic/mythmusic/metadata.cpp

     
    381381 
    382382    if (m_id < 1 && query.isActive() && 1 == query.numRowsAffected()) 
    383383        m_id = query.lastInsertId().toInt(); 
     384 
     385    if (! m_albumart.empty()) 
     386    { 
     387        QValueList<struct AlbumArtImage>::iterator it; 
     388        for ( it = m_albumart.begin(); it != m_albumart.end(); ++it ) 
     389        { 
     390            query.prepare("INSERT INTO music_albumart ( filename, " 
     391                        "imagetype, song_id, embedded ) VALUES ( " 
     392                        ":FILENAME, :TYPE, :SONGID, :EMBED );"); 
     393 
     394            query.bindValue(":FILENAME", (*it).description); 
     395            query.bindValue(":TYPE", (*it).imageType); 
     396            query.bindValue(":SONGID", m_id); 
     397            query.bindValue(":EMBED", 1); 
     398 
     399            if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0) 
     400            { 
     401                MythContext::DBError("music insert albumart", query); 
     402            } 
     403        } 
     404    } 
    384405} 
    385406 
    386407// Default values for formats 
     
    616637    m_changed = true; 
    617638} 
    618639 
     640void Metadata::setEmbeddedAlbumArt(QValueList<struct AlbumArtImage> albumart) 
     641{ 
     642    m_albumart = albumart; 
     643} 
     644 
    619645QStringList Metadata::fillFieldList(QString field) 
    620646{ 
    621647    QStringList searchList; 
     
    658684    return searchList; 
    659685} 
    660686 
    661 QStringList Metadata::AlbumArtInDir(QString directory) 
     687QImage Metadata::getAlbumArt(ImageType type) 
    662688{ 
    663     QStringList paths; 
     689    AlbumArtImages albumArt(this); 
    664690 
    665     directory.remove(0, m_startdir.length()); 
     691    QImage image; 
    666692 
    667     MSqlQuery query(MSqlQuery::InitCon()); 
    668     query.prepare("SELECT CONCAT_WS('/', music_directories.path, " 
    669                   "music_albumart.filename) FROM music_albumart " 
    670                   "LEFT JOIN music_directories ON " 
    671                   "music_directories.directory_id=music_albumart.directory_id " 
    672                   "WHERE music_directories.path = :DIR;"); 
    673     query.bindValue(":DIR", directory.utf8()); 
    674     if (query.exec()) 
     693    if (albumArt.isImageEmbedded(type)) 
    675694    { 
    676         while (query.next()) 
    677         { 
    678             paths += m_startdir + "/" + 
    679                 QString::fromUtf8(query.value(0).toString()); 
    680         } 
     695        image = QImage(MetaIOTagLib::getAlbumArt(m_filename, type)); 
    681696    } 
    682     return paths; 
    683 } 
     697    else 
     698    { 
     699        image = QImage(albumArt.getImageFilename(type)); 
     700    } 
    684701 
    685 QString Metadata::getAlbumArt(ImageType type) 
    686 { 
    687     QString res = ""; 
    688     AlbumArtImages albumArt(this); 
    689  
    690     res = albumArt.getImageFilename(type); 
    691  
    692     return res; 
     702    return image; 
    693703} 
    694704 
    695705MetadataLoadingThread::MetadataLoadingThread(AllMusic *parent_ptr) 
     
    13751385/**************************************************************************/ 
    13761386 
    13771387AlbumArtImages::AlbumArtImages(Metadata *metadata) 
     1388    : m_parent(metadata) 
    13781389{ 
    1379     m_parent = metadata; 
    13801390    m_imageList.setAutoDelete(true); 
    13811391 
    13821392    findImages(); 
     
    13861396{ 
    13871397    m_imageList.clear(); 
    13881398 
     1399    if (m_parent == NULL) 
     1400        return; 
     1401 
     1402    int trackid = m_parent->ID(); 
     1403 
    13891404    QFileInfo fi(m_parent->Filename()); 
    13901405    QString dir = fi.dirPath(true); 
    13911406    dir.remove(0, Metadata::GetStartdir().length()); 
    13921407 
    13931408    MSqlQuery query(MSqlQuery::InitCon()); 
    13941409    query.prepare("SELECT albumart_id, CONCAT_WS('/', music_directories.path, " 
    1395             "music_albumart.filename), music_albumart.imagetype " 
     1410            "music_albumart.filename), music_albumart.imagetype, " 
     1411            "music_albumart.embedded " 
    13961412            "FROM music_albumart " 
    13971413            "LEFT JOIN music_directories ON " 
    13981414            "music_directories.directory_id=music_albumart.directory_id " 
    13991415            "WHERE music_directories.path = :DIR " 
     1416            "OR song_id = :SONGID " 
    14001417            "ORDER BY music_albumart.imagetype;"); 
    14011418    query.bindValue(":DIR", dir.utf8()); 
     1419    query.bindValue(":SONGID", trackid); 
    14021420    if (query.exec()) 
    14031421    { 
    14041422        while (query.next()) 
     
    14091427                    QString::fromUtf8(query.value(1).toString()); 
    14101428            image->imageType = (ImageType) query.value(2).toInt(); 
    14111429            image->typeName = getTypeName(image->imageType); 
     1430            if (query.value(3).toInt() == 1) 
     1431            { 
     1432                image->description = query.value(1).toString(); 
     1433                image->embedded = true; 
     1434            } 
     1435            else { 
     1436                image->embedded = false; 
     1437            } 
    14121438            m_imageList.append(image); 
    14131439        } 
    14141440    } 
     
    14221448    for (image = m_imageList.first(); image; image = m_imageList.next()) 
    14231449    { 
    14241450        if (image->imageType == type) 
     1451        { 
     1452            if (image->embedded) 
     1453                return "embedded"; 
     1454 
    14251455            return image->filename; 
     1456        } 
    14261457    } 
    14271458 
    14281459    return ""; 
     
    14421473    return paths; 
    14431474} 
    14441475 
     1476AlbumArtImage AlbumArtImages::getImageAt(uint index)  
     1477{ 
     1478    return *(m_imageList.at(index)); 
     1479} 
     1480 
     1481bool AlbumArtImages::isImageEmbedded(ImageType type) 
     1482{ 
     1483    AlbumArtImage *image; 
     1484 
     1485    for (image = m_imageList.first(); image; image = m_imageList.next()) 
     1486    { 
     1487        if (image->imageType == type) 
     1488            return image->embedded; 
     1489    } 
     1490 
     1491    return false; 
     1492} 
     1493 
    14451494bool AlbumArtImages::isImageAvailable(ImageType type) 
    14461495{ 
    14471496    // try to find a matching image 
  • mythmusic/mythmusic/dbcheck.cpp

     
    99#include "mythtv/mythcontext.h" 
    1010#include "mythtv/mythdbcon.h" 
    1111 
    12 const QString currentDatabaseVersion = "1011"; 
     12const QString currentDatabaseVersion = "1012"; 
    1313 
    1414static bool UpdateDBVersionNumber(const QString &newnumber) 
    1515{    
     
    587587            return false; 
    588588 
    589589    } 
     590 
     591    if (dbver == "1011") 
     592    { 
     593        const QString updates[] = { 
     594"ALTER TABLE music_albumart ADD COLUMN song_id int(11) NOT NULL DEFAULT '0', ADD COLUMN embedded TINYINT(1) NOT NULL DEFAULT '0';", 
     595        "" 
     596}; 
     597 
     598        if (!performActualUpdate(updates, "1012", dbver)) 
     599            return false; 
     600 
     601    } 
    590602/* in 0.21 */ 
    591603//"DROP TABLE musicmetadata;", 
    592604//"DROP TABLE musicplaylist;", 
  • mythmusic/mythmusic/metadata.h

     
    44#include <qstring.h> 
    55#include <qstringlist.h> 
    66#include <qptrlist.h> 
     7#include <qvaluelist.h> 
    78#include <qmap.h> 
    89#include <qthread.h> 
    910 
    1011#include "treecheckitem.h" 
    1112#include <mythtv/uitypes.h> 
    1213 
     14 
    1315class AllMusic; 
    1416class CoverArt; 
    1517 
     
    2325    IT_LAST 
    2426}; 
    2527 
     28#include "metaiotaglib.h" 
     29 
    2630typedef struct AlbumArtImage 
    2731{ 
    2832    int       id; 
    2933    QString   filename; 
    3034    ImageType imageType; 
    3135    QString   typeName; 
     36    QString   description; 
     37    bool      embedded; 
    3238} AlbumArtImage; 
    3339 
     40//typedef QValueList<struct AlbumArtImage> AlbumArtList; 
     41 
    3442class Metadata 
    3543{ 
    3644  public: 
     
    5967                   m_lastplay(llastplay), 
    6068                   m_playcount(lplaycount), 
    6169                   m_compilation(lcompilation), 
     70                   m_albumart(), 
    6271                   m_id(lid), 
    6372                   m_filename(lfilename), 
    6473                   m_changed(false), 
     
    159168    } 
    160169    bool determineIfCompilation(bool cd = false); 
    161170 
     171    void setEmbeddedAlbumArt(QValueList<struct AlbumArtImage> art); 
     172 
    162173    bool isInDatabase(void); 
    163174    void dumpToDatabase(void); 
    164175    void setField(const QString &field, const QString &data); 
     
    173184 
    174185    static QStringList fillFieldList(QString field); 
    175186 
    176     QStringList AlbumArtInDir(QString directory); 
    177     QString getAlbumArt(ImageType type); 
     187    QImage getAlbumArt(ImageType type); 
    178188 
    179189  private: 
    180190    void setCompilationFormatting(bool cd = false); 
     
    201211    QString m_lastplay; 
    202212    int m_playcount; 
    203213    bool m_compilation; 
     214    QValueList<struct AlbumArtImage> m_albumart; 
    204215 
    205216    unsigned int m_id; 
    206217    QString m_filename; 
     
    394405    QStringList              getImageFilenames(); 
    395406    QPtrList<AlbumArtImage> *getImageList() { return &m_imageList; } 
    396407    AlbumArtImage            getImageAt(uint index); 
     408        bool                     isImageEmbedded(ImageType type); 
    397409 
    398410    bool isImageAvailable(ImageType type); 
    399411 
  • mythmusic/mythmusic/metaiotaglib.h

     
    22#define METAIOTAGLIB_H_ 
    33 
    44#include "metaio.h" 
     5#include "metadata.h" 
    56#include <id3v2tag.h> 
    67#include <textidentificationframe.h> 
     8#include <attachedpictureframe.h> 
    79#include <mpegfile.h> 
     10#include <mpegproperties.h> 
    811 
    912using TagLib::MPEG::File; 
    1013using TagLib::Tag; 
    1114using TagLib::ID3v2::UserTextIdentificationFrame; 
     15using TagLib::ID3v2::AttachedPictureFrame; 
    1216using TagLib::String; 
     17using TagLib::MPEG::Properties; 
    1318 
    1419class MetaIOTagLib : public MetaIO 
    1520{ 
     
    2025    bool write(Metadata* mdata, bool exclusive = false); 
    2126    Metadata* read(QString filename); 
    2227 
     28    static QImage getAlbumArt(QString filename, ImageType type); 
     29 
    2330private: 
    2431 
    25      int getTrackLength(QString filename); 
     32    int getTrackLength(QString filename); 
    2633 
    27      UserTextIdentificationFrame* find(TagLib::ID3v2::Tag *tag, const String &description); 
     34    QValueList<struct AlbumArtImage> readAlbumArt(TagLib::ID3v2::Tag *tag); 
     35    UserTextIdentificationFrame* find(TagLib::ID3v2::Tag *tag, const String &description); 
    2836}; 
    2937 
    3038#endif 
  • mythmusic/mythmusic/metaiotaglib.cpp

     
    102102            genre = ""; 
    103103    int year = 0, tracknum = 0, length = 0, playcount = 0, rating = 0, id = 0; 
    104104    bool compilation = false; 
     105    QValueList<struct AlbumArtImage> albumart; 
    105106 
    106107    QString extension = filename.section( '.', -1 ) ; 
    107108 
     
    151152        // Length 
    152153        if(!taglib->ID3v2Tag()->frameListMap()["TLEN"].isEmpty()) 
    153154            length = taglib->ID3v2Tag()->frameListMap()["TLEN"].front()->toString().toInt(); 
     155 
     156        // Album Art 
     157        if(!taglib->ID3v2Tag()->frameListMap()["APIC"].isEmpty()) 
     158        { 
     159            albumart = readAlbumArt(taglib->ID3v2Tag()); 
     160        } 
    154161    } 
    155162 
    156163    // Fallback to filename reading 
     
    183190                                     id, rating, playcount); 
    184191 
    185192    retdata->setCompilation(compilation); 
     193    retdata->setEmbeddedAlbumArt(albumart); 
    186194 
    187195    return retdata; 
    188196} 
     
    203211} 
    204212 
    205213/*! 
     214 * \brief Read the albumart image from the file 
     215 * 
     216 * \param filename The filename for which we want to find the length. 
     217 * \param type The type of image we want - front/back etc 
     218 * \returns A QByteArray that can contains the image data. 
     219 */ 
     220QImage MetaIOTagLib::getAlbumArt(QString filename, ImageType type) 
     221{ 
     222    QImage picture; 
     223 
     224    AttachedPictureFrame::Type apicType  
     225        = AttachedPictureFrame::FrontCover; 
     226 
     227    switch (type) 
     228    { 
     229        case IT_UNKNOWN : 
     230            apicType = AttachedPictureFrame::Other; 
     231            break; 
     232        case IT_FRONTCOVER : 
     233            apicType = AttachedPictureFrame::FrontCover; 
     234            break; 
     235        case IT_BACKCOVER : 
     236            apicType = AttachedPictureFrame::BackCover; 
     237            break; 
     238        case IT_CD : 
     239            apicType = AttachedPictureFrame::Media; 
     240            break; 
     241        case IT_INLAY : 
     242            apicType = AttachedPictureFrame::LeafletPage; 
     243            break; 
     244        default: 
     245            return picture; 
     246    } 
     247 
     248    File *taglib = new TagLib::MPEG::File(filename.local8Bit()); 
     249 
     250    if (taglib->isOpen() && !taglib->ID3v2Tag()->frameListMap()["APIC"].isEmpty()) 
     251    { 
     252        TagLib::ID3v2::FrameList apicframes = taglib->ID3v2Tag()->frameListMap()["APIC"]; 
     253 
     254        for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin(); it != apicframes.end(); ++it) { 
     255            AttachedPictureFrame *frame = static_cast<AttachedPictureFrame *>(*it); 
     256            if(frame && frame->type() == apicType) 
     257            { 
     258                QImage picture; 
     259                picture.loadFromData((const uchar *)frame->picture().data(), frame->picture().size()); 
     260                return picture; 
     261            } 
     262        } 
     263    } 
     264 
     265    return picture; 
     266} 
     267 
     268/*! 
     269 * \brief Read the albumart image from the file 
     270 * 
     271 * \param tag The ID3v2 tag object in which to look for Album Art 
     272 * \returns A QValueList containing a list of AlbumArtImage structs 
     273 *          with the type and description of the APIC tag. 
     274 */ 
     275QValueList<struct AlbumArtImage> MetaIOTagLib::readAlbumArt(TagLib::ID3v2::Tag *tag) 
     276{ 
     277 
     278    QValueList<struct AlbumArtImage> artlist; 
     279 
     280    if (!tag->frameListMap()["APIC"].isEmpty()) 
     281    { 
     282        TagLib::ID3v2::FrameList apicframes = tag->frameListMap()["APIC"]; 
     283 
     284        for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin(); 
     285            it != apicframes.end(); ++it) 
     286        { 
     287 
     288            AttachedPictureFrame *frame = 
     289                static_cast<AttachedPictureFrame *>(*it); 
     290 
     291            AlbumArtImage art; 
     292 
     293            if (!frame->description().isEmpty()) 
     294            { 
     295                art.description = TStringToQString(frame->description()); 
     296            } else  
     297            { 
     298                art.description = ""; 
     299            } 
     300 
     301            art.embedded = true; 
     302 
     303            switch (frame->type()) 
     304            { 
     305                case AttachedPictureFrame::FrontCover : 
     306                    art.imageType = IT_FRONTCOVER; 
     307                    art.typeName = "Front Cover"; 
     308                    break; 
     309                case AttachedPictureFrame::BackCover : 
     310                    art.imageType = IT_BACKCOVER; 
     311                    art.typeName = "Back Cover"; 
     312                    break; 
     313                case AttachedPictureFrame::Media : 
     314                    art.imageType = IT_CD; 
     315                    art.typeName = "CD"; 
     316                    break; 
     317                case AttachedPictureFrame::LeafletPage : 
     318                    art.imageType = IT_INLAY; 
     319                    art.typeName = "Inlay"; 
     320                    break; 
     321                case AttachedPictureFrame::Other : 
     322                    art.imageType = IT_UNKNOWN; 
     323                    art.typeName = "Other"; 
     324                    break; 
     325                default: 
     326                    VERBOSE(VB_GENERAL, "Music Scanner - APIC tag found " 
     327                                        "with unsupported type"); 
     328                    continue; 
     329            } 
     330 
     331            artlist.append(art); 
     332        } 
     333    } 
     334 
     335    return artlist; 
     336} 
     337 
     338/*! 
    206339 * \brief Find the a custom comment tag by description. 
    207340 *        This is a copy of the same function in the 
    208341 *        TagLib::ID3v2::UserTextIdentificationFrame Class with a static 
  • mythmusic/mythmusic/mainvisual.cpp

     
    350351        return; 
    351352 
    352353    QString  text = "\"" + mdata->Title() + "\"\n" +  mdata->Artist() + "\n" + mdata->Album(); 
    353     QString albumArt = mdata->getAlbumArt(IT_FRONTCOVER); 
     354    QImage albumArt = mdata->getAlbumArt(IT_FRONTCOVER); 
    354355 
    355356    if (text == info) 
    356357        return; 
     
    370371    } 
    371372 
    372373    // ...and only then when we have an album art image to show 
    373     if (visMode != 2 && fullScreen && albumArt == "") 
     374    if (visMode != 2 && fullScreen && ! albumArt.isNull()) 
    374375    { 
    375376        hide(); 
    376377        return; 
    377378    } 
    378379 
    379     if (fullScreen && albumArt != "") 
     380    if (fullScreen && ! albumArt.isNull()) 
    380381    { 
    381382        resize(parentWidget()->width(), parentWidget()->height()); 
    382383        move(0, 0); 
     
    400401    int x = indent; 
    401402    int y = indent; 
    402403 
    403     if (fullScreen && albumArt != "") 
     404    if (fullScreen && ! albumArt.isNull()) 
    404405    { 
    405406        p.fillRect(0, 0, info_pixmap.width(), info_pixmap.height(), QColor ("black")); 
    406407 
     
    419420    { 
    420421        p.fillRect(0, 0, info_pixmap.width(), info_pixmap.height(), QColor ("darkblue")); 
    421422 
    422         if (albumArt != "") 
     423        if (! albumArt.isNull()) 
    423424        { 
    424425            // draw the albumArt image 
    425426 
  • mythmusic/mythmusic/visualize.h

     
    9191 
    9292  private: 
    9393    bool needsUpdate(void); 
    94     QString getImageFilename(void); 
    9594    void findFrontCover(void); 
    9695 
    9796    QSize m_size, m_cursize;