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()); } } } }
void printTags ( const std::string &file ) { printf("%s\n", file.c_str()); printf("\tid3v1:\n"); if (m_id3v1) { printf("\t\tTitle:\t\t%s\n", m_id3v1_tag->title ().to8Bit().c_str()); printf("\t\tArtist:\t\t%s\n", m_id3v1_tag->artist ().to8Bit().c_str()); printf("\t\tAlbum:\t\t%s\n", m_id3v1_tag->album ().to8Bit().c_str()); printf("\t\tComment:\t%s\n", m_id3v1_tag->comment ().to8Bit().c_str()); printf("\t\tGenre:\t\t%s\n", m_id3v1_tag->genre ().to8Bit().c_str()); } else { printf("\t\tempty.\n"); } printf("\tid3v2:\n"); if (m_id3v2) { printf("\t\tTitle:\t\t%s\n", m_id3v2_tag->title ().to8Bit(m_id3v2_utf8).c_str()); printf("\t\tArtist:\t\t%s\n", m_id3v2_tag->artist ().to8Bit(m_id3v2_utf8).c_str()); printf("\t\tAlbum:\t\t%s\n", m_id3v2_tag->album ().to8Bit(m_id3v2_utf8).c_str()); printf("\t\tComment:\t%s\n", m_id3v2_tag->comment ().to8Bit(m_id3v2_utf8).c_str()); printf("\t\tGenre:\t\t%s\n", m_id3v2_tag->genre ().to8Bit(m_id3v2_utf8).c_str()); } else { printf("\t\tempty.\n"); } }
/*! * \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; }
Json::Value Firnplayer::ScanDirectory(const std::string &Root) { // Initializations DIR *dir; struct dirent *ent; std::list<std::string> DirectoryQueue; Json::Value AllJson; // Push the root to the queue and start the scan loop DirectoryQueue.push_back(Root); while(DirectoryQueue.size()){ // Grap the front of the queue and erase it from the queue std::string ThisDirectory = *DirectoryQueue.begin(); DirectoryQueue.erase(DirectoryQueue.begin()); if((dir = opendir(ThisDirectory.c_str())) != NULL) { // Try to open the directory while ((ent = readdir(dir)) != NULL) { // First, see if it is a directory. If so, we add id to the queue for later scans. if(ent->d_type == 4 && *ent->d_name != '.') DirectoryQueue.push_back(cleanpath(ThisDirectory + "/" + ent->d_name)); else{ // If it is not a queue, we look closer at the file. // First, we want to see if it has the .mp3 ending. std::string FileName = cleanpath(ThisDirectory + "/" + ent->d_name); std::string LastFour(" "); std::transform(FileName.begin()+(FileName.size()-4), FileName.end(), LastFour.begin(), ::toupper); if(LastFour == ".MP3") { // Ok, it calls itself an mp3. Scan it! Json::Value &TrackJson = (AllJson[FileName] = Json::Value()); TagLib::MPEG::File file(FileName.c_str()); // If it has an ID3v2Tag, we use that. if(file.hasID3v2Tag()) { TagLib::ID3v2::Tag *tag = file.ID3v2Tag(true); for(TagLib::List<TagLib::ID3v2::Frame *>::ConstIterator theitr = tag->frameList().begin(); theitr != tag->frameList().end(); theitr++) { std::string framevalue = (*theitr)->toString().to8Bit(); std::string Trigger((*theitr)->frameID().data()); Trigger = std::string(Trigger.begin(), Trigger.begin()+4); TrackJson[Trigger] = framevalue; } } // Now save the file path, the bitrate and the track length. TrackJson["FILE"] = FileName; TagLib::MPEG::Properties *Properties = file.audioProperties(); TrackJson["LENG"] = Properties->length(); TrackJson["BITR"] = Properties->bitrate(); } } } } } return AllJson; }
/*! * \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; }
/*! * \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->m_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; case IT_ARTIST: type = AttachedPictureFrame::Artist; break; default: type = AttachedPictureFrame::Other; break; } if (!OpenFile(filename, true)) return false; TagLib::ID3v2::Tag *tag = GetID3v2Tag(); if (!tag) return false; AttachedPictureFrame *apic = findAPIC(tag, type, QStringToTString(albumart->m_description)); if (!apic) return false; tag->removeFrame(apic); if (!SaveFile()) return false; return true; }
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; } }
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 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(); }
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(); } }
/*! * \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->m_filename); QByteArray imageData; QBuffer buffer(&imageData); buffer.open(QIODevice::WriteOnly); image.save(&buffer, "JPEG"); AttachedPictureFrame::Type type = AttachedPictureFrame::Other; switch (albumart->m_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; case IT_ARTIST: type = AttachedPictureFrame::Artist; break; default: type = AttachedPictureFrame::Other; break; } if (!OpenFile(filename, true)) return false; TagLib::ID3v2::Tag *tag = GetID3v2Tag(); if (!tag) return false; AttachedPictureFrame *apic = findAPIC(tag, type, QStringToTString(albumart->m_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->m_description)); if (!SaveFile()) return false; return true; }
/*! * \copydoc MetaIO::read() */ MusicMetadata *MetaIOID3::read(const QString &filename) { if (!OpenFile(filename)) return nullptr; TagLib::ID3v2::Tag *tag = GetID3v2Tag(true); // Create tag if none are found // 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 = GetID3v1Tag(); if (!tag_v1) return nullptr; 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()); } } MusicMetadata *metadata = new MusicMetadata(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 = nullptr; 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); } // Rating and playcount, stored in POPM frame PopularimeterFrame *popm = findPOPM(tag, ""); // Global (all apps) tag // If no 'global' tag exists, look for the MythTV specific one if (!popm) { popm = findPOPM(tag, email); } // Fallback to using any POPM tag we can find if (!popm) { if (!tag->frameListMap()["POPM"].isEmpty()) popm = dynamic_cast<PopularimeterFrame *> (tag->frameListMap()["POPM"].front()); } if (popm) { int rating = popm->rating(); rating = lroundf(static_cast<float>(rating) / 255.0f * 10.0f); 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()) { TagLib::StringList l = musicbrainz->fieldList(); for (TagLib::StringList::ConstIterator it = l.begin(); it != l.end(); it++) { QString ID = TStringToQString((*it)); if (ID == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID) { compilation = true; break; } } } } // TLEN - Ignored intentionally, some encoders write bad values // e.g. Lame under certain circumstances will always write a length of // 27 hours // Length if (!tag->frameListMap()["TLEN"].isEmpty()) { int length = tag->frameListMap()["TLEN"].front()->toString().toInt(); LOG(VB_FILE, LOG_DEBUG, QString("MetaIOID3::read: Length for '%1' from tag is '%2'\n").arg(filename).arg(length)); } metadata->setCompilation(compilation); metadata->setLength(getTrackLength(m_file)); // The number of tracks on the album, if supplied if (!tag->frameListMap()["TRCK"].isEmpty()) { QString trackFrame = TStringToQString( tag->frameListMap()["TRCK"].front()->toString()) .trimmed(); int trackCount = trackFrame.section('/', -1).toInt(); if (trackCount > 0) metadata->setTrackCount(trackCount); } LOG(VB_FILE, LOG_DEBUG, QString("MetaIOID3::read: Length for '%1' from properties is '%2'\n").arg(filename).arg(metadata->Length())); // Look for MythTVLastPlayed in TXXX Frame UserTextIdentificationFrame *lastplayed = find(tag, "MythTVLastPlayed"); if (lastplayed) { QString lastPlayStr = TStringToQString(lastplayed->toString()); metadata->setLastPlay(QDateTime::fromString(lastPlayStr, Qt::ISODate)); } // Part of a set if (!tag->frameListMap()["TPOS"].isEmpty()) { QString pos = TStringToQString( tag->frameListMap()["TPOS"].front()->toString()).trimmed(); int discNumber = pos.section('/', 0, 0).toInt(); int discCount = pos.section('/', -1).toInt(); if (discNumber > 0) metadata->setDiscNumber(discNumber); if (discCount > 0) metadata->setDiscCount(discCount); } return metadata; }
/*! * \copydoc MetaIO::write() */ bool MetaIOID3::write(const QString &filename, MusicMetadata* mdata) { if (filename.isEmpty()) return false; if (!OpenFile(filename, true)) return false; TagLib::ID3v2::Tag *tag = GetID3v2Tag(); if (!tag) return false; WriteGenericMetadata(tag, mdata); // MythTV rating and playcount, stored in POPM frame writeRating(tag, mdata->Rating()); writePlayCount(tag, mdata->PlayCount()); writeLastPlay(tag, mdata->LastPlay()); // MusicBrainz ID UserTextIdentificationFrame *musicbrainz = nullptr; 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 = nullptr; 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 = nullptr; 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())); } if (!SaveFile()) return false; return true; }
/*! * \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; }
/*! * \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; }
/*! * \copydoc MetaIO::read() */ Metadata *MetaIOID3::read(const QString &filename) { if (!OpenFile(filename)) return NULL; TagLib::ID3v2::Tag *tag = GetID3v2Tag(true); // Create tag if none are found // 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 = GetID3v1Tag(); if (!tag_v1) 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 // Length if (!tag->frameListMap()["TLEN"].isEmpty()) { int length = tag->frameListMap()["TLEN"].front()->toString().toInt(); LOG(VB_FILE, LOG_DEBUG, QString("MetaIOID3::read: Length for '%1' from tag is '%2'\n").arg(filename).arg(length)); } metadata->setCompilation(compilation); metadata->setLength(getTrackLength(m_file)); // The number of tracks on the album, if supplied if (!tag->frameListMap()["TRCK"].isEmpty()) { QString trackFrame = TStringToQString( tag->frameListMap()["TRCK"].front()->toString()) .trimmed(); int trackCount = trackFrame.section('/', -1).toInt(); if (trackCount > 0) metadata->setTrackCount(trackCount); } LOG(VB_FILE, LOG_DEBUG, QString("MetaIOID3::read: Length for '%1' from properties is '%2'\n").arg(filename).arg(metadata->Length())); return metadata; }
void saveFile(string stdPath, DataEditors* editors) { const char* charPath = stdPath.c_str(); ifstream fileCheck(charPath); if(!fileCheck.good()) { QWidget *w = new QWidget(); QLabel *l = new QLabel("Invalid file!", w); QPushButton *b = new QPushButton("OK", w); QVBoxLayout *lay = new QVBoxLayout(); lay->addWidget(l); lay->addWidget(b); w->setLayout(lay); QWidget::connect(b, SIGNAL(clicked()), w, SLOT(close())); w->show(); return; } TagLib::FileName name = charPath; TagLib::FileRef file(name); if(editors->artist->isEnabled()) file.tag()->setArtist(editors->artist->text().toStdString()); if(editors->album->isEnabled()) file.tag()->setAlbum(editors->album->text().toStdString()); if(editors->track->isEnabled()) file.tag()->setTrack(editors->track->text().toInt()); if(editors->title->isEnabled()) file.tag()->setTitle(editors->title->text().toStdString()); if(editors->year->isEnabled()) file.tag()->setYear(editors->year->text().toInt()); if(editors->genre->isEnabled()) file.tag()->setGenre(editors->genre->currentText().toStdString()); if(editors->comment->isEnabled()) file.tag()->setComment(editors->comment->toPlainText().toStdString()); file.save(); if(editors->picture->isEnabled()) { TagLib::MPEG::File mpegFile(name); TagLib::ID3v2::Tag *tag = mpegFile.ID3v2Tag(true); TagLib::ID3v2::AttachedPictureFrame *frame = new TagLib::ID3v2::AttachedPictureFrame; QString picture = editors->picture->text(); if(picture == "<Attached picture>") { TagLib::ID3v2::AttachedPictureFrame *f = static_cast<TagLib::ID3v2::AttachedPictureFrame *>(editors->mpegFile->ID3v2Tag(true)->frameList("APIC").front()); frame->setMimeType(f->mimeType()); frame->setPicture(f->picture()); tag->removeFrames("APIC"); tag->addFrame(frame); mpegFile.save(); } else if(picture == "") { tag->removeFrames("APIC"); mpegFile.save(); } else { frame->setMimeType("image/jpeg"); string stdPic = picture.toStdString(); const char* charPicture = stdPic.c_str(); ifstream fileCheck(charPicture); if(!fileCheck.good()) { QWidget *w = new QWidget(); QLabel *l = new QLabel("Invalid picture!", w); QPushButton *b = new QPushButton("OK", w); QVBoxLayout *lay = new QVBoxLayout(); lay->addWidget(l); lay->addWidget(b); w->setLayout(lay); QWidget::connect(b, SIGNAL(clicked()), w, SLOT(close())); w->show(); delete w; return; } ImageFile imageTagLibFile(charPicture); frame->setPicture(imageTagLibFile.data()); tag->removeFrames("APIC"); tag->addFrame(frame); mpegFile.save(); } } }