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()); } } } }
/** 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(); }
unsigned TagWriter::Write(const std::string& filename, const db::Recordset *tags) { util::Mutex::Lock lock(s_taglib_mutex); // TRACE << "Opening '" << filename << "'\n"; typedef std::map<std::string, std::string> tagmap_t; tagmap_t tagmap; for (unsigned int i=0; i<mediadb::FIELD_COUNT; ++i) { const char *s = import::GetVorbisTagForField(i); if (s) { std::string val = tags->GetString(i); if (!val.empty()) tagmap[s] = val; } } TagLib::FLAC::File tff(filename.c_str()); TagLib::Ogg::XiphComment *oxc = tff.xiphComment(true); for (tagmap_t::const_iterator i = tagmap.begin(); i != tagmap.end(); ++i) { if (!i->second.empty()) oxc->addField(i->first, TagLib::String(i->second, TagLib::String::UTF8)); } tff.save(); TRACE << "FLAC file tagged\n"; return 0; }
/*! * \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); }
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; } }
/** * Set the file-type specific `compilation' tag. * * See the discussion on top of this file about which tag is used * for which file-type. * * @param file taggit's file-data structure for the processed file * @param tag the tag-data decoded by `taglib_file_tag()' * @param value the string the user wants to set this tag to * * @return void * @sideeffects none */ void taggit_tag_set_compilation(struct taggit_file *file, TagLib_Tag *tag, const char *value) { TagLib::APE::Tag *ape; TagLib::ID3v2::Tag *v2; TagLib::Ogg::XiphComment *ogg; const char *ret; TagLib::MPEG::File::File *f; int mask; ret = (const char *)NULL; switch (file->type) { case FT_MPEG: f = reinterpret_cast<TagLib::MPEG::File::File *>(file->data); mask = setup_get_write_mask(FT_MPEG); if (mask & MP3_ID3V2) { v2 = f->ID3v2Tag(); v2->removeFrames("TPE2"); /* * @TODO: I don't know how to figure out the proper `encoding' * value here. Should we look at the `unicodeStrings' * variable from taglib? */ TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame( "TPE2", TagLib::String::Latin1); frame->setText(value); v2->addFrame(frame); } if (mask & MP3_APE) { ape = f->APETag(); ape->addValue("ALBUMARTIST", value, true); } break; case FT_OGGVORBIS: /* @FALLTHROUGH@ */ case FT_OGGFLAC: ogg = reinterpret_cast<TagLib::Ogg::XiphComment *>(tag); ogg->addField("ALBUMARTIST", value, true); break; default: break; } }
/** 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; } }