int tag_data_get_bitdepth(char * filename) { TagLib::String s = filename; TagLib::FLAC::File * f = new TagLib::FLAC::File(filename); if (! f->isValid ()) return 0; return ( f->audioProperties()->sampleWidth()); }
/*! * \copydoc MetaIO::read() */ Metadata* MetaIOFLACVorbis::read(QString filename) { TagLib::FLAC::File *flacfile = OpenFile(filename); if (!flacfile) return NULL; TagLib::Ogg::XiphComment *tag = flacfile->xiphComment(); if (!tag) { delete flacfile; return NULL; } Metadata *metadata = new Metadata(filename); ReadGenericMetadata(tag, metadata); bool compilation = false; if (tag->contains("COMPILATION_ARTIST")) { QString compilation_artist = TStringToQString( tag->fieldListMap()["COMPILATION_ARTIST"].toString()).trimmed(); if (compilation_artist != metadata->Artist()) { metadata->setCompilationArtist(compilation_artist); compilation = true; } } if (!compilation && tag->contains("MUSICBRAINZ_ALBUMARTISTID")) { QString musicbrainzcode = TStringToQString( tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString()).trimmed(); if (musicbrainzcode == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID) compilation = true; } metadata->setCompilation(compilation); if (metadata->Length() <= 0) { TagLib::FileRef *fileref = new TagLib::FileRef(flacfile); metadata->setLength(getTrackLength(fileref)); // FileRef takes ownership of flacfile, and is responsible for it's // deletion. Messy. delete fileref; } else delete flacfile; return metadata; }
/*! * \brief Open the file to read the tag * * \param filename The filename * \returns A taglib file object for this format */ TagLib::FLAC::File *MetaIOFLACVorbis::OpenFile(const QString &filename) { QByteArray fname = filename.toLocal8Bit(); TagLib::FLAC::File *flacfile = new TagLib::FLAC::File(fname.constData()); if (!flacfile->isOpen()) { delete flacfile; flacfile = NULL; } return flacfile; }
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; }
/*! * \copydoc MetaIO::write() */ bool MetaIOFLACVorbis::write(Metadata* mdata) { if (!mdata) return false; TagLib::FLAC::File *flacfile = OpenFile(mdata->Filename()); if (!flacfile) return false; TagLib::Ogg::XiphComment *tag = flacfile->xiphComment(); if (!tag) { delete flacfile; return false; } WriteGenericMetadata(tag, mdata); // Compilation if (mdata->Compilation()) { tag->addField("MUSICBRAINZ_ALBUMARTISTID", MYTH_MUSICBRAINZ_ALBUMARTIST_UUID, true); tag->addField("COMPILATION_ARTIST", QStringToTString(mdata->CompilationArtist()), true); } else { // Don't remove the musicbrainz field unless it indicated a compilation if (tag->contains("MUSICBRAINZ_ALBUMARTISTID") && (tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString() == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID)) { tag->removeField("MUSICBRAINZ_ALBUMARTISTID"); } tag->removeField("COMPILATION_ARTIST"); } bool result = flacfile->save(); if (flacfile) delete flacfile; return (result); }
/** 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; } }
/** 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(); }
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)
bool CTagLoaderTagLib::Load(const string& strFileName, CMusicInfoTag& tag, EmbeddedArt *art /* = NULL */) { CStdString strExtension; URIUtils::GetExtension(strFileName, strExtension); strExtension.ToLower(); strExtension.TrimLeft('.'); if (strExtension.IsEmpty()) return false; TagLibVFSStream* stream = new TagLibVFSStream(strFileName, true); if (!stream) { CLog::Log(LOGERROR, "could not create TagLib VFS stream for: %s", strFileName.c_str()); return false; } 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; 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 == "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; 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; 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) { 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 (wvFile) ape = wvFile->APETag(false); else // This is a catch all to get generic information for other files types (s3m, xm, it, mod, etc) generic = file->tag(); if (file->audioProperties()) tag.SetDuration(file->audioProperties()->length()); if (ape && !g_advancedSettings.m_prioritiseAPEv2tags) ParseAPETag(ape, art, tag); if (asf) ParseASF(asf, art, tag); else if (id3v2) ParseID3v2Tag(id3v2, art, tag); else if (generic) ParseGenericTag(generic, art, tag); else if (mp4) ParseMP4Tag(mp4, art, tag); else if (xiph) ParseXiphComment(xiph, art, tag); // art for flac files is outside the tag if (flacFile) SetFlacArt(flacFile, art, tag); // Add APE tags over the top of ID3 tags if we want to prioritize them if (ape && g_advancedSettings.m_prioritiseAPEv2tags) ParseAPETag(ape, art, tag); if (!tag.GetTitle().IsEmpty() || !tag.GetArtist().empty() || !tag.GetAlbum().IsEmpty()) tag.SetLoaded(); tag.SetURL(strFileName); delete file; delete stream; return true; }
/* LOAD UP THE FILE'S TAG * Search each file type individually so we can get individual tags for * custom tagging. */ TagDatac * tag_data_load (char *url, int *pvalid) { TagData * data; TagLib::String s = url; int mtime; struct stat buf; if (!stat (url, &buf)) mtime = (int) buf.st_mtime; /* FIXME: Using filename to find media type. GStreamer probe instead? */ if(s.size() > 4) { if(s.substr(s.size() - 4, 4).upper() == ".OGG") { TagLib::Vorbis::File * f = new TagLib::Vorbis::File(url); if (! f->isValid ()) return NULL; data = (TagData*) malloc (sizeof (TagData)); data->file = new TagLib::FileRef (f); data->id3v2 = NULL; data->id3v1 = NULL; data->ape = NULL; data->xiph = f->tag (); data->mime = "application/ogg"; data->mtime = mtime; return reinterpret_cast<TagDatac *> (data); } if(s.substr(s.size() - 4, 4).upper() == ".MP3") { TagLib::MPEG::File * f = new TagLib::MPEG::File(url); if (! f->isValid ()) return NULL; data = (TagData*) malloc (sizeof (TagData)); data->file = new TagLib::FileRef (f); data->id3v2 = f->ID3v2Tag (); data->id3v1 = f->ID3v1Tag (); data->ape = f->APETag (); data->xiph = NULL; data->mime = "audio/mpeg"; data->mtime = mtime; return reinterpret_cast<TagDatac *>(data); } if(s.substr(s.size() - 5, 5).upper() == ".FLAC") { TagLib::FLAC::File * f = new TagLib::FLAC::File(url); if ((! f->isValid ())&& (pvalid != NULL)){ *pvalid = -1;//paul add on 080827 merge from Olive return NULL; } data = (TagData*) malloc (sizeof (TagData)); data->file = new TagLib::FileRef (f); data->id3v2 = f->ID3v2Tag (); data->id3v1 = f->ID3v1Tag (); data->ape = NULL; data->xiph = f->xiphComment (); data->mime = "audio/x-flac"; data->mtime = mtime; return reinterpret_cast<TagDatac *>(data); } if(s.substr(s.size() - 4, 4).upper() == ".MPC" || s.substr(s.size() - 4, 4).upper() == ".AAC") { TagLib::MPC::File * f = new TagLib::MPC::File(url); if (! f->isValid ()) return NULL; data = (TagData*) malloc (sizeof (TagData)); data->file = new TagLib::FileRef (f); data->id3v2 = NULL; data->id3v1 = f->ID3v1Tag (); data->ape = f->APETag (); data->xiph = NULL; data->mime = "audio/x-musepack"; data->mtime = mtime; return reinterpret_cast<TagDatac *>(data); } } return NULL; }
int main(int argc, char *argv[]) { for(int i = 1; i < argc; i++) { cout << "******************** \"" << argv[i] << "\" ********************" << endl; TagLib::FileRef f(argv[i]); if(!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); cout << "-- TAG --" << endl; cout << "title - \"" << tag->title() << "\"" << endl; cout << "artist - \"" << tag->artist() << "\"" << endl; cout << "album artist - \"" << tag->albumArtist() << "\"" << endl; cout << "album - \"" << tag->album() << "\"" << endl; cout << "year - \"" << tag->year() << "\"" << endl; cout << "comment - \"" << tag->comment() << "\"" << endl; cout << "track - \"" << tag->track() << "\"" << endl; cout << "genre - \"" << tag->genre() << "\"" << endl; cout << "grouping - \"" << tag->grouping() << "\"" << endl; TagLib::Ogg::XiphComment *comment = NULL; TagLib::FLAC::File *flac = dynamic_cast<TagLib::FLAC::File *>(f.file()); if (flac) { cout << "flac:" << endl; cout << "id3v1 - \"" << flac->ID3v1Tag() << "\"" << endl; cout << "id3v2 - \"" << flac->ID3v2Tag() << "\"" << endl; cout << "xiph - \"" << flac->xiphComment() << "\"" << endl; comment = flac->xiphComment(); } if (!comment) { comment = dynamic_cast<TagLib::Ogg::XiphComment *>(tag); } if (comment) { TagLib::Ogg::FieldListMap fields = comment->fieldListMap(); for(TagLib::Ogg::FieldListMap::ConstIterator it = fields.begin(), end = fields.end(); it != end; it++) { if (!it->second.isEmpty()) cout << "xiph:" << it->first << " \"" << it->second[0].substr(0,3) << "\"" << endl; } } cout << "pictures- \"" << f.file()->pictures().size() << "\"" << endl; TagLib::File::PictureList l = f.file()->pictures(); for (TagLib::File::_PictureList::ConstIterator i = l.begin(), end = l.end(); i != end; i++) { cout << "\t" << (*i)->typeName() << ' ' << (*i)->mimeType() << ' ' << (*i)->base64data().size() << endl; } cout << "pictures- \"" << tag->pictures().size() << "\"" << endl; } if(!f.isNull() && f.audioProperties()) { TagLib::AudioProperties *properties = f.audioProperties(); int seconds = properties->length() % 60; int minutes = (properties->length() - seconds) / 60; cout << "-- AUDIO --" << endl; cout << "bitrate - " << properties->bitrate() << endl; cout << "sample rate - " << properties->sampleRate() << endl; cout << "channels - " << properties->channels() << endl; cout << "length - " << minutes << ":" << formatSeconds(seconds) << endl; } } return 0; }