示例#1
0
bool MetaIOID3::writeVolatileMetadata(const Metadata* mdata)
{
    QString filename = mdata->Filename();
    int rating = mdata->Rating();
    int playcount = mdata->PlayCount();
    TagLib::MPEG::File *mpegfile = OpenFile(filename);

    if (!mpegfile)
        return false;

    TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

    if (!tag)
    {
        delete mpegfile;
        return false;
    }

    bool result = (writeRating(tag, rating) && writePlayCount(tag, playcount));

    mpegfile->save();
    delete mpegfile;

    return result;
}
示例#2
0
/** Convert the existing rating number into a smaller range from 1 to 5. */
int FileHelper::rating() const
{
	int r = -1;

	/// TODO other types?
	switch (_fileType) {
	case EXT_MP3: {
		TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file);
		if (mpegFile && mpegFile->hasID3v2Tag()) {
			r = this->ratingForID3v2(mpegFile->ID3v2Tag());
		}
		break;
	}
	case EXT_FLAC: {
		if (TagLib::FLAC::File *flacFile = static_cast<TagLib::FLAC::File*>(_file)) {
			if (flacFile->hasID3v2Tag()) {
				r = this->ratingForID3v2(flacFile->ID3v2Tag());
			} else if (flacFile->hasID3v1Tag()) {
				qDebug() << Q_FUNC_INFO << "Not implemented (FLAC ID3v1)";
			} else if (flacFile->hasXiphComment()) {
				TagLib::StringList list = flacFile->xiphComment()->fieldListMap()["RATING"];
				if (!list.isEmpty()) {
					r = list.front().toInt();
				}
			}
		}
		break;
	}
	default:
		break;
	}
	return r;
}
示例#3
0
void MainWindow::on_pushOpenFolder_clicked()
{
    m_notUsed.clear();
    QString dir = QFileDialog::getExistingDirectory(this, tr("Open MP3 Source Directory"),
                                                    pSet->value("src_dir").toString(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

    if (!dir.isEmpty())
    {
        pSet->setValue("src_dir", dir);

        ui->lineSrcFolder->setText(dir);
        cleanTags();

        QDir mp3Dir(dir, "*.mp3");
        QStringList files = mp3Dir.entryList();
        TagLib::MPEG::File* ptlFile;

        foreach (QString file, files)
        {
            QString path = QString("%1/%2").arg(mp3Dir.absolutePath()).arg(file);

            ptlFile = new TagLib::MPEG::File(reinterpret_cast<const wchar_t *>(path.utf16()));

            if (ptlFile && ptlFile->isOpen())
            {
                tagFiles.append(ptlFile);
            }
            else if(ptlFile)
            {
                m_notUsed.append(path);
                delete ptlFile;
            }
        }
示例#4
0
/** Set or remove any rating. */
void FileHelper::setRating(int rating)
{
	switch (_fileType) {
	case EXT_MP3: {
		TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file);
		if (mpegFile->hasID3v2Tag()) {
			this->setRatingForID3v2(rating, mpegFile->ID3v2Tag());
		} else if (mpegFile->hasID3v1Tag()) {
			qDebug() << Q_FUNC_INFO << "Not implemented for ID3v1Tag";
		}
		break;
	}
	case EXT_FLAC: {
		TagLib::FLAC::File *flacFile = static_cast<TagLib::FLAC::File*>(_file);
		if (flacFile->hasID3v2Tag()) {
			this->setRatingForID3v2(rating, flacFile->ID3v2Tag());
		} else if (flacFile->hasID3v1Tag()) {
			qDebug() << Q_FUNC_INFO << "hasID3v1Tag";
		} else if (flacFile->hasXiphComment()) {
			TagLib::Ogg::XiphComment *xiph = flacFile->xiphComment();
			if (rating == 0) {
				xiph->removeField("RATING");
			} else {
				xiph->addField("RATING", QString::number(rating).toStdString());
			}
		}
		break;
	}
	default:
		break;
	}
	this->save();
}
示例#5
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;
}
示例#6
0
/** Check if file has an inner picture. */
bool FileHelper::hasCover() const
{
	bool atLeastOnePicture = false;
	switch (_fileType) {
	case EXT_MP3: {
		TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file);
		if (mpegFile && mpegFile->hasID3v2Tag()) {
			// Look for picture frames only
			TagLib::ID3v2::FrameList listOfMp3Frames = mpegFile->ID3v2Tag()->frameListMap()["APIC"];
			// It's possible to have more than one picture per file!
			if (!listOfMp3Frames.isEmpty()) {
				for (TagLib::ID3v2::FrameList::ConstIterator it = listOfMp3Frames.begin(); it != listOfMp3Frames.end() ; it++) {
					// Cast a Frame* to AttachedPictureFrame*
					TagLib::ID3v2::AttachedPictureFrame *pictureFrame = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it);
					atLeastOnePicture = atLeastOnePicture || (pictureFrame != nullptr && !pictureFrame->picture().isEmpty());
				}
			}
		}
		break;
	}
	case EXT_FLAC: {
		if (TagLib::FLAC::File *flacFile = static_cast<TagLib::FLAC::File*>(_file)) {
			atLeastOnePicture = !flacFile->pictureList().isEmpty();
		}
	}
	default:
		break;
	}
	return atLeastOnePicture;
}
示例#7
0
文件: taglib_ext.cpp 项目: pft/taggit
/**
 * When make sure an apetag is there, so that saving a mp3 file back
 * can include apetags too.
 *
 * This is needed, since taglib will only create apetags in mp3 files
 * if that is explicitly requested.
 *
 * Only use this for FT_MPEG files. Other types may not have the required
 * method, which will cause fatal problems.
 *
 * @param   file    TagLib_File pointer to the mp3 in question.
 *
 * @return      void
 * @sideeffects none
 */
void
mp3_dotheape(TagLib_File *file)
{
    TagLib::MPEG::File *f;

    f = reinterpret_cast<TagLib::MPEG::File *>(file);
    f->APETag(true);
}
示例#8
0
/*!
 * \brief Remove the albumart image from the file
 *
 * \param filename The music file to remove the albumart
 * \param albumart The Album Art image to remove
 * \returns True if successful
 */
bool MetaIOID3::removeAlbumArt(const QString &filename, const AlbumArtImage *albumart)
{
    if (filename.isEmpty() || !albumart)
        return false;

    AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
    switch (albumart->imageType)
    {
        case IT_FRONTCOVER:
            type = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER:
            type = AttachedPictureFrame::BackCover;
            break;
        case IT_CD:
            type = AttachedPictureFrame::Media;
            break;
        case IT_INLAY:
            type = AttachedPictureFrame::LeafletPage;
            break;
        default:
            type = AttachedPictureFrame::Other;
            break;
    }

    TagLib::MPEG::File *mpegfile = OpenFile(filename);

    if (!mpegfile)
        return false;

    TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

    if (!tag)
    {
        delete mpegfile;
        return false;
    }

    AttachedPictureFrame *apic = findAPIC(tag, type, QStringToTString(albumart->description));
    if (!apic)
    {
        delete mpegfile;
        return false;
    }

    tag->removeFrame(apic);

    mpegfile->save();
    delete mpegfile;

    return true;
}
示例#9
0
/*!
* \brief Open the file to read the tag
*
* \param filename The filename
* \returns A taglib file object for this format
*/
TagLib::MPEG::File *MetaIOID3::OpenFile(const QString &filename)
{
    QByteArray fname = filename.toLocal8Bit();
    TagLib::MPEG::File *mpegfile = new TagLib::MPEG::File(fname.constData());

    if (!mpegfile->isOpen())
    {
        delete mpegfile;
        mpegfile = NULL;
    }

    return mpegfile;
}
示例#10
0
bool FileHelper::save()
{
	if (_fileType == EXT_MP3) {
		TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file);
		// TagLib updates tags with the latest version (ID3v2.4)
		// We just want to save the file with the exact same version!
		if (mpegFile->hasID3v2Tag()) {
			return mpegFile->save(TagLib::MPEG::File::AllTags, false, mpegFile->ID3v2Tag()->header()->majorVersion());
		}
	} else if (_fileType != EXT_UNKNOWN) {
		return _file->save();
	}
	return false;
}
示例#11
0
void
MetaBundle::readTags( TagLib::AudioProperties::ReadStyle readStyle )
{
    if( m_url.protocol() != "file" )
        return;

    const QString path = m_url.path();
    TagLib::FileRef fileref;
    TagLib::Tag *tag = 0;

    if( AmarokConfig::recodeID3v1Tags() && path.endsWith( ".mp3", false ) )
    {
        TagLib::MPEG::File *mpeg = new TagLib::MPEG::File( QFile::encodeName( path ), true, readStyle );
        fileref = TagLib::FileRef( mpeg );

        if( mpeg->isValid() )
            // we prefer ID3v1 over ID3v2 if recoding tags because
            // apparently this is what people who ignore ID3 standards want
            tag = mpeg->ID3v1Tag() ? (TagLib::Tag*)mpeg->ID3v1Tag() : (TagLib::Tag*)mpeg->ID3v2Tag();
    }

    else {
        fileref = TagLib::FileRef( QFile::encodeName( path ), true, readStyle );

        if( !fileref.isNull() )
            tag = fileref.tag();
    }

    if( !fileref.isNull() ) {
        if ( tag ) {
            #define strip( x ) TStringToQString( x ).stripWhiteSpace()
            m_title   = strip( tag->title() );
            m_artist  = strip( tag->artist() );
            m_album   = strip( tag->album() );
            m_comment = strip( tag->comment() );
            m_genre   = strip( tag->genre() );
            m_year    = tag->year() ? QString::number( tag->year() ) : QString();
            m_track   = tag->track() ? QString::number( tag->track() ) : QString();
            #undef strip

            m_isValidMedia = true;
        }

        init( fileref.audioProperties() );
    }

    //FIXME disabled for beta4 as it's simpler to not got 100 bug reports
    //else if( KMimeType::findByUrl( m_url )->is( "audio" ) )
    //    init( KFileMetaInfo( m_url, QString::null, KFileMetaInfo::Everything ) );
}
示例#12
0
TagLib::Tag *mttFile::getTag( bool create )
{
    if ( tag == NULL ) {
		fileref = new TagLib::FileRef( QFile::encodeName( fname ).constData() );

        if ( fileref ) {
            if ( ismpeg ) {
                TagLib::MPEG::File *f = dynamic_cast<TagLib::MPEG::File *>(fileref->file());
                tag = new TagLib::ID3v2::Tag();
                if ( f->ID3v2Tag( create ) != NULL ) {
                    TagLib::Tag::duplicate( dynamic_cast<TagLib::Tag *>( f->ID3v2Tag( create ) ), tag, true );

                    // Read extra mp3 tags
                    int i;
                    for ( i = 0; i < EF_NUM; i++ ) {
                        TagLib::ID3v2::FrameList l = f->ID3v2Tag()->frameListMap()[extraFrames[i][0]];

                        if ( !l.isEmpty() ) {
                            mp3eframes += extraFrames[i][0];
                            mp3eframes += TStringToQString( l.front()->toString() );
                        }
                    }
                }


                delete fileref;
                fileref = NULL;
                return tag;
            }
            else { // If the file is ogg or flac
                tag = new TagLib::Ogg::XiphComment();
                if ( fileref->tag() ) // If a tag already exists
                    TagLib::Tag::duplicate( fileref->tag(), tag, true );
                delete fileref;
                fileref = NULL;
                return tag;
            }
        }
        else {
            //qDebug( "fileref = NULL" );
            return NULL;
        }

        delete fileref;
        fileref = NULL;
    }
    else
        return tag;
}
示例#13
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;
	}
}
示例#14
0
bool CCover::GetComposer(TagLib::FileRef& fr, std::string& composer)
{
    TagLib::MPEG::File        * mpgfile   = NULL;
    TagLib::Ogg::Vorbis::File * oggfile   = NULL;
    TagLib::FLAC::File        * flacfile  = NULL;
    TagLib::Ogg::XiphComment  * xiph      = NULL;
    TagLib::ID3v2::Tag        * id3v2     = NULL;
#ifdef TAGLIB_HAVE_MP4
    TagLib::MP4::File         * mp4file   = NULL;
    TagLib::MP4::Tag          * mp4       = NULL;
#endif

    if ((oggfile = dynamic_cast<TagLib::Ogg::Vorbis::File*>(fr.file()))) {
        xiph=oggfile->tag();
        //log_debug("ogg");
    } else if ((flacfile = dynamic_cast<TagLib::FLAC::File*>(fr.file()))) {
        xiph=flacfile->xiphComment();
        id3v2=flacfile->ID3v2Tag();
        //log_debug("flac");
    } else if ((mpgfile = dynamic_cast<TagLib::MPEG::File*>(fr.file()))) {
        id3v2=mpgfile->ID3v2Tag();
        //log_debug("mpg");
    }
#ifdef TAGLIB_HAVE_MP4
    else if ((mp4file = dynamic_cast<TagLib::MP4::File*>(fr.file()))) {
        mp4=mp4file->tag();
    }
#endif
#ifndef TAGLIB_HAVE_MP4
    void* mp4 = NULL;
#endif
    //log_debug4("xiph=%p, id3v2=%p, mp4=%p", xiph, id3v2, mp4);

    bool retval = true;
    if (xiph)
        retval = xiph_get_field(xiph, "COMPOSER",composer);
    else if (id3v2)
        retval = id3v2_get_field(id3v2, "TCOM",composer);
#ifdef TAGLIB_HAVE_MP4
    else if (mp4)
        retval = mp4_get_field(mp4file, "\251wrt",composer);
#endif
    else
        retval = false;

    //log_debug2("composer = %s", composer.c_str());

    return retval;
}
示例#15
0
bool CTagBase::addImage(wchar_t* s)
{
	if (!_tagFile) return false;
	TagLib::MPEG::File *pAudioFile = (TagLib::MPEG::File *)_tagFile.get();
	CString strFileName = s;
	ImageFile imageFile((CW2A)strFileName.GetBuffer());
	if (!pAudioFile->isValid() || !imageFile.isValid())
		return false;
	TagLib::ID3v2::Tag *tag = pAudioFile->ID3v2Tag(true);
	TagLib::ID3v2::AttachedPictureFrame *frame = new TagLib::ID3v2::AttachedPictureFrame;
	frame->setMimeType(imageFile.mimeType());
	frame->setPicture(imageFile.data());
	tag->addFrame(frame);
	return pAudioFile->save();

}
示例#16
0
Cover* FileHelper::extractCover()
{
	Cover *cover = nullptr;
	switch (_fileType) {
	case EXT_MP3: {
		TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file);
		if (mpegFile && mpegFile->hasID3v2Tag()) {
			// Look for picture frames only
			TagLib::ID3v2::FrameList listOfMp3Frames = mpegFile->ID3v2Tag()->frameListMap()["APIC"];
			// It's possible to have more than one picture per file!
			if (!listOfMp3Frames.isEmpty()) {
				for (TagLib::ID3v2::FrameList::ConstIterator it = listOfMp3Frames.begin(); it != listOfMp3Frames.end() ; it++) {
					// Cast a Frame* to AttachedPictureFrame*
					TagLib::ID3v2::AttachedPictureFrame *pictureFrame = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it);
					if (pictureFrame) {
						// Performs a deep copy of the cover
						QByteArray b = QByteArray(pictureFrame->picture().data(), pictureFrame->picture().size());
						cover = new Cover(b, QString(pictureFrame->mimeType().toCString(true)));
					}
				}
			}
		} else if (mpegFile && mpegFile->hasID3v1Tag()) {
			qDebug() << Q_FUNC_INFO << "Not implemented for ID3v1Tag";
		}
		break;
	}
	case EXT_FLAC: {
		if (TagLib::FLAC::File *flacFile = static_cast<TagLib::FLAC::File*>(_file)) {
			auto list = flacFile->pictureList();
			for (auto it = list.begin(); it != list.end() ; it++) {
				TagLib::FLAC::Picture *p = *it;
				if (p->type() == TagLib::FLAC::Picture::FrontCover) {
					// Performs a deep copy of the cover
					QByteArray b = QByteArray(p->data().data(), p->data().size());
					cover = new Cover(b, QString(p->mimeType().toCString(true)));
					break;
				}
			}
		}
		break;
	}
	default:
		qDebug() << Q_FUNC_INFO << "Not implemented for this file type" << _fileType << _file << _fileInfo.absoluteFilePath();
		break;
	}
	return cover;
}
示例#17
0
bool CTagBase::exportImage(const wchar_t* s)
{
	if (!s)	return false;
	if (_tagFile)
	{
		//get picture
		TagLib::MPEG::File *f = (TagLib::MPEG::File *)_tagFile.get();
		if (!f->hasID3v2Tag() || f->ID3v2Tag()->isEmpty())
			return false;
		/*
		TagLib::ID3v2::FrameList::ConstIterator it = f->ID3v2Tag()->frameList().begin();
		for (; it != f->ID3v2Tag()->frameList().end(); it++)
		{
			if ((*it)->frameID().operator == (TagLib::ByteVector("APIC")))
			{
				HANDLE hFile = CreateFile(s, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
				if (INVALID_HANDLE_VALUE == hFile)
					return false;
				int nWriteBytes = 0;
				size_t size = (*it)->size();
				::WriteFile(hFile, (*it)->render().data(), (*it)->size(), (LPDWORD)&nWriteBytes, NULL);
				::CloseHandle(hFile);
				if (nWriteBytes != size)
					return false;
				return true;
			}
		}*/
		if (f->ID3v2Tag()->frameListMap().size() == 0)
			return false;
		if (f->ID3v2Tag()->frameListMap().find("APIC") == f->ID3v2Tag()->frameListMap().end())
			return false;

		TagLib::ID3v2::FrameList Flist = f->ID3v2Tag()->frameListMap()["APIC"];
		if (Flist.isEmpty())
			return false;
		TagLib::ID3v2::AttachedPictureFrame *p = static_cast<TagLib::ID3v2::AttachedPictureFrame *>(Flist.front());
		size_t size = p->picture().size();
		CString strPicType = p->mimeType().toCString(true);
		int nPos = strPicType.Find('/');
		CString strTemp = strPicType.Right(strPicType.GetLength() - nPos - 1);
		//CString strPicPath   = s;

		//if (strTemp == _T("png"))
		//	strPicPath.Append(_T(".png"));
		//else
		//	strPicPath.Append(_T(".jpg"));

		HANDLE hFile = CreateFile(s, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		if (INVALID_HANDLE_VALUE == hFile)
			return false;
		int nWriteBytes = 0;
		::WriteFile(hFile, p->picture().data(), size, (LPDWORD)&nWriteBytes, NULL);
		::CloseHandle(hFile);
		if (nWriteBytes != size)
			return false;

		return true;
	}
	return false;
}
示例#18
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;
	}
}
示例#19
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();
    }

}
示例#20
0
/*!
 * \brief Read the albumart images from the file
 *
 * \param filename The filename for which we want to find the images.
 */
AlbumArtList MetaIOID3::getAlbumArtList(const QString &filename)
{
    AlbumArtList imageList;
    QByteArray fname = filename.toLocal8Bit();
    TagLib::MPEG::File *mpegfile = new TagLib::MPEG::File(fname.constData());

    if (mpegfile)
    {
        TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

        if (!tag)
        {
            delete mpegfile;
            return imageList;
        }

        imageList = readAlbumArt(tag);

        delete mpegfile;
    }

    return imageList;
}
示例#21
0
文件: taglib_ext.cpp 项目: pft/taggit
/**
 * Save a file back to disc
 *
 * This is a wrapper around a file type's save() method, which
 * also handles file type specific actions.
 *
 * @param   file    pointer to the taggit_file structure describing
 *                  the file in question
 *
 * @return      1 if the save() method returned true; 0 otherwise
 * @sideeffects none
 */
int
taggit_file_save(struct taggit_file *file)
{
    bool rc;
    int mask;

    switch (file->type) {
    case FT_MPEG:
        TagLib::MPEG::File *f;

        f = reinterpret_cast<TagLib::MPEG::File *>(file->data);
        mask = setup_get_write_mask(FT_MPEG);
#ifdef TAGGIT_DEBUG
        fprintf(stderr, "writemask (mp3): %d\n", mask);
#endif
        rc = f->save(mask, 1);
        break;
    default:
        rc = taglib_file_save(file->data);
    }

    return rc ? 1 : 0;
}
示例#22
0
void mttFile::removeTag( void )
{
	fileref = new TagLib::FileRef( QFile::encodeName( fname ).constData() );

    if ( ismpeg ) {
        TagLib::MPEG::File *f = dynamic_cast<TagLib::MPEG::File *>(fileref->file());
        f->strip();
    }
    else {
        TagLib::Tag *intag = fileref->tag();

        intag->setTitle( TagLib::String::null );
        intag->setArtist( TagLib::String::null );
        intag->setAlbum( TagLib::String::null );
        intag->setComment( TagLib::String::null );
        intag->setGenre( TagLib::String::null );
        intag->setYear( 0 );
        intag->setTrack( 0 );
        fileref->save();
    }

    delete fileref;
    fileref = NULL;
}
示例#23
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;
}
示例#24
0
/** Sets the inner picture. */
void FileHelper::setCover(Cover *cover)
{
	switch (_fileType) {
	case EXT_MP3: {
		TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file);
		if (mpegFile->hasID3v2Tag()) {
			// Look for picture frames only
			TagLib::ID3v2::FrameList mp3Frames = mpegFile->ID3v2Tag()->frameListMap()["APIC"];
			if (!mp3Frames.isEmpty()) {
				for (TagLib::ID3v2::FrameList::Iterator it = mp3Frames.begin(); it != mp3Frames.end() ; it++) {
					// Removing a frame will invalidate any pointers on the list
					mpegFile->ID3v2Tag()->removeFrame(*it);
					break;
				}
			}
			if (cover != nullptr) {
				TagLib::ByteVector bv(cover->byteArray().data(), cover->byteArray().length());
				TagLib::ID3v2::AttachedPictureFrame *pictureFrame = new TagLib::ID3v2::AttachedPictureFrame();
				pictureFrame->setMimeType(cover->mimeType());
				pictureFrame->setPicture(bv);
				pictureFrame->setType(TagLib::ID3v2::AttachedPictureFrame::FrontCover);
				mpegFile->ID3v2Tag()->addFrame(pictureFrame);
			}
		} else if (mpegFile->hasID3v1Tag()) {
			qDebug() << Q_FUNC_INFO << "Not implemented for ID3v1Tag";
		}
		break;
	}
	case EXT_FLAC: {
		TagLib::FLAC::File *flacFile = static_cast<TagLib::FLAC::File*>(_file);
		flacFile->removePictures();
		if (cover != nullptr) {
			TagLib::FLAC::Picture *picture = new TagLib::FLAC::Picture;
			picture->setType(TagLib::FLAC::Picture::FrontCover);
			TagLib::ByteVector bv(cover->byteArray().data(), cover->byteArray().length());
			picture->setData(bv);
			flacFile->addPicture(picture);
		}
		break;
	}
	default:
		qDebug() << Q_FUNC_INFO << "Not implemented for" << _fileType;
		break;
	}
}
示例#25
0
QByteArray TagReader::LoadEmbeddedArt(const QString& filename) const {
  if (filename.isEmpty()) return QByteArray();

  qLog(Debug) << "Loading art from" << filename;

#ifdef Q_OS_WIN32
  TagLib::FileRef ref(filename.toStdWString().c_str());
#else
  TagLib::FileRef ref(QFile::encodeName(filename).constData());
#endif

  if (ref.isNull() || !ref.file()) return QByteArray();

  // MP3
  TagLib::MPEG::File* file = dynamic_cast<TagLib::MPEG::File*>(ref.file());
  if (file && file->ID3v2Tag()) {
    TagLib::ID3v2::FrameList apic_frames =
        file->ID3v2Tag()->frameListMap()["APIC"];
    if (apic_frames.isEmpty()) return QByteArray();

    TagLib::ID3v2::AttachedPictureFrame* pic =
        static_cast<TagLib::ID3v2::AttachedPictureFrame*>(apic_frames.front());

    return QByteArray((const char*)pic->picture().data(),
                      pic->picture().size());
  }

  // Ogg vorbis/speex
  TagLib::Ogg::XiphComment* xiph_comment =
      dynamic_cast<TagLib::Ogg::XiphComment*>(ref.file()->tag());

  if (xiph_comment) {
    TagLib::Ogg::FieldListMap map = xiph_comment->fieldListMap();

    // Other than the below mentioned non-standard COVERART,
    // METADATA_BLOCK_PICTURE
    // is the proposed tag for cover pictures.
    // (see http://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE)
    if (map.contains("METADATA_BLOCK_PICTURE")) {
      TagLib::StringList pict_list = map["METADATA_BLOCK_PICTURE"];
      for (std::list<TagLib::String>::iterator it = pict_list.begin();
           it != pict_list.end(); ++it) {
        QByteArray data(QByteArray::fromBase64(it->toCString()));
        TagLib::ByteVector tdata(data.data(), data.size());
        TagLib::FLAC::Picture p(tdata);
        if (p.type() == TagLib::FLAC::Picture::FrontCover)
          return QByteArray(p.data().data(), p.data().size());
      }
      // If there was no specific front cover, just take the first picture
      QByteArray data(QByteArray::fromBase64(
          map["METADATA_BLOCK_PICTURE"].front().toCString()));
      TagLib::ByteVector tdata(data.data(), data.size());
      TagLib::FLAC::Picture p(tdata);
      return QByteArray(p.data().data(), p.data().size());
    }

    // Ogg lacks a definitive standard for embedding cover art, but it seems
    // b64 encoding a field called COVERART is the general convention
    if (!map.contains("COVERART")) return QByteArray();

    return QByteArray::fromBase64(map["COVERART"].toString().toCString());
  }

#ifdef TAGLIB_HAS_FLAC_PICTURELIST
  // Flac
  TagLib::FLAC::File* flac_file = dynamic_cast<TagLib::FLAC::File*>(ref.file());
  if (flac_file && flac_file->xiphComment()) {
    TagLib::List<TagLib::FLAC::Picture*> pics = flac_file->pictureList();
    if (!pics.isEmpty()) {
      // Use the first picture in the file - this could be made cleverer and
      // pick the front cover if it's present.

      std::list<TagLib::FLAC::Picture*>::iterator it = pics.begin();
      TagLib::FLAC::Picture* picture = *it;

      return QByteArray(picture->data().data(), picture->data().size());
    }
  }
#endif

  // MP4/AAC
  TagLib::MP4::File* aac_file = dynamic_cast<TagLib::MP4::File*>(ref.file());
  if (aac_file) {
    TagLib::MP4::Tag* tag = aac_file->tag();
    const TagLib::MP4::ItemListMap& items = tag->itemListMap();
    TagLib::MP4::ItemListMap::ConstIterator it = items.find("covr");
    if (it != items.end()) {
      const TagLib::MP4::CoverArtList& art_list = it->second.toCoverArtList();

      if (!art_list.isEmpty()) {
        // Just take the first one for now
        const TagLib::MP4::CoverArt& art = art_list.front();
        return QByteArray(art.data().data(), art.data().size());
      }
    }
  }

  return QByteArray();
}
示例#26
0
bool CTagLoaderTagLib::Load(const std::string& strFileName, CMusicInfoTag& tag, const std::string& fallbackFileExtension, MUSIC_INFO::EmbeddedArt *art /* = NULL */)
{
  std::string strExtension = URIUtils::GetExtension(strFileName);
  StringUtils::TrimLeft(strExtension, ".");

  if (strExtension.empty())
  {
    strExtension = fallbackFileExtension;
    if (strExtension.empty())
      return false;
  }

  StringUtils::ToLower(strExtension);
  TagLibVFSStream*           stream = new TagLibVFSStream(strFileName, true);
  if (!stream)
  {
    CLog::Log(LOGERROR, "could not create TagLib VFS stream for: %s", strFileName.c_str());
    return false;
  }

  ID3v1::Tag::setStringHandler(&ID3v1StringHandler);
  ID3v2::Tag::setLatin1StringHandler(&ID3v2StringHandler);
  TagLib::File*              file = NULL;
  TagLib::APE::File*         apeFile = NULL;
  TagLib::ASF::File*         asfFile = NULL;
  TagLib::FLAC::File*        flacFile = NULL;
  TagLib::IT::File*          itFile = NULL;
  TagLib::Mod::File*         modFile = NULL;
  TagLib::MP4::File*         mp4File = NULL;
  TagLib::MPC::File*         mpcFile = NULL;
  TagLib::MPEG::File*        mpegFile = NULL;
  TagLib::Ogg::Vorbis::File* oggVorbisFile = NULL;
  TagLib::Ogg::FLAC::File*   oggFlacFile = NULL;
  TagLib::S3M::File*         s3mFile = NULL;
  TagLib::TrueAudio::File*   ttaFile = NULL;
  TagLib::WavPack::File*     wvFile = NULL;
  TagLib::XM::File*          xmFile = NULL;
  TagLib::RIFF::WAV::File *  wavFile = NULL;
  TagLib::RIFF::AIFF::File * aiffFile = NULL;

  if (strExtension == "ape")
    file = apeFile = new APE::File(stream);
  else if (strExtension == "asf" || strExtension == "wmv" || strExtension == "wma")
    file = asfFile = new ASF::File(stream);
  else if (strExtension == "flac")
    file = flacFile = new FLAC::File(stream, ID3v2::FrameFactory::instance());
  else if (strExtension == "it")
    file = itFile = new IT::File(stream);
  else if (strExtension == "mod" || strExtension == "module" || strExtension == "nst" || strExtension == "wow")
    file = modFile = new Mod::File(stream);
  else if (strExtension == "mp4" || strExtension == "m4a" ||
           strExtension == "m4r" || strExtension == "m4b" ||
           strExtension == "m4p" || strExtension == "3g2")
    file = mp4File = new MP4::File(stream);
  else if (strExtension == "mpc")
    file = mpcFile = new MPC::File(stream);
  else if (strExtension == "mp3" || strExtension == "aac")
    file = mpegFile = new MPEG::File(stream, ID3v2::FrameFactory::instance());
  else if (strExtension == "s3m")
    file = s3mFile = new S3M::File(stream);
  else if (strExtension == "tta")
    file = ttaFile = new TrueAudio::File(stream, ID3v2::FrameFactory::instance());
  else if (strExtension == "wv")
    file = wvFile = new WavPack::File(stream);
  else if (strExtension == "aif" || strExtension == "aiff")
    file = aiffFile = new RIFF::AIFF::File(stream);
  else if (strExtension == "wav")
    file = wavFile = new RIFF::WAV::File(stream);
  else if (strExtension == "xm")
    file = xmFile = new XM::File(stream);
  else if (strExtension == "ogg")
    file = oggVorbisFile = new Ogg::Vorbis::File(stream);
  else if (strExtension == "oga") // Leave this madness until last - oga container can have Vorbis or FLAC
  {
    file = oggFlacFile = new Ogg::FLAC::File(stream);
    if (!file || !file->isValid())
    {
      delete file;
      oggFlacFile = NULL;
      file = oggVorbisFile = new Ogg::Vorbis::File(stream);
    }
  }

  if (!file || !file->isOpen())
  {
    delete file;
    delete stream;
    CLog::Log(LOGDEBUG, "file could not be opened for tag reading");
    return false;
  }

  APE::Tag *ape = NULL;
  ASF::Tag *asf = NULL;
  MP4::Tag *mp4 = NULL;
  ID3v1::Tag *id3v1 = NULL;
  ID3v2::Tag *id3v2 = NULL;
  Ogg::XiphComment *xiph = NULL;
  Tag *generic = NULL;

  if (apeFile)
    ape = apeFile->APETag(false);
  else if (asfFile)
    asf = asfFile->tag();
  else if (flacFile)
  {
    xiph = flacFile->xiphComment(false);
    id3v2 = flacFile->ID3v2Tag(false);
  }
  else if (mp4File)
    mp4 = mp4File->tag();
  else if (mpegFile)
  {
    id3v1 = mpegFile->ID3v1Tag(false);
    id3v2 = mpegFile->ID3v2Tag(false);
    ape = mpegFile->APETag(false);
  }
  else if (oggFlacFile)
    xiph = dynamic_cast<Ogg::XiphComment *>(oggFlacFile->tag());
  else if (oggVorbisFile)
    xiph = dynamic_cast<Ogg::XiphComment *>(oggVorbisFile->tag());
  else if (ttaFile)
    id3v2 = ttaFile->ID3v2Tag(false);
  else if (aiffFile)
    id3v2 = aiffFile->tag();
  else if (wavFile)
#if TAGLIB_MAJOR_VERSION > 1 || TAGLIB_MINOR_VERSION > 8
    id3v2 = wavFile->ID3v2Tag();
#else
    id3v2 = wavFile->tag();
#endif
  else if (wvFile)
示例#27
0
bool mttFile::Open( QString filename )
{
    bool changed = false;

    fname = filename;

    fileref = new TagLib::FileRef( QFile::encodeName( filename ).constData() );
    if ( filename.endsWith( QString( ".mp3" ), Qt::CaseInsensitive ) ) {
        ismpeg = true;
        TagLib::MPEG::File *f = dynamic_cast<TagLib::MPEG::File *>(fileref->file());
        if ( f ) {
            if ( f->ID3v1Tag() ) {
                if ( !(f->ID3v2Tag()) ) {
					qDebug("ID3v1 found");
                    // Copy id3v1 tag to id3v2 tag
                    TagLib::ID3v1::Tag *v1tag = f->ID3v1Tag();
                    TagLib::ID3v2::Tag *v2tag = f->ID3v2Tag( true );
    
                    v2tag->setAlbum( v1tag->album() );
                    v2tag->setArtist( v1tag->artist() );
                    v2tag->setComment( v1tag->comment() );
                    v2tag->setGenre( v1tag->genre() );
                    v2tag->setTitle( v1tag->title() );
                    v2tag->setTrack( v1tag->track() );
                    v2tag->setYear( v1tag->year() );
                    changed = true;
                }
                else if ( f->ID3v2Tag() && f->ID3v1Tag() ) {
					qDebug("ID3v1 & v2 found");
                    // Fill gaps of ID3v2Tag from ID3v1Tag
                    TagLib::ID3v1::Tag *v1tag = f->ID3v1Tag();
                    TagLib::ID3v2::Tag *v2tag = f->ID3v2Tag();
    
                    if ( v2tag->album().isEmpty() ) {
                        v2tag->setAlbum( v1tag->album() );
                        changed = true;
                    }
                    if ( v2tag->artist().isEmpty() ) {
                        v2tag->setArtist( v1tag->artist() );
                        changed = true;
                    }
                    if ( v2tag->comment().isEmpty() ) {
                        v2tag->setComment( v1tag->comment() );
                        changed = true;
                    }
                    if ( v2tag->genre().isEmpty() ) {
                        v2tag->setGenre( v1tag->genre() );
                        changed = true;
                    }
                    if ( v2tag->title().isEmpty() ) {
                        v2tag->setTitle( v1tag->title() );
                        changed = true;
                    }
                    if ( v2tag->track() == 0 ) {
                        v2tag->setTrack( v1tag->track() );
                        changed = true;
                    }
                    if ( v2tag->year() == 0 ) {
                        v2tag->setYear( v1tag->year() );
                        changed = true;
                    }
                }
            }
        }
    }
    else if ( filename.endsWith( QString( ".ogg" ), Qt::CaseInsensitive ) ) {
        isogg = true;
    }
    else if ( filename.endsWith( QString( ".flac" ), Qt::CaseInsensitive ) ) {
        isflac = true;
    }

    delete fileref;
    fileref = NULL;

    return changed;
}
示例#28
0
/*!
 * \copydoc MetaIO::read()
 */
Metadata *MetaIOID3::read(QString filename)
{
    TagLib::MPEG::File *mpegfile = OpenFile(filename);

    if (!mpegfile)
        return NULL;

    TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

    if (!tag)
    {
        delete mpegfile;
        return NULL;
    }

    // if there is no ID3v2 tag, try to read the ID3v1 tag and copy it to the ID3v2 tag structure
    if (tag->isEmpty())
    {
        TagLib::ID3v1::Tag *tag_v1 = mpegfile->ID3v1Tag();

        if (!tag_v1)
        {
            delete mpegfile;
            return NULL;
        }

        if (!tag_v1->isEmpty())
        {
            tag->setTitle(tag_v1->title());
            tag->setArtist(tag_v1->artist());
            tag->setAlbum(tag_v1->album());
            tag->setTrack(tag_v1->track());
            tag->setYear(tag_v1->year());
            tag->setGenre(tag_v1->genre());
        }
    }

    Metadata *metadata = new Metadata(filename);

    ReadGenericMetadata(tag, metadata);

    bool compilation = false;

    // Compilation Artist (TPE4 Remix) or fallback to (TPE2 Band)
    // N.B. The existance of a either frame is NOT an indication that this
    // is a compilation, but if it is then one of them will probably hold
    // the compilation artist.
    TextIdentificationFrame *tpeframe = NULL;
    TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
    if (tpelist.isEmpty() || tpelist.front()->toString().isEmpty())
        tpelist = tag->frameListMap()["TPE2"];
    if (!tpelist.isEmpty())
        tpeframe = (TextIdentificationFrame *)tpelist.front();

    if (tpeframe && !tpeframe->toString().isEmpty())
    {
        QString compilation_artist = TStringToQString(tpeframe->toString())
                                                                    .trimmed();
        metadata->setCompilationArtist(compilation_artist);
    }

    // MythTV rating and playcount, stored in POPM frame
    PopularimeterFrame *popm = findPOPM(tag, email);

    if (!popm)
    {
        if (!tag->frameListMap()["POPM"].isEmpty())
            popm = dynamic_cast<PopularimeterFrame *>
                                        (tag->frameListMap()["POPM"].front());
    }

    if (popm)
    {
        int rating = popm->rating();
        rating = static_cast<int>(((static_cast<float>(rating)/255.0)
                                                                * 10.0) + 0.5);
        metadata->setRating(rating);
        metadata->setPlaycount(popm->counter());
    }

    // Look for MusicBrainz Album+Artist ID in TXXX Frame
    UserTextIdentificationFrame *musicbrainz = find(tag,
                                            "MusicBrainz Album Artist Id");

    if (musicbrainz)
    {
        // If the MusicBrainz ID is the special "Various Artists" ID
        // then compilation is TRUE
        if (!compilation && !musicbrainz->fieldList().isEmpty())
            compilation = (MYTH_MUSICBRAINZ_ALBUMARTIST_UUID
            == TStringToQString(musicbrainz->fieldList().front()));
    }

    // TLEN - Ignored intentionally, some encoders write bad values
    // e.g. Lame under certain circumstances will always write a length of
    // 27 hours

    metadata->setCompilation(compilation);

    TagLib::FileRef *fileref = new TagLib::FileRef(mpegfile);
    metadata->setLength(getTrackLength(fileref));
    // FileRef takes ownership of mpegfile, and is responsible for it's
    // deletion. Messy.
    delete fileref;

    return metadata;
}
示例#29
0
/*!
 * \copydoc MetaIO::write()
 */
bool MetaIOID3::write(Metadata* mdata)
{
    TagLib::MPEG::File *mpegfile = OpenFile(mdata->Filename());

    if (!mpegfile)
        return false;

    TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

    if (!tag)
    {
        delete mpegfile;
        return false;
    }

    WriteGenericMetadata(tag, mdata);

    // MythTV rating and playcount, stored in POPM frame
    writeRating(tag, mdata->Rating());
    writePlayCount(tag, mdata->PlayCount());

    // MusicBrainz ID
    UserTextIdentificationFrame *musicbrainz = NULL;
    musicbrainz = find(tag, "MusicBrainz Album Artist Id");

    if (mdata->Compilation())
    {

        if (!musicbrainz)
        {
            musicbrainz = new UserTextIdentificationFrame(TagLib::String::UTF8);
            tag->addFrame(musicbrainz);
            musicbrainz->setDescription("MusicBrainz Album Artist Id");
        }

        musicbrainz->setText(MYTH_MUSICBRAINZ_ALBUMARTIST_UUID);
    }
    else if (musicbrainz)
        tag->removeFrame(musicbrainz);

    // Compilation Artist Frame (TPE4/2)
    if (!mdata->CompilationArtist().isEmpty())
    {
        TextIdentificationFrame *tpe4frame = NULL;
        TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
        if (!tpelist.isEmpty())
            tpe4frame = (TextIdentificationFrame *)tpelist.front();

        if (!tpe4frame)
        {
            tpe4frame = new TextIdentificationFrame(TagLib::ByteVector("TPE4"),
                                                    TagLib::String::UTF8);
                                                    tag->addFrame(tpe4frame);
        }
        tpe4frame->setText(QStringToTString(mdata->CompilationArtist()));


        TextIdentificationFrame *tpe2frame = NULL;
        tpelist = tag->frameListMap()["TPE2"];
        if (!tpelist.isEmpty())
            tpe2frame = (TextIdentificationFrame *)tpelist.front();

        if (!tpe2frame)
        {
            tpe2frame = new TextIdentificationFrame(TagLib::ByteVector("TPE2"),
                                                    TagLib::String::UTF8);
                                                    tag->addFrame(tpe2frame);
        }
        tpe2frame->setText(QStringToTString(mdata->CompilationArtist()));
    }

    bool result = mpegfile->save();

    delete mpegfile;

    return result;
}
示例#30
0
/*!
 * \brief Write the albumart image to the file
 *
 * \param filename The music file to add the albumart
 * \param albumart The Album Art image to write
 * \returns True if successful
 *
 * \Note We always save the image in JPEG format
 */
bool MetaIOID3::writeAlbumArt(const QString &filename, const AlbumArtImage *albumart)
{
    if (filename.isEmpty() || !albumart)
        return false;

    // load the image into a QByteArray
    QImage image(albumart->filename);
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "JPEG");

    AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
    switch (albumart->imageType)
    {
        case IT_FRONTCOVER:
            type = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER:
            type = AttachedPictureFrame::BackCover;
            break;
        case IT_CD:
            type = AttachedPictureFrame::Media;
            break;
        case IT_INLAY:
            type = AttachedPictureFrame::LeafletPage;
            break;
        default:
            type = AttachedPictureFrame::Other;
            break;
    }

    TagLib::MPEG::File *mpegfile = OpenFile(filename);

    if (!mpegfile)
        return false;

    TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

    if (!tag)
    {
        delete mpegfile;
        return false;
    }

    AttachedPictureFrame *apic = findAPIC(tag, type, QStringToTString(albumart->description));

    if (!apic)
    {
        apic = new AttachedPictureFrame();
        tag->addFrame(apic);
        apic->setType(type);
    }

    QString mimetype = "image/jpeg";

    TagLib::ByteVector bytevector;
    bytevector.setData(imageData.data(), imageData.size());

    apic->setMimeType(QStringToTString(mimetype));
    apic->setPicture(bytevector);
    apic->setDescription(QStringToTString(albumart->description));

    mpegfile->save();
    delete mpegfile;

    return true;
}