示例#1
0
/* GET ALBUM COVER
 */
const char * tag_data_get_cover (TagDatac * data, uint * len)
{
    TagLib::ID3v2::AttachedPictureFrame * pic = NULL;
    if (!(reinterpret_cast<TagData *>(data))->id3v2 || (reinterpret_cast<TagData *>(data))->id3v2->frameListMap()["APIC"].isEmpty())
    {
        *len = 0;
        return NULL;
    }

    TagLib::ID3v2::FrameList::ConstIterator it;
    TagLib::ID3v2::FrameList l = (reinterpret_cast<TagData *>(data))->id3v2->frameListMap()["APIC"];
    for(it=l.begin(); it!=l.end(); ++it)
    {
        TagLib::ID3v2::AttachedPictureFrame * t = dynamic_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it);
        if (pic == NULL)
            pic = t;
        if (t->type () == TagLib::ID3v2::AttachedPictureFrame::FrontCover)
        {
            pic = t;
            break;
        }
    }
    if (pic == NULL)
    {
        *len = 0;
        return NULL;
    }
    *len = pic->picture ().size ();
	const char * out = (const char *) malloc (*len);
    memcpy ((void *) out, pic->picture ().data(), *len);
    return out;
}
示例#2
0
ID3v2Tag::ID3v2Tag( TagLib::Tag *tag, TagLib::ID3v2::Tag *id3v2Tag )
    : Tag( tag )
    , m_id3v2Tag( id3v2Tag )
{
    TagLib::ID3v2::FrameList fList = m_id3v2Tag->frameList();
    for( TagLib::ID3v2::FrameList::ConstIterator it = fList.begin();
         it != fList.end(); ++it )
    {
        TagLib::String frameId = TagLib::String( (*it)->frameID() );
        TagLib::ID3v2::TextIdentificationFrame *frame =
                dynamic_cast< TagLib::ID3v2::TextIdentificationFrame * >( *it );
        if( frame )
        {
            QString val = TStringToQString( frame->fieldList().toString( '\n' ) );

            if( frameId == TagLib::String( "TPE2" ) ) //album artist
            {
                m_albumArtist = val;
            }
            else if( frameId == TagLib::String( "TCOM" ) ) //composer
            {
                m_composer = val;
            }
            else if( frameId == TagLib::String( "TPOS" ) ) //disc number
            {
                m_discNumber = processDiscNumber( val );
            }
        }
    }
}
示例#3
0
/* GET REPLAY GAIN
 */
 float tag_data_get_gain (TagDatac * data)
{

    if ((reinterpret_cast<TagData *>(data))->xiph && !(reinterpret_cast<TagData *>(data))->xiph->fieldListMap()["REPLAYGAIN_ALBUM_GAIN"].isEmpty())
        return atof((reinterpret_cast<TagData *>(data))->xiph->fieldListMap()["REPLAYGAIN_ALBUM_GAIN"].front().toCString(1));
    if ((reinterpret_cast<TagData *>(data))->xiph && !(reinterpret_cast<TagData *>(data))->xiph->fieldListMap()["REPLAYGAIN_TRACK_GAIN"].isEmpty())
        return atof((reinterpret_cast<TagData *>(data))->xiph->fieldListMap()["REPLAYGAIN_TRACK_GAIN"].front().toCString(1));
    if ((reinterpret_cast<TagData *>(data))->xiph && !(reinterpret_cast<TagData *>(data))->xiph->fieldListMap()["RG_AUDIOPHILE"].isEmpty())
        return atof((reinterpret_cast<TagData *>(data))->xiph->fieldListMap()["RG_AUDIOPHILE"].front().toCString(1));
    if ((reinterpret_cast<TagData *>(data))->xiph && !(reinterpret_cast<TagData *>(data))->xiph->fieldListMap()["RG_RADIO"].isEmpty())
        return atof((reinterpret_cast<TagData *>(data))->xiph->fieldListMap()["RG_RADIO"].front().toCString(1));


    if ((reinterpret_cast<TagData *>(data))->id3v2 && !(reinterpret_cast<TagData *>(data))->id3v2->frameListMap()["RVA2"].isEmpty())
    {
        TagLib::ID3v2::FrameList::ConstIterator it;
        TagLib::ID3v2::FrameList l = (reinterpret_cast<TagData *>(data))->id3v2->frameListMap()["RVA2"];
        for(it=l.begin(); it!=l.end(); ++it)
        {
            TagLib::ID3v2::RelativeVolumeFrame * rva = dynamic_cast<TagLib::ID3v2::RelativeVolumeFrame*>(*it);
            if (rva->channelType () == TagLib::ID3v2::RelativeVolumeFrame::MasterVolume)
                return rva->volumeAdjustment ();
        }
    }
    return 0.0;
}
示例#4
0
文件: tag.cpp 项目: jhanssen/Ornament
Tag::Tag(const QString &filename)
    : m_filename(filename)
{
    TagLib::MPEG::File mpegfile(filename.toLocal8Bit().constData());
    TagLib::ID3v2::Tag* id3v2 = mpegfile.ID3v2Tag();
    if (id3v2 && !id3v2->isEmpty()) {
        readRegularTag(id3v2, m_data);

        int picnum = 0;

        TagLib::ID3v2::FrameList frames = id3v2->frameListMap()["APIC"]; // attached picture
        TagLib::ID3v2::FrameList::ConstIterator it = frames.begin();
        while (it != frames.end()) {
            TagLib::ID3v2::AttachedPictureFrame* apic = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it);
            TagLib::ByteVector bytes = apic->picture();
            QImage img = QImage::fromData(reinterpret_cast<const uchar*>(bytes.data()), bytes.size());
            if (!img.isNull()) {
                m_data[QLatin1String("picture") + QString::number(picnum++)] = QVariant(img);
            }
            ++it;
        }

    } else {
        TagLib::FileRef fileref(filename.toLocal8Bit().constData());
        if (fileref.isNull())
            return;
        TagLib::Tag* tag = fileref.tag();
        if (!tag || tag->isEmpty())
            return;

        readRegularTag(tag, m_data);
    }
}
bool is_framelist_empty(const TagLib::ID3v2::FrameList &list)
{
	for (auto it = list.begin(); it != list.end(); ++it)
		if ((*it)->toString() != TagLib::String::null)
			return false;
	return true;
}
示例#6
0
/*!
 * \brief Read the albumart image from the file
 *
 * \param filename The filename for which we want to find the length.
 * \param type The type of image we want - front/back etc
 * \returns A pointer to a QImage owned by the caller or NULL if not found.
 */
QImage* MetaIOID3::getAlbumArt(QString filename, ImageType type)
{
    QImage *picture = new QImage();

    AttachedPictureFrame::Type apicType
        = AttachedPictureFrame::FrontCover;

    switch (type)
    {
        case IT_UNKNOWN :
            apicType = AttachedPictureFrame::Other;
            break;
        case IT_FRONTCOVER :
            apicType = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER :
            apicType = AttachedPictureFrame::BackCover;
            break;
        case IT_CD :
            apicType = AttachedPictureFrame::Media;
            break;
        case IT_INLAY :
            apicType = AttachedPictureFrame::LeafletPage;
            break;
        default:
            return picture;
    }

    QByteArray fname = filename.toLocal8Bit();
    TagLib::MPEG::File *mpegfile = new TagLib::MPEG::File(fname.constData());

    if (mpegfile)
    {
        if (mpegfile->isOpen()
            && !mpegfile->ID3v2Tag()->frameListMap()["APIC"].isEmpty())
        {
            TagLib::ID3v2::FrameList apicframes =
                                    mpegfile->ID3v2Tag()->frameListMap()["APIC"];

            for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin();
                it != apicframes.end(); ++it)
            {
                AttachedPictureFrame *frame =
                                    static_cast<AttachedPictureFrame *>(*it);
                if (frame && frame->type() == apicType)
                {
                    picture->loadFromData((const uchar *)frame->picture().data(),
                                          frame->picture().size());
                    return picture;
                }
            }
        }

        delete mpegfile;
    }

    delete picture;

    return NULL;
}
QImage
ID3v2TagHelper::embeddedCover() const
{
    TagLib::ID3v2::FrameList apicList = m_tag->frameListMap()[fieldName( Meta::valHasCover ).toCString()];
    TagLib::ID3v2::AttachedPictureFrame *cover = NULL;
    TagLib::ID3v2::AttachedPictureFrame *otherCover = NULL;

    for( TagLib::ID3v2::FrameList::ConstIterator it = apicList.begin(); it != apicList.end(); ++it )
    {
        TagLib::ID3v2::AttachedPictureFrame *currFrame =
                dynamic_cast< TagLib::ID3v2::AttachedPictureFrame * >( *it );

        if( currFrame->picture().size() < MIN_COVER_SIZE )
            continue;

        if( currFrame->type() == TagLib::ID3v2::AttachedPictureFrame::FrontCover )
        {
            cover = currFrame;
        }
        else if( currFrame->type() == TagLib::ID3v2::AttachedPictureFrame::Other )
        {
            otherCover = currFrame;
        }
    }

    if( !cover && otherCover )
        cover = otherCover;

    if( !cover )
        return QImage();

    return QImage::fromData( ( uchar * )( cover->picture().data() ), cover->picture().size() );
}
示例#8
0
bool MetaDSF::exportPictures(const char *prefix) const
{
  std::map<std::string, unsigned int> counter;
  TagLib::ID3v2::FrameList l = _i->_file.ID3v2Tag()->frameList("APIC");
  TagLib::ID3v2::FrameList::ConstIterator it;
  for (it = l.begin(); it != l.end(); ++it) {
    TagLib::ID3v2::AttachedPictureFrame *f =
      static_cast<TagLib::ID3v2::AttachedPictureFrame *>(*it);
    std::string fname = prefix;
    std::string tname = picTypeDesc[f->type()].toCString();
    std::string ext = MIMETypeToExtMap[f->mimeType()].toCString();
    if (counter.find(tname) == counter.end())
      counter[tname] = 1;
    else
      counter[tname] += 1;
    fname += "_";
    fname += tname;
    fname += "_";
    fname += std::to_string(counter[tname]);
    fname += ".";
    fname += ext;
    //std::cout << "fname = " << fname << std::endl;
    writeFileFromVector(fname.c_str(), f->picture());
  }
  return true;
}
示例#9
0
//// Private ////
void MetaDSF::MetaDSFImpl::deleteFrames(const TagLib::ID3v2::FrameList &l)
{
  TagLib::ID3v2::FrameList::ConstIterator it;

  for (it = l.begin(); it != l.end(); it++) {
    _file.ID3v2Tag()->removeFrame(*it);
  }
}
示例#10
0
// Too bad can't use STL copy alogirthm....
// copy(src.begin(), src.end(), back_inserter(dest));
void MetaDSF::MetaDSFImpl::dupFrameList(const TagLib::ID3v2::FrameList &src, 
					TagLib::ID3v2::FrameList &dest) 
{
  TagLib::ID3v2::FrameList::ConstIterator it;

  for (it = src.begin(); it != src.end(); it++) {
    dest.append(*it);
  }
}
示例#11
0
/*!
 * \brief Read the albumart image from the file
 *
 * \param filename The filename for which we want to find the albumart.
 * \param type The type of image we want - front/back etc
 * \returns A pointer to a QImage owned by the caller or nullptr if not found.
 */
QImage* MetaIOID3::getAlbumArt(const QString &filename, ImageType type)
{
    QImage *picture = new QImage();

    AttachedPictureFrame::Type apicType
        = AttachedPictureFrame::FrontCover;

    switch (type)
    {
        case IT_UNKNOWN :
            apicType = AttachedPictureFrame::Other;
            break;
        case IT_FRONTCOVER :
            apicType = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER :
            apicType = AttachedPictureFrame::BackCover;
            break;
        case IT_CD :
            apicType = AttachedPictureFrame::Media;
            break;
        case IT_INLAY :
            apicType = AttachedPictureFrame::LeafletPage;
            break;
        case IT_ARTIST :
            apicType = AttachedPictureFrame::Artist;
            break;
        default:
            return picture;
    }

    if (OpenFile(filename))
    {
        TagLib::ID3v2::Tag *tag = GetID3v2Tag();
        if (tag && !tag->frameListMap()["APIC"].isEmpty())
        {
            TagLib::ID3v2::FrameList apicframes = tag->frameListMap()["APIC"];

            for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin();
                it != apicframes.end(); ++it)
            {
                AttachedPictureFrame *frame =
                                    static_cast<AttachedPictureFrame *>(*it);
                if (frame && frame->type() == apicType)
                {
                    picture->loadFromData((const uchar *)frame->picture().data(),
                                         frame->picture().size());
                    return picture;
                }
            }
        }
    }

    delete picture;

    return nullptr;
}
示例#12
0
/*!
 * \brief Find the POPM tag associated with MythTV
 *
 * \param tag Pointer to TagLib::ID3v2::Tag object
 * \param email Email address associated with this POPM frame
 * \returns Pointer to frame
 */
PopularimeterFrame* MetaIOID3::findPOPM(TagLib::ID3v2::Tag *tag,
                                        const String &_email)
{
  TagLib::ID3v2::FrameList l = tag->frameList("POPM");
  for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
  {
    PopularimeterFrame *f = static_cast<PopularimeterFrame *>(*it);
    if (f && f->email() == _email)
      return f;
  }
  return nullptr;
}
示例#13
0
/*!
 * \brief Find the a custom comment tag by description.
 *        This is a copy of the same function in the
 *        TagLib::ID3v2::UserTextIdentificationFrame Class with a static
 *        instead of dynamic cast.
 *
 * \param tag Pointer to TagLib::ID3v2::Tag object
 * \param description Description of tag to search for
 * \returns Pointer to frame
 */
UserTextIdentificationFrame* MetaIOID3::find(TagLib::ID3v2::Tag *tag,
                                                const String &description)
{
  TagLib::ID3v2::FrameList l = tag->frameList("TXXX");
  for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
  {
    UserTextIdentificationFrame *f =
                                static_cast<UserTextIdentificationFrame *>(*it);
    if (f && f->description() == description)
      return f;
  }
  return nullptr;
}
示例#14
0
/*!
 * \brief Find an APIC tag by type and optionally description
 *
 * \param tag Pointer to TagLib::ID3v2::Tag object
 * \param type Type of picture to search for
 * \param description Description of picture to search for (optional)
 * \returns Pointer to frame
 */
AttachedPictureFrame* MetaIOID3::findAPIC(TagLib::ID3v2::Tag *tag,
                                        const AttachedPictureFrame::Type &type,
                                        const String &description)
{
  TagLib::ID3v2::FrameList l = tag->frameList("APIC");
  for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
  {
    AttachedPictureFrame *f = static_cast<AttachedPictureFrame *>(*it);
    if (f && f->type() == type &&
        (description.isNull() || f->description() == description))
      return f;
  }
  return nullptr;
}
示例#15
0
void MetaDSF::printTags(const char *prefix) const 
{
  if (_i->_file.ID3v2Tag()->isEmpty()) {
    return;
  }

  TagLib::ID3v2::FrameList l = _i->_file.ID3v2Tag()->frameList();
  TagLib::ID3v2::FrameList::ConstIterator it;
  
  for (it = l.begin(); it != l.end(); it++) {
    std::cout << prefix;
    std::cout << (*it)->frameID() << "=" << (*it)->toString() << std::endl;
  }
}
示例#16
0
bool SoundSource::processID3v2Tag(TagLib::ID3v2::Tag* id3v2) {

    // Print every frame in the file.
    if (s_bDebugMetadata) {
        TagLib::ID3v2::FrameList::ConstIterator it = id3v2->frameList().begin();
        for(; it != id3v2->frameList().end(); it++) {
            qDebug() << "ID3V2" << (*it)->frameID().data() << "-"
                    << TStringToQString((*it)->toString());
        }
    }

    TagLib::ID3v2::FrameList bpmFrame = id3v2->frameListMap()["TBPM"];
    if (!bpmFrame.isEmpty()) {
        QString sBpm = TStringToQString(bpmFrame.front()->toString());
        processBpmString("ID3v2", sBpm);
    }

    TagLib::ID3v2::FrameList keyFrame = id3v2->frameListMap()["TKEY"];
    if (!keyFrame.isEmpty()) {
        QString sKey = TStringToQString(keyFrame.front()->toString());
        setKey(sKey);
    }
    // Foobar2000-style ID3v2.3.0 tags
    // TODO: Check if everything is ok.
    TagLib::ID3v2::FrameList frames = id3v2->frameListMap()["TXXX"];
    for ( TagLib::ID3v2::FrameList::Iterator it = frames.begin(); it != frames.end(); ++it ) {
        TagLib::ID3v2::UserTextIdentificationFrame* ReplayGainframe =
                dynamic_cast<TagLib::ID3v2::UserTextIdentificationFrame*>( *it );
        if ( ReplayGainframe && ReplayGainframe->fieldList().size() >= 2 )
        {
            QString desc = TStringToQString( ReplayGainframe->description() ).toLower();
            if ( desc == "replaygain_album_gain" ){
                QString sReplayGain = TStringToQString( ReplayGainframe->fieldList()[1]);
                parseReplayGainString(sReplayGain);
            }
            if ( desc == "replaygain_track_gain" ){
                QString sReplayGain = TStringToQString( ReplayGainframe->fieldList()[1]);
                parseReplayGainString(sReplayGain);
            }
        }
    }
    TagLib::ID3v2::FrameList composerFrame = id3v2->frameListMap()["TCOM"];
    if (!composerFrame.isEmpty()) {
        QString sComposer = TStringToQString(composerFrame.front()->toString());
        setComposer(sComposer);
    }

    return true;
}
QString extractMBIDFromFile(TagLib::MPEG::File *file)
{
	TagLib::ID3v2::Tag *tag = file->ID3v2Tag();
	TagLib::ID3v2::FrameList ufid = tag->frameListMap()["UFID"];
	if (!ufid.isEmpty()) {
		for (TagLib::ID3v2::FrameList::Iterator i = ufid.begin(); i != ufid.end(); i++) {
			TagLib::ID3v2::UniqueFileIdentifierFrame *frame = dynamic_cast<TagLib::ID3v2::UniqueFileIdentifierFrame *>(*i);
			if (frame && frame->owner() == "http://musicbrainz.org") {
				TagLib::ByteVector id = frame->identifier();
				return QString::fromAscii(id.data(), id.size());
			}
		}
	}
	return QString();
}
bool
ID3v2TagHelper::hasEmbeddedCover() const
{
    TagLib::ID3v2::FrameList apicList = m_tag->frameListMap()[fieldName( Meta::valHasCover ).toCString()];

    for( TagLib::ID3v2::FrameList::ConstIterator it = apicList.begin(); it != apicList.end(); ++it )
    {
        TagLib::ID3v2::AttachedPictureFrame *currFrame =
                dynamic_cast< TagLib::ID3v2::AttachedPictureFrame * >( *it );

        if( currFrame->picture().size() < MIN_COVER_SIZE )
            continue;

        if( currFrame->type() == TagLib::ID3v2::AttachedPictureFrame::FrontCover ||
            currFrame->type() == TagLib::ID3v2::AttachedPictureFrame::Other )
            return true;
    }

    return false;
}
示例#19
0
void ReplayGainReader::readID3v2(TagLib::ID3v2::Tag *tag)
{
    TagLib::ID3v2::UserTextIdentificationFrame* frame = 0;
    TagLib::ID3v2::FrameList frames = tag->frameList("TXXX");
    for(TagLib::ID3v2::FrameList::Iterator it = frames.begin(); it != frames.end(); ++it)
    {
        frame = dynamic_cast<TagLib::ID3v2::UserTextIdentificationFrame*>(*it);
        if(frame && frame->fieldList().size() >= 2)
        {
            TagLib::String desc = frame->description().upper();
            if (desc == "REPLAYGAIN_TRACK_GAIN")
                setValue(Qmmp::REPLAYGAIN_TRACK_GAIN, TStringToQString(frame->fieldList()[1]));
            else if (desc == "REPLAYGAIN_TRACK_PEAK")
                setValue(Qmmp::REPLAYGAIN_TRACK_PEAK, TStringToQString(frame->fieldList()[1]));
            else if (desc == "REPLAYGAIN_ALBUM_GAIN")
                setValue(Qmmp::REPLAYGAIN_ALBUM_GAIN, TStringToQString(frame->fieldList()[1]));
            else if (desc == "REPLAYGAIN_ALBUM_PEAK")
                setValue(Qmmp::REPLAYGAIN_ALBUM_PEAK, TStringToQString(frame->fieldList()[1]));
        }
    }
}
bool
ID3v2TagHelper::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::ByteVector field = fieldName( Meta::valHasCover ).toCString();
    TagLib::ID3v2::FrameList apicList = m_tag->frameListMap()[field];
    TagLib::ID3v2::AttachedPictureFrame *frontCover = NULL;

    // remove covers
    TagLib::List<TagLib::ID3v2::AttachedPictureFrame*> backedUpPictures;
    for( TagLib::ID3v2::FrameList::ConstIterator it = apicList.begin(); it != apicList.end(); ++it )
    {
        TagLib::ID3v2::AttachedPictureFrame *currFrame =
                dynamic_cast< TagLib::ID3v2::AttachedPictureFrame * >( *it );

        m_tag->removeFrame( currFrame, false );
    }

    // add new cover
    frontCover = new TagLib::ID3v2::AttachedPictureFrame( field );
    frontCover->setMimeType( "image/jpeg" );
    frontCover->setPicture( TagLib::ByteVector( bytes.data(), bytes.count() ) );
    frontCover->setType( TagLib::ID3v2::AttachedPictureFrame::FrontCover );
    m_tag->addFrame( frontCover );

    return true;
}
示例#21
0
int MetaDSF::deletePictures(const TagLib::String &ptype) 
{
  TagLib::ID3v2::FrameList l = _i->_file.ID3v2Tag()->frameList("APIC");
  TagLib::ID3v2::FrameList dl; // a list of frames to be deleted
  TagLib::ID3v2::FrameList::ConstIterator it;
  std::string pt = ptype.toCString();
  // retrieve a list of frames that matches the given type
  for (it = l.begin(); it != l.end(); it++) {
    TagLib::ID3v2::AttachedPictureFrame *f = 
      static_cast<TagLib::ID3v2::AttachedPictureFrame *>(*it);
    TagLib::ID3v2::AttachedPictureFrame::Type t = 
      static_cast<TagLib::ID3v2::AttachedPictureFrame::Type>(std::stoi(pt, 
								       0, 16));
    if (f->type() == t) {
      dl.append(f);
    }
  }  

  _i->deleteFrames(dl);
  _i->_changed = true;
  return dl.size();
}
bool
ID3v2TagHelper::setTags( const Meta::FieldHash &changes )
{
    bool modified = TagHelper::setTags( changes );

    foreach( const qint64 key, changes.keys() )
    {
        QVariant value = changes.value( key );
        TagLib::ByteVector field( fieldName( key ).toCString() );

        if( !field.isNull() && !field.isEmpty() )
        {
            if( key == Meta::valHasCover )
                continue;
            else if( key == Meta::valUniqueId )
            {
                QPair< UIDType, QString > uidPair = splitUID( value.toString() );
                if( uidPair.first == UIDInvalid )
                    continue;

                TagLib::String owner  = uidFieldName( uidPair.first );
                TagLib::ByteVector uid( uidPair.second.toAscii().data() );
                TagLib::ID3v2::FrameList list = m_tag->frameList();

                for( TagLib::ID3v2::FrameList::ConstIterator it = list.begin(); it != list.end(); ++it )
                {
                    if( ( *it )->frameID() == field )
                    {
                        TagLib::ID3v2::UniqueFileIdentifierFrame *frame =
                                dynamic_cast< TagLib::ID3v2::UniqueFileIdentifierFrame * >( *it );
                        if( !frame )
                            continue;

                        if( frame->owner() == owner )
                        {
                            m_tag->removeFrame( frame );
                            modified = true;
                            break;
                        }
                    }
                }

                if ( !uid.isEmpty() )
                {
                    m_tag->addFrame( new TagLib::ID3v2::UniqueFileIdentifierFrame( owner, uid ) );
                    modified = true;
                }
                continue;
            }

            TagLib::String tValue = Qt4QStringToTString( ( key == Meta::valCompilation )
                                                         ? QString::number( value.toInt() )
                                                         : value.toString() );
            if( tValue.isEmpty() )
                m_tag->removeFrames( field );
            else
            {
                TagLib::ID3v2::TextIdentificationFrame *frame = NULL;
                if( !m_tag->frameListMap()[field].isEmpty() )
                    frame = dynamic_cast< TagLib::ID3v2::TextIdentificationFrame * >(
                                                  m_tag->frameListMap()[field].front()
                                                                                    );
                if( !frame )
                {
                    frame = new TagLib::ID3v2::TextIdentificationFrame( field );
                    m_tag->addFrame( frame );
                }
                // note: TagLib is smart enough to automatically set UTF8 encoding if needed.
                frame->setText( tValue );
            }
            modified = true;
        }
        else if( key == Meta::valScore || key == Meta::valRating || key == Meta::valPlaycount )
        {
            TagLib::String description;
            TagLib::String tValue;

            if( key == Meta::valRating )
            {
                description = fmpsFieldName( FMPSRating );
                tValue = Qt4QStringToTString( QString::number( value.toFloat() / 10.0 ) );
            }
            else if( key == Meta::valScore )
            {
                description = fmpsFieldName( FMPSScore );
                tValue = Qt4QStringToTString( QString::number( value.toFloat() / 100.0 ) );
            }
            else if( key == Meta::valPlaycount )
            {
                description = fmpsFieldName( FMPSPlayCount );
                tValue = Qt4QStringToTString( QString::number( value.toInt() ) );
            }

            if( key == Meta::valRating || key == Meta::valPlaycount )
            {
                TagLib::ID3v2::PopularimeterFrame *popFrame = NULL;
                if( !m_tag->frameListMap()[POPM_Frame].isEmpty() )
                    popFrame = dynamic_cast< TagLib::ID3v2::PopularimeterFrame * >( m_tag->frameListMap()[POPM_Frame].front() );

                if( !popFrame )
                {
                    popFrame = new TagLib::ID3v2::PopularimeterFrame( POPM_Frame );
                    m_tag->addFrame( popFrame );
                }

                if( key == Meta::valRating )
                    popFrame->setRating( qBound(0, int(qRound(value.toDouble() / 10.0 * 256)), 255) );
                else
                    popFrame->setCounter( value.toInt() );

                modified = true;
            }

            TagLib::ID3v2::FrameList list = m_tag->frameList();
            for( TagLib::ID3v2::FrameList::ConstIterator it = list.begin(); it != list.end(); ++it )
            {
                if( ( *it )->frameID() == TXXX_Frame )
                {
                    TagLib::ID3v2::UserTextIdentificationFrame *frame =
                            dynamic_cast< TagLib::ID3v2::UserTextIdentificationFrame * >( *it );
                    if( !frame )
                        continue;

                    if( frame->description() == description )
                    {
                        m_tag->removeFrame( frame );
                        modified = true;
                        break;
                    }
                }
            }

            if( value.toBool() )
            {
                TagLib::ID3v2::UserTextIdentificationFrame *frame =
                        new TagLib::ID3v2::UserTextIdentificationFrame( TXXX_Frame );

                frame->setDescription( description );
                frame->setText( tValue );
                m_tag->addFrame( frame );
                modified = true;
            }
        }
    }

    return modified;
}
示例#23
0
/*!
 * \brief Read the albumart images from the file
 *
 * \param tag The ID3v2 tag object in which to look for Album Art
 * \returns A QList containing a list of AlbumArtImage's
 *          with the type and description of the APIC tag.
 */
AlbumArtList MetaIOID3::readAlbumArt(TagLib::ID3v2::Tag *tag)
{
    AlbumArtList artlist;

    if (!tag->frameListMap()["APIC"].isEmpty())
    {
        TagLib::ID3v2::FrameList apicframes = tag->frameListMap()["APIC"];

        for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin();
            it != apicframes.end(); ++it)
        {

            AttachedPictureFrame *frame =
                static_cast<AttachedPictureFrame *>(*it);

            // Assume a valid image would have at least
            // 100 bytes of data (1x1 indexed gif is 35 bytes)
            if (frame->picture().size() < 100)
            {
                LOG(VB_GENERAL, LOG_NOTICE,
                    "Music Scanner - Discarding APIC frame "
                    "with size less than 100 bytes");
                continue;
            }

            AlbumArtImage *art = new AlbumArtImage();

            if (frame->description().isEmpty())
                art->m_description.clear();
            else
                art->m_description = TStringToQString(frame->description());

            art->m_embedded = true;
            art->m_hostname = gCoreContext->GetHostName();

            QString ext = getExtFromMimeType(
                                TStringToQString(frame->mimeType()).toLower());

            switch (frame->type())
            {
                case AttachedPictureFrame::FrontCover :
                    art->m_imageType = IT_FRONTCOVER;
                    art->m_filename = QString("front") + ext;
                    break;
                case AttachedPictureFrame::BackCover :
                    art->m_imageType = IT_BACKCOVER;
                    art->m_filename = QString("back") + ext;
                    break;
                case AttachedPictureFrame::Media :
                    art->m_imageType = IT_CD;
                    art->m_filename = QString("cd") + ext;
                    break;
                case AttachedPictureFrame::LeafletPage :
                    art->m_imageType = IT_INLAY;
                    art->m_filename = QString("inlay") + ext;
                    break;
                case AttachedPictureFrame::Artist :
                    art->m_imageType = IT_ARTIST;
                    art->m_filename = QString("artist") + ext;
                    break;
                case AttachedPictureFrame::Other :
                    art->m_imageType = IT_UNKNOWN;
                    art->m_filename = QString("unknown") + ext;
                    break;
                default:
                    LOG(VB_GENERAL, LOG_ERR, "Music Scanner - APIC tag found "
                                             "with unsupported type");
                    delete art;
                    continue;
            }

            artlist.append(art);
        }
    }

    return artlist;
}
Meta::FieldHash
ID3v2TagHelper::tags() const
{
    Meta::FieldHash data = TagHelper::tags();

    TagLib::ID3v2::FrameList list = m_tag->frameList();
    for( TagLib::ID3v2::FrameList::ConstIterator it = list.begin(); it != list.end(); ++it )
    {
        qint64 field;
        TagLib::String frameName  = TagLib::String( ( *it )->frameID() );
        if( ( field = fieldName( frameName ) ) )
        {
            if( field == Meta::valUniqueId )
            {
                TagLib::ID3v2::UniqueFileIdentifierFrame *frame =
                        dynamic_cast< TagLib::ID3v2::UniqueFileIdentifierFrame * >( *it );

                if( !frame )
                    continue;

                QString identifier = TStringToQString( TagLib::String( frame->identifier() ) );

                if( identifier.isEmpty() )
                    continue;

                if( frame->owner() == uidFieldName( UIDAFT ) && isValidUID( identifier, UIDAFT ) )
                    data.insert( Meta::valUniqueId, identifier );
                continue;
            }
            else if( field == Meta::valHasCover )
            {
                TagLib::ID3v2::AttachedPictureFrame *frame =
                        dynamic_cast< TagLib::ID3v2::AttachedPictureFrame * >( *it );

                if( !frame )
                    continue;

                if( ( frame->type() == TagLib::ID3v2::AttachedPictureFrame::FrontCover ||
                      frame->type() == TagLib::ID3v2::AttachedPictureFrame::Other ) &&
                    frame->picture().size() > MIN_COVER_SIZE ) // must be at least 1kb
                {
                    data.insert( Meta::valHasCover, true );
                }
                continue;
            }

            TagLib::ID3v2::TextIdentificationFrame *frame =
                    dynamic_cast< TagLib::ID3v2::TextIdentificationFrame * >( *it );

            if( !frame )
                continue;

            QString value = TStringToQString( frame->fieldList().toString( '\n' ) );

            if( field == Meta::valDiscNr )
            {
                int disc;
                if( ( disc = splitDiscNr( value ).first ) )
                    data.insert( field, disc );
            }
            else if( field == Meta::valBpm )
                data.insert( field, value.toFloat() );
            else
                data.insert( field, value );
        }
        else if( frameName == POPM_Frame )
        {
            TagLib::ID3v2::PopularimeterFrame *frame =
                    dynamic_cast< TagLib::ID3v2::PopularimeterFrame * >( *it );

            if( !frame )
                continue;

            if( TStringToQString( frame->email() ).isEmpty() ) // only read anonymous ratings
            {
                // FMPS tags have precedence
                if( !data.contains( Meta::valRating ) && frame->rating() != 0 )
                    data.insert( Meta::valRating, qRound( frame->rating() / 256.0 * 10.0 ) );
                if( !data.contains( Meta::valPlaycount ) && frame->counter() < 10000 )
                    data.insert( Meta::valPlaycount, frame->counter() );
            }
        }
        else if( frameName == TXXX_Frame )
        {
            TagLib::ID3v2::UserTextIdentificationFrame *frame =
                    dynamic_cast< TagLib::ID3v2::UserTextIdentificationFrame * >( *it );

            if( !frame )
                continue;

            // the value of the user text frame is stored in the
            // second and following fields.
            TagLib::StringList fields = frame->fieldList();
            if( fields.size() >= 2 )
            {
                QString value = TStringToQString( fields[1] );

                if( fields[0] == fmpsFieldName( FMPSRating ) )
                    data.insert( Meta::valRating, qRound( value.toFloat() * 10.0 ) );
                else if( fields[0] == fmpsFieldName( FMPSScore ) )
                    data.insert( Meta::valScore, value.toFloat() * 100.0 );
                else if( fields[0] == fmpsFieldName( FMPSPlayCount ) )
                    data.insert( Meta::valPlaycount, value.toFloat() );
            }
        }
    }

    return data;
}
示例#25
0
void MediaScannerThread::run()
{
	if (multiPass)
	{
		qDebug() << "MediaScannerThread: multi non-single pass selected";
		multiPass = false;
		for (int i=0;i<multiPassFileNames.count();i++)
		{
			QString fullPath = multiPassFileNames.at(i);
			TagLib::FileRef testfile(fullPath.toStdString().c_str());
			if (!testfile.isNull())
			{
				ID3Tag *tmpTag = 0;
				if (!tmpTag)
				{
					tmpTag = new ID3Tag();
					tmpTag->valid = false;
				}
				if (TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File *>( testfile.file()))
				{
					if (file->ID3v2Tag(false))
					{
						//Check to see if there are images in the tag
						#ifdef Q_OS_WIN32 //Currently this only works in the windows version of taglib??
						if (!file->ID3v2Tag()->frameListMap()["APIC"].isEmpty())
						{
							TagLib::ID3v2::FrameList frameList = file->ID3v2Tag()->frameListMap()["APIC"];
							TagLib::ID3v2::FrameList::Iterator iter;
							for( iter = frameList.begin(); iter != frameList.end(); ++iter )
							{
								TagLib::ID3v2::AttachedPictureFrame::Type t = (((TagLib::ID3v2::AttachedPictureFrame*)*iter))->type();
								if (t == TagLib::ID3v2::AttachedPictureFrame::Type::FrontCover)
								{
									TagLib::ByteVector pic = (((TagLib::ID3v2::AttachedPictureFrame*)*iter))->picture();
									QImage tmpPicture;
									tmpPicture.loadFromData((uchar*)pic.data(),pic.size());
									tmpTag->frontcover = tmpPicture;
								}
								else if (t == TagLib::ID3v2::AttachedPictureFrame::Type::BackCover)
								{
									TagLib::ByteVector pic = (((TagLib::ID3v2::AttachedPictureFrame*)*iter))->picture();
									QImage tmpPicture;
									tmpPicture.loadFromData((uchar*)pic.data(),pic.size());
									tmpTag->backcover = tmpPicture;
								}
								
							}
						}
						#endif //Q_OS_WIN32
						TagLib::Tag *tag = testfile.tag();
						if (!tmpTag->valid)
						{
							tmpTag->artist = tag->artist().toCString();
							tmpTag->title = tag->title().toCString();
							tmpTag->filename = fullPath;
							emit tagReceived("",0,tmpTag);
						}	
					}

				}
				else
				{
					TagLib::Tag *tag = testfile.tag();
					if (!tmpTag->valid)
					{
						tmpTag->artist = tag->artist().toCString();
						tmpTag->title = tag->title().toCString();
						tmpTag->filename = fullPath;
						emit tagReceived("",0,tmpTag);
					}
				}
			}
			else
			{
				qDebug() << "MediaScannerThread: Invalid File in multipass" << fullPath;
				int stop = 1;
			}
			QThread::msleep(50);
		}
		multiPassFileNames.clear();
		
	}
	else if (singlePass)
	{
		qDebug() << "MediaScannerThread: Non-multi single pass selected";
		singlePass = false;
		QString fullPath = singlePassFileName;
		TagLib::FileRef testfile(fullPath.toStdString().c_str());
		if (!testfile.isNull())
		{
			TagLib::Tag *tag = testfile.tag();
		//if (tag)
		//{
			ID3Tag *tmpTag = 0;
			if (!tmpTag)
			{
				tmpTag = new ID3Tag();
				tmpTag->valid = false;
			}
			if (!tmpTag->valid)
			{
				tmpTag->artist = tag->artist().toCString();
				tmpTag->title = tag->title().toCString();
				tmpTag->filename = fullPath;
				emit tagReceived("",0,tmpTag);
			}
			//ID3Tag *tmpTag = new ID3Tag();
		}
		else
		{
			qDebug() << "MediaScannerThread: Invalid File in singlepass" << fullPath;
		}

	}
	else
	{
		qDebug() << "MediaScannerThread: Non-multi non-single pass selected";
		bool firstScan = true;
		int delay=0;
		bool anyValid = true;
		while (anyValid)
		{
			anyValid = false;
			if (firstScan)
			{
				delay=0;
				//firstScan = false;
			}
			else
			{	
				delay=20;
			}
			for (int i=0;i<m_playLists->count();i++)
			{
				for (int j=0;j<m_playLists->at(i)->size();j++)
				{

					QString fullPath = m_playLists->at(i)->getFileNum(j)->fullPath();
//					qDebug() << fullPath;
					TagLib::FileRef testfile(fullPath.toStdString().c_str());
					if (!testfile.isNull())
					{
						ID3Tag *tmpTag = m_playLists->at(i)->getFileNum(j)->getId3Tag();
						if (!tmpTag)
						{
							tmpTag = new ID3Tag();
							tmpTag->valid = false;
							anyValid = true;
						}
						if (TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File *>( testfile.file()))
						{
							if (file->ID3v2Tag(false))
							{
								//Check to see if there are images in the tag
								#ifdef Q_OS_WIN32 //Currently this only works in the windows version of taglib??
								if (!file->ID3v2Tag()->frameListMap()["APIC"].isEmpty())
								{
									TagLib::ID3v2::FrameList frameList = file->ID3v2Tag()->frameListMap()["APIC"];
									TagLib::ID3v2::FrameList::Iterator iter;
									for( iter = frameList.begin(); iter != frameList.end(); ++iter )
									{
										TagLib::ID3v2::AttachedPictureFrame::Type t = (((TagLib::ID3v2::AttachedPictureFrame*)*iter))->type();
										if (t == TagLib::ID3v2::AttachedPictureFrame::Type::FrontCover)
										{
											TagLib::ByteVector pic = (((TagLib::ID3v2::AttachedPictureFrame*)*iter))->picture();
											QImage tmpPicture;
											tmpPicture.loadFromData((uchar*)pic.data(),pic.size());
											tmpTag->frontcover = tmpPicture;
										}
										else if (t == TagLib::ID3v2::AttachedPictureFrame::Type::BackCover)
										{
											TagLib::ByteVector pic = (((TagLib::ID3v2::AttachedPictureFrame*)*iter))->picture();
											QImage tmpPicture;
											tmpPicture.loadFromData((uchar*)pic.data(),pic.size());
											tmpTag->backcover = tmpPicture;
										}
										
									}
								}
								#endif
								TagLib::Tag *tag = testfile.tag();
								if (!tmpTag->valid)
								{
									tmpTag->artist = tag->artist().toCString();
									tmpTag->title = tag->title().toCString();
									tmpTag->filename = fullPath;
									emit tagReceived(m_playLists->at(i)->title(),j,tmpTag);
								}	
							}
						}
						else
						{
							TagLib::Tag *tag = testfile.tag();
							if (!tmpTag->valid)
							{
								tmpTag->artist = tag->artist().toCString();
								tmpTag->title = tag->title().toCString();
								tmpTag->valid = true;
								tmpTag->filename = fullPath;
								m_playLists->at(i)->setId3(j,tmpTag);
								anyValid = true;
								emit tagReceived(m_playLists->at(i)->title(),j,tmpTag);
							}
							else
							{
								if (tmpTag->filename != fullPath)
								{
									tmpTag->artist = tag->artist().toCString();
									tmpTag->title = tag->title().toCString();
									tmpTag->filename = fullPath;
									tmpTag->valid = true;
									m_playLists->at(i)->setId3(j,tmpTag);
									anyValid = true;
									emit tagReceived(m_playLists->at(i)->title(),j,tmpTag);								
								}
							}
						}
						//ID3Tag *tmpTag = new ID3Tag();
					}
					else
					{
						qDebug() << "MediaScannerThread: Invalid File in standardpass" << fullPath;
					}
					QThread::msleep(delay);
				}
			}
			if (firstScan)
			{
				firstScan = false;
				qDebug() << "Initial scan of id3 tags completed. ";
				if (anyValid)
				{
					qDebug() << "Moving to background  mode...";
				}
				else
				{
					qDebug() << "All files scanned, exiting thread";
				}
			}
			else
			{
				qDebug() << "Secondary id3 scan complete... continuing...";
			}
		}
	}
	/*
	int done = 1;
	return;
	QFile tmpFile("music.conf");
	if (!tmpFile.open(QIODevice::ReadOnly | QIODevice::Text))
	{	
		printf("Error opening configuration file!!!\n");
		return;
	}
	QString musicDir(tmpFile.readLine());
	printf("Music Directory from configuration file: %s\n",musicDir.toStdString().c_str());
	tmpFile.close();
	musicDir = musicDir.mid(0,musicDir.length()-1);
	QDir tmpDir(musicDir);

	tmpDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
	QDir tmpFiles(musicDir);
	tmpFiles.setFilter(QDir::Files | QDir::NoDotAndDotDot);
	QStringList infoList = tmpDir.entryList();
	foreach (QString info,infoList)
	{
		TagLib::FileRef testfile(info.toStdString().c_str());
		TagLib::Tag *tag = testfile.tag();
		ID3Tag *tmpTag = new ID3Tag();
		tmpTag->artist = tag->artist().to8Bit().c_str();
		tmpTag->title = tag->title().to8Bit().c_str();
		//emit tagReceived(tmpTag);		
	}
	bool inLoop = true;
	//while (inLoop)
	//{
		//QThread::
	//	QThread::sleep(1);
		
	//	ID3Tag *tmpTag = new ID3Tag();
		//tmpTag->artist = 
		
	//}
	*/
}
示例#26
0
static Meta::ReplayGainTagMap readID3v2Tags( TagLib::ID3v2::Tag *tag )
{
    Meta::ReplayGainTagMap map;
    {   // ID3v2.4.0 native replay gain tag support (as written by Quod Libet, for example).
        TagLib::ID3v2::FrameList frames = tag->frameListMap()["RVA2"];
        frames.append(tag->frameListMap()["XRVA"]);
        if ( !frames.isEmpty() )
        {
            for ( unsigned int i = 0; i < frames.size(); ++i )
            {
                // we have to parse this frame ourselves
                // ID3v2 frame header is 10 bytes, so skip that
                TagLib::ByteVector data = frames[i]->render().mid( 10 );
                unsigned int offset = 0;
                QString desc( data.data() );
                offset += desc.count() + 1;
                unsigned int channel = data.mid( offset, 1 ).toUInt( true );
                // channel 1 is the main volume - the only one we care about
                if ( channel == 1 )
                {
                    ++offset;
                    qint16 adjustment512 = data.mid( offset, 2 ).toShort( true );
                    qreal adjustment = ( (qreal)adjustment512 ) / 512.0;
                    offset += 2;
                    unsigned int peakBits = data.mid( offset, 1 ).toUInt( true );
                    ++offset;
                    bool ok = false;
                    qreal peak = readRVA2PeakValue( data.mid( offset ), peakBits, &ok );
                    if ( ok )
                    {
                        if ( desc.toLower() == "album" )
                        {
                            map[Meta::ReplayGain_Album_Gain] = adjustment;
                            map[Meta::ReplayGain_Album_Peak] = peakToDecibels( peak );
                        }
                        else if ( desc.toLower() == "track" || !map.contains( Meta::ReplayGain_Track_Gain ) )
                        {
                            map[Meta::ReplayGain_Track_Gain] = adjustment;
                            map[Meta::ReplayGain_Track_Peak] = peakToDecibels( peak );
                        }
                    }
                }
            }
            if ( !map.isEmpty() )
                return map;
        }
    }

    {   // Foobar2000-style ID3v2.3.0 tags
        TagLib::ID3v2::FrameList frames = tag->frameListMap()["TXXX"];
        for ( TagLib::ID3v2::FrameList::Iterator it = frames.begin(); it != frames.end(); ++it ) {
            TagLib::ID3v2::UserTextIdentificationFrame* frame =
                dynamic_cast<TagLib::ID3v2::UserTextIdentificationFrame*>( *it );
            if ( frame && frame->fieldList().size() >= 2 )
            {
                QString desc = TStringToQString( frame->description() ).toLower();
                if ( desc == "replaygain_album_gain" )
                    maybeAddGain( frame->fieldList()[1], Meta::ReplayGain_Album_Gain, &map );
                if ( desc == "replaygain_album_peak" )
                    maybeAddPeak( frame->fieldList()[1], Meta::ReplayGain_Album_Peak, &map );
                if ( desc == "replaygain_track_gain" )
                    maybeAddGain( frame->fieldList()[1], Meta::ReplayGain_Track_Gain, &map );
                if ( desc == "replaygain_track_peak" )
                    maybeAddPeak( frame->fieldList()[1], Meta::ReplayGain_Track_Peak, &map );
            }
        }
    }
    return map;
}