Пример #1
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 );
            }
        }
    }
}
Пример #2
0
void FileHelper::setFlacAttribute(const std::string &attribute, const QString &value)
{
	if (TagLib::FLAC::File *flacFile = static_cast<TagLib::FLAC::File*>(_file)) {
		if (flacFile->hasID3v2Tag()) {
			TagLib::ID3v2::Tag *tag = flacFile->ID3v2Tag();
			QString key = this->convertKeyToID3v2Key(attribute.data());
			TagLib::ID3v2::FrameList l = tag->frameListMap()[key.toStdString().data()];
			if (!l.isEmpty()) {
				tag->removeFrame(l.front());
			}
			TagLib::ID3v2::TextIdentificationFrame *tif = new TagLib::ID3v2::TextIdentificationFrame(TagLib::ByteVector("ARTISTALBUM"));
			tif->setText(value.toStdString().data());
			tag->addFrame(tif);
		} else if (flacFile->hasID3v1Tag()) {
			qDebug() << Q_FUNC_INFO << "Not implemented (FLAC ID3v1)";
		} else if (flacFile->hasXiphComment()) {
			TagLib::Ogg::XiphComment *xiph = flacFile->xiphComment();
			if (value.isEmpty()) {
				xiph->removeField(attribute.data());
			} else {
				xiph->addField(attribute.data(), value.toStdString().data());
			}
		}
	}
}
Пример #3
0
void TagReader::SetTextFrame(const char* id, const std::string& value,
                             TagLib::ID3v2::Tag* tag) const {
  TagLib::ByteVector id_vector(id);
  QVector<TagLib::ByteVector> frames_buffer;

  // Store and clear existing frames
  while (tag->frameListMap().contains(id_vector) &&
         tag->frameListMap()[id_vector].size() != 0) {
    frames_buffer.push_back(tag->frameListMap()[id_vector].front()->render());
    tag->removeFrame(tag->frameListMap()[id_vector].front());
  }

  // If no frames stored create empty frame
  if (frames_buffer.isEmpty()) {
    TagLib::ID3v2::TextIdentificationFrame frame(id_vector,
                                                 TagLib::String::UTF8);
    frames_buffer.push_back(frame.render());
  }

  // Update and add the frames
  for (int lyrics_index = 0; lyrics_index < frames_buffer.size();
       lyrics_index++) {
    TagLib::ID3v2::TextIdentificationFrame* frame =
        new TagLib::ID3v2::TextIdentificationFrame(
            frames_buffer.at(lyrics_index));
    if (lyrics_index == 0) {
      frame->setText(StdStringToTaglibString(value));
    }
    // add frame takes ownership and clears the memory
    tag->addFrame(frame);
  }
}
Пример #4
0
void FileHelper::setArtistAlbum(const QString &artistAlbum)
{
	switch (_fileType) {
	case EXT_FLAC: {
		this->setFlacAttribute("ALBUMARTIST", artistAlbum);
		break;
	}
	case EXT_MP4:{
		TagLib::StringList l;
		l.append(artistAlbum.toStdString().data());
		TagLib::MP4::Item item(l);
		this->setMp4Attribute("aART", item);
		break;
	}
	case EXT_MPC:
		//mpcFile = static_cast<MPC::File*>(f);
		qDebug() << Q_FUNC_INFO << "Not implemented for MPC";
		break;
	case EXT_MP3:{
		TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file);
		if (mpegFile->hasID3v2Tag()) {
			TagLib::ID3v2::Tag *tag = mpegFile->ID3v2Tag();
			QString convertedKey = this->convertKeyToID3v2Key("ARTISTALBUM");
			TagLib::ID3v2::FrameList l = tag->frameListMap()[convertedKey.toStdString().data()];
			if (!l.isEmpty()) {
				tag->removeFrame(l.front());
			}
			TagLib::ID3v2::TextIdentificationFrame *tif = new TagLib::ID3v2::TextIdentificationFrame(TagLib::ByteVector(convertedKey.toStdString().data()));
			tif->setText(artistAlbum.toStdString().data());
			tag->addFrame(tif);
		} else if (mpegFile->hasID3v1Tag()) {
			qDebug() << Q_FUNC_INFO << "Not implemented for ID3v1Tag";
		}
		break;
	}
	case EXT_OGG: {
		TagLib::Ogg::XiphComment *xiphComment = static_cast<TagLib::Ogg::XiphComment*>(_file->tag());
		if (xiphComment) {
			xiphComment->addField("ALBUMARTIST", artistAlbum.toStdString().data());
		} else {
			qDebug() << Q_FUNC_INFO << "Not implemented for this OGG file";
		}
		break;
	}
	default:
		qDebug() << Q_FUNC_INFO << "Not implemented for this type of file";
		break;
	}
}
Пример #5
0
void TagReader::SetTextFrame(const char* id, const std::string& value,
                             TagLib::ID3v2::Tag* tag) const {
  TagLib::ByteVector id_vector(id);

  // Remove the frame if it already exists
  while (tag->frameListMap().contains(id_vector) &&
         tag->frameListMap()[id_vector].size() != 0) {
    tag->removeFrame(tag->frameListMap()[id_vector].front());
  }

  // Create and add a new frame
  TagLib::ID3v2::TextIdentificationFrame* frame =
      new TagLib::ID3v2::TextIdentificationFrame(id_vector,
                                                 TagLib::String::UTF8);
  frame->setText(StdStringToTaglibString(value));
  tag->addFrame(frame);
}
Пример #6
0
/**
 * Set the file-type specific `compilation' tag.
 *
 * See the discussion on top of this file about which tag is used
 * for which file-type.
 *
 * @param file  taggit's file-data structure for the processed file
 * @param tag   the tag-data decoded by `taglib_file_tag()'
 * @param value the string the user wants to set this tag to
 *
 * @return      void
 * @sideeffects none
 */
void
taggit_tag_set_compilation(struct taggit_file *file,
                           TagLib_Tag *tag, const char *value)
{
    TagLib::APE::Tag *ape;
    TagLib::ID3v2::Tag *v2;
    TagLib::Ogg::XiphComment *ogg;
    const char *ret;
    TagLib::MPEG::File::File *f;
    int mask;

    ret = (const char *)NULL;
    switch (file->type) {
    case FT_MPEG:
        f = reinterpret_cast<TagLib::MPEG::File::File *>(file->data);
        mask = setup_get_write_mask(FT_MPEG);
        if (mask & MP3_ID3V2) {
            v2 = f->ID3v2Tag();
            v2->removeFrames("TPE2");
            /*
             * @TODO: I don't know how to figure out the proper `encoding'
             *        value here. Should we look at the `unicodeStrings'
             *        variable from taglib?
             */
            TagLib::ID3v2::TextIdentificationFrame *frame =
                new TagLib::ID3v2::TextIdentificationFrame(
                    "TPE2", TagLib::String::Latin1);
            frame->setText(value);
            v2->addFrame(frame);
        }
        if (mask & MP3_APE) {
            ape = f->APETag();
            ape->addValue("ALBUMARTIST", value, true);
        }
        break;
    case FT_OGGVORBIS:
        /* @FALLTHROUGH@ */
    case FT_OGGFLAC:
        ogg = reinterpret_cast<TagLib::Ogg::XiphComment *>(tag);
        ogg->addField("ALBUMARTIST", value, true);
        break;
    default:
        break;
    }
}
Пример #7
0
/** Set or remove any disc number. */
void FileHelper::setDiscNumber(const QString &disc)
{
	switch (_fileType) {
	case EXT_FLAC: {
		this->setFlacAttribute("DISCNUMBER", disc);
		break;
	}
	case EXT_OGG: {
		TagLib::Ogg::XiphComment *xiphComment = static_cast<TagLib::Ogg::XiphComment*>(_file->tag());
		if (xiphComment) {
			xiphComment->addField("DISCNUMBER", disc.toStdString().data());
		} else {
			qDebug() << Q_FUNC_INFO << "Not implemented for this OGG file";
		}
		break;
	}
	case EXT_MP3: {
		TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file);
		if (mpegFile && mpegFile->hasID3v2Tag()) {
			// Remove existing disc number if one has set an empty string
			if (disc.isEmpty()) {
				mpegFile->ID3v2Tag()->removeFrames(TagLib::ByteVector("TPOS"));
			} else {
				TagLib::ID3v2::TextIdentificationFrame *f = new TagLib::ID3v2::TextIdentificationFrame(TagLib::ByteVector("TPOS"));
				f->setText(disc.toStdString());
				mpegFile->ID3v2Tag()->addFrame(f);
			}
		}
		break;
	}
	case EXT_MP4: {
		TagLib::MP4::Item item(disc.toUInt());
		this->setMp4Attribute("disk", item);
		break;
	}
	default:
		qDebug() << Q_FUNC_INFO << "Not implemented for this file type";
		break;
	}
}
Пример #8
0
bool mttFile::saveTag( void )
{
    fileref = new TagLib::FileRef( QFile::encodeName( fname ).constData() );

    if ( ismpeg ) {
        TagLib::MPEG::File *f = dynamic_cast<TagLib::MPEG::File *>(fileref->file());

        // Remove id3v1 tag. Help put that hack into eternal rest :-)
        f->strip( TagLib::MPEG::File::ID3v1, true );
        //qDebug("ID3v1 tag stripped!");

        TagLib::Tag::duplicate( tag, dynamic_cast<TagLib::Tag *>( f->ID3v2Tag( true ) ), true );

        // Save extra mp3 tags
        TagLib::ID3v2::TextIdentificationFrame *myframe;
        TagLib::ID3v2::Tag *mytag;

        mytag = f->ID3v2Tag( false );
        for ( QStringList::Iterator it = mp3eframes.begin(); it != mp3eframes.end(); ++it ) {
            myframe = new TagLib::ID3v2::TextIdentificationFrame( (*it).toAscii().constData(), TagLib::String::UTF8 );
            mytag->removeFrames( (*it).toAscii().constData() );
            ++it;
            myframe->setText( Q4StringToTString( (*it) ) );
            mytag->addFrame( myframe );
        }

        
	delete fileref;
	fileref = NULL;
	return f->save( TagLib::MPEG::File::ID3v2, true );
    }
    else {
        TagLib::Tag::duplicate( tag, fileref->tag(), true );
	delete fileref;
	fileref = NULL;
        return fileref->save();
    }

}
Пример #9
0
void AudioTagger::addID3v2Tag(TagLib::ID3v2::Tag* id3v2) {
    if (!id3v2)
        return;

    TagLib::ID3v2::FrameList bpmFrame = id3v2->frameListMap()["TBPM"];
    if (!bpmFrame.isEmpty()) {
        bpmFrame.front()->setText(m_bpm.toStdString());
    } else {
         // add new frame TextIdentificationFrame which is responsible for TKEY and TBPM
         // see http://developer.kde.org/~wheeler/taglib/api/classTagLib_1_1ID3v2_1_1TextIdentificationFrame.html

        TagLib::ID3v2::TextIdentificationFrame* newFrame = new TagLib::ID3v2::TextIdentificationFrame("TBPM", TagLib::String::Latin1);

        newFrame->setText(m_bpm.toStdString());
        id3v2->addFrame(newFrame);

    }

    TagLib::ID3v2::FrameList keyFrame = id3v2->frameListMap()["TKEY"];
    if (!keyFrame.isEmpty()) {
        keyFrame.front()->setText(m_key.toStdString());
    } else {
        //add new frame
        TagLib::ID3v2::TextIdentificationFrame* newFrame = new TagLib::ID3v2::TextIdentificationFrame("TKEY", TagLib::String::Latin1);

        newFrame->setText(m_key.toStdString());
        id3v2->addFrame(newFrame);

    }

    TagLib::ID3v2::FrameList composerFrame = id3v2->frameListMap()["TCOM"];
    if (!composerFrame.isEmpty()) {
        composerFrame.front()->setText(m_composer.toStdString());
    } else {
        //add new frame
        TagLib::ID3v2::TextIdentificationFrame* newFrame =
                new TagLib::ID3v2::TextIdentificationFrame(
                    "TCOM", TagLib::String::Latin1);
        newFrame->setText(m_composer.toStdString());
        id3v2->addFrame(newFrame);
    }
}
Пример #10
0
void mttFile::checkEncodings( void )
{
	fileref = new TagLib::FileRef( QFile::encodeName( fname ).constData() );

    if ( isMpeg() ) {
        TagLib::MPEG::File *f = dynamic_cast<TagLib::MPEG::File *>(fileref->file());

        if ( f->ID3v2Tag() ) {
            TagLib::ID3v2::FrameList l = f->ID3v2Tag()->frameListMap()["TALB"];
            if ( !l.isEmpty() ) {
                TagLib::ID3v2::TextIdentificationFrame *tf = dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(l.front());
                if ( tf && tf->textEncoding() != TagLib::String::UTF8 )
                    tf->setTextEncoding( TagLib::String::UTF8 );
            }

            l = f->ID3v2Tag()->frameListMap()["TIT2"];
            if ( !l.isEmpty() ) {
                TagLib::ID3v2::TextIdentificationFrame *tf = dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(l.front());
                if ( tf && tf->textEncoding() != TagLib::String::UTF8 )
                    tf->setTextEncoding( TagLib::String::UTF8 );
            }

            l = f->ID3v2Tag()->frameListMap()["TPE1"];
            if ( !l.isEmpty() ) {
                TagLib::ID3v2::TextIdentificationFrame *tf = dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(l.front());
                if ( tf && tf->textEncoding() != TagLib::String::UTF8 )
                    tf->setTextEncoding( TagLib::String::UTF8 );
            }

            l = f->ID3v2Tag()->frameListMap()["TCON"];
            if ( !l.isEmpty() ) {
                TagLib::ID3v2::TextIdentificationFrame *tf = dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(l.front());
                if ( tf && tf->textEncoding() != TagLib::String::UTF8 )
                    tf->setTextEncoding( TagLib::String::UTF8 );
            }

            l = f->ID3v2Tag()->frameListMap()["COMM"];
            if ( !l.isEmpty() ) {
                TagLib::ID3v2::TextIdentificationFrame *tf = dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(l.front());
                if ( tf && tf->textEncoding() != TagLib::String::UTF8 )
                    tf->setTextEncoding( TagLib::String::UTF8 );
            }
        }
    }

    delete fileref;
    fileref = NULL;
}
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;
}
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;
}