Meta::FieldHash MP4TagHelper::tags() const { Meta::FieldHash data = TagHelper::tags(); TagLib::MP4::ItemListMap map = m_tag->itemListMap(); for( TagLib::MP4::ItemListMap::ConstIterator it = map.begin(); it != map.end(); ++it ) { qint64 field; QString value = TStringToQString( it->second.toStringList().toString( '\n' ) ); if( ( field = fieldName( it->first ) ) ) { if( field == Meta::valHasCover ) { TagLib::MP4::CoverArtList coverList = it->second.toCoverArtList(); for( TagLib::MP4::CoverArtList::ConstIterator it = coverList.begin(); it != coverList.end(); ++it ) if( it->data().size() > MIN_COVER_SIZE ) { data.insert( field, true ); break; } } // http://gitorious.org/~jefferai/xdg-specs/jefferais-xdg-specs/blobs/mediaspecs/specifications/FMPSpecs/specification.txt sais that mp4 tags should be saved as strings else if( field == Meta::valPlaycount ) data.insert( field, value.toInt() ); else if( field == Meta::valRating ) data.insert( field, qRound( value.toFloat() * 10.0 ) ); else if( field == Meta::valScore ) data.insert( field, value.toFloat() * 100.0 ); else if( field == Meta::valBpm ) data.insert( field, it->second.toInt() ); else if( field == Meta::valDiscNr ) data.insert( field, it->second.toIntPair().first ); else if( field == Meta::valCompilation ) data.insert( field, it->second.toBool() ); else data.insert( field, value ); } else if( it->first == uidFieldName( UIDAFT ) && isValidUID( value, UIDAFT ) ) data.insert( Meta::valUniqueId, value ); } return data; }
QImage MP4TagHelper::embeddedCover() const { TagLib::MP4::ItemListMap map = m_tag->itemListMap(); TagLib::String name = fieldName( Meta::valHasCover ); for( TagLib::MP4::ItemListMap::ConstIterator it = map.begin(); it != map.end(); ++it ) { if( it->first == name ) { TagLib::MP4::CoverArtList coverList = it->second.toCoverArtList(); for( TagLib::MP4::CoverArtList::Iterator cover = coverList.begin(); cover != coverList.end(); ++cover ) { if( cover->data().size() > MIN_COVER_SIZE ) return QImage::fromData( ( uchar * ) cover->data().data(), cover->data().size() ); } } } return QImage(); }
bool CoverUtils::coverFromMP4(QString filename, Album *album) { TagLib::MP4::File f((TagLib::FileName)filename.toUtf8()); if (!f.isValid()) return false; TagLib::MP4::Tag *tag = static_cast<TagLib::MP4::Tag *>(f.tag()); if (!tag) return false; TagLib::MP4::ItemListMap itemsListMap = tag->itemListMap(); TagLib::MP4::Item coverItem = itemsListMap["covr"]; TagLib::MP4::CoverArtList coverArtList = coverItem.toCoverArtList(); TagLib::MP4::CoverArt coverArt = coverArtList.front(); QImage image; image.loadFromData((const uchar *) coverArt.data().data(), coverArt.data().size()); if (!isAcceptableImage(image)) return false; qDebug() << "Cover from MP4!"; return saveImage(image, album); }
bool MP4TagHelper::setEmbeddedCover( const QImage &cover ) { QByteArray bytes; QBuffer buffer( &bytes ); buffer.open( QIODevice::WriteOnly ); if( !cover.save( &buffer, "JPEG" ) ) { buffer.close(); return false; } buffer.close(); TagLib::MP4::CoverArtList covers; covers.append( TagLib::MP4::CoverArt( TagLib::MP4::CoverArt::JPEG, TagLib::ByteVector( bytes.data(), bytes.count() ) ) ); m_tag->itemListMap()[fieldName( Meta::valHasCover )] = TagLib::MP4::Item( covers ); return true; }
void LocalSong::setInfo(const QString &filePath) { QFileInfo fileInfo(filePath); fileExtension = fileInfo.completeSuffix(); QString singer=""; QString sname=""; QString album=""; QImage covpic; if(fileExtension == "m4a") { TagLib::MP4::File *mp4File = new TagLib::MP4::File( QFile::encodeName(filePath).constData()); if(false==mp4File->isOpen()) return; sname=QString(mp4File->tag()->title().toCString(true)); singer=QString(mp4File->tag()->artist().toCString(true)); album=QString(mp4File->tag()->album().toCString(true)); TagLib::MP4::ItemListMap itemListMap = mp4File->tag()->itemListMap(); TagLib::MP4::Item albumArtItem = itemListMap["covr"]; TagLib::MP4::CoverArtList albumArtList = albumArtItem.toCoverArtList(); TagLib::MP4::CoverArt albumArt = albumArtList.front(); QImage cover; cover.loadFromData((const uchar *) albumArt.data().data(), albumArt.data().size()); covpic = cover.scaled( 50, 50, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); if(!covpic.isNull()) { qDebug()<<"读取M4A封面信息成功"; }else { covpic.load(":/image/image/playIcon.png"); qDebug()<<"读取音乐封面信息失败"; } } else if(fileExtension == "mp3") { TagLib::MPEG::File *mpegFile = new TagLib::MPEG::File( QFile::encodeName(filePath).constData()); if(false==mpegFile->isOpen()) return; else { sname=QString(mpegFile->tag()->title().toCString(true)); singer=QString(mpegFile->tag()->artist().toCString(true)); album=QString(mpegFile->tag()->album().toCString(true)); auto tag = mpegFile->ID3v2Tag(false); auto list = tag->frameListMap()["APIC"]; if(!list.isEmpty()) { auto frame = list.front(); auto pic = reinterpret_cast<TagLib::ID3v2::AttachedPictureFrame *>(frame); if(pic && !pic->picture().isNull()) { QImage cover; if(cover.loadFromData(QByteArray::fromRawData(pic->picture().data(), pic->picture().size()))) { covpic = cover.scaled( 50, 50, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); qDebug()<<"读取MP3封面信息成功"; } } } else { covpic.load(":/image/image/playIcon.png"); qDebug()<<"读取音乐封面信息失败"; } } } singerlist.append(singer); snamelist.append(sname); albumlist.append(album); covPiclist.append(covpic); int covCount=covPiclist.length(); QString covpicpath=QDir::tempPath()+QString("/%1.png").arg(covCount); covpic.save(covpicpath); QUrl covpicUrl=QUrl::fromLocalFile(covpicpath); qDebug()<<"歌名为"<<sname; qDebug()<<"歌手为"<<singer; qDebug()<<"专辑为"<<album; qDebug()<<"URL为"<<covpicUrl; emit setSongInfo(singer,sname,album,covpicUrl); return; }