Tag::Tag(const QString &filename) : m_filename(filename) { TagLib::MPEG::File mpegfile(filename.toLocal8Bit().constData()); TagLib::ID3v2::Tag* id3v2 = mpegfile.ID3v2Tag(); if (id3v2 && !id3v2->isEmpty()) { readRegularTag(id3v2, m_data); int picnum = 0; TagLib::ID3v2::FrameList frames = id3v2->frameListMap()["APIC"]; // attached picture TagLib::ID3v2::FrameList::ConstIterator it = frames.begin(); while (it != frames.end()) { TagLib::ID3v2::AttachedPictureFrame* apic = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it); TagLib::ByteVector bytes = apic->picture(); QImage img = QImage::fromData(reinterpret_cast<const uchar*>(bytes.data()), bytes.size()); if (!img.isNull()) { m_data[QLatin1String("picture") + QString::number(picnum++)] = QVariant(img); } ++it; } } else { TagLib::FileRef fileref(filename.toLocal8Bit().constData()); if (fileref.isNull()) return; TagLib::Tag* tag = fileref.tag(); if (!tag || tag->isEmpty()) return; readRegularTag(tag, m_data); } }
void M3uLoader::getTags( const QFileInfo& info ) { QByteArray fileName = QFile::encodeName( info.canonicalFilePath() ); const char *encodedName = fileName.constData(); TagLib::FileRef f( encodedName ); TagLib::Tag *tag = f.tag(); QString artist = TStringToQString( tag->artist() ).trimmed(); QString album = TStringToQString( tag->album() ).trimmed(); QString track = TStringToQString( tag->title() ).trimmed(); if ( artist.isEmpty() || track.isEmpty() ) { qDebug() << "Error parsing" << info.fileName(); return; } else { qDebug() << Q_FUNC_INFO << artist << track << album; Tomahawk::query_ptr q = Tomahawk::Query::get( artist, track, album, uuid(), !m_createNewPlaylist ); if ( !q.isNull() ) m_tracks << q; } }
QVector<bool> TagsManager::writeTags(const QVector<SongFile>& songs) { QVector<bool> result; for (SongFile const& song : songs) { bool success = false; if (!song.getAuthors().isEmpty() || !song.getTitle().isEmpty()) { const QString songFilePath = song.getFilepath(); TagLib::FileRef file(songFilePath.toStdString().c_str()); if (!file.isNull() && file.tag()) { TagLib::Tag *tag = file.tag(); tag->setArtist(song.getAuthors().join(";").toStdString()); tag->setTitle(song.getTitle().toStdString()); success = file.save(); } } result.append(success); } return result; }
cFileInfoMenu::cFileInfoMenu(std::string mrl) : cOsdMenu( tr("File Info:"), 12) { //set title //SetTitle(tr("mediaplayer - Id3 Info:")); mrl_ = mrl; fileInfoVec_ = GetFileInfo(mrl_); // Get title std::string title; TagLib::FileRef f( mrl.c_str() ); if(!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); // unicode = false title = tag->title().stripWhiteSpace().toCString(false) ; if (title.size()) { char buffer[128]; snprintf(buffer, 127, "File Info: %s", title.c_str()); SetTitle(buffer); printf("setting title to : %s\n", buffer); } } ShowInfo(); }
QList<QByteArray> MetaDetector::detectEncodings(const MetaPtr meta) { if (meta->localPath.isEmpty()) { return QList<QByteArray>() << "UTF-8"; } QByteArray detectByte; if (!meta->cuePath.isEmpty()) { QFile cueFile(meta->cuePath); if (cueFile.open(QIODevice::ReadOnly)) { detectByte = cueFile.readAll(); return detectEncodings(detectByte); } } #ifdef _WIN32 TagLib::FileRef f(meta->localPath.toStdWString().c_str()); #else TagLib::FileRef f(meta->localPath.toStdString().c_str()); #endif TagLib::Tag *tag = f.tag(); if (tag) { detectByte += tag->title().toCString(); detectByte += tag->artist().toCString(); detectByte += tag->album().toCString(); } return detectEncodings(detectByte); }
JNIEXPORT jstring JNICALL Java_TagLibReader_getTitle (JNIEnv *env, jobject thisObj, jstring path) { const jchar *pathCStr = env->GetStringChars(path, NULL); TagLib::FileRef f(reinterpret_cast<const wchar_t*>(pathCStr)); if(!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); return env->NewStringUTF(tag->title().toCString(true)); } else { return NULL; } }
bool WriteTag(const musik::Core::SongInfo& info) { bool ret = true; try { #if defined (WIN32) TagLib::FileRef tag_file(info.GetFilename().c_str()); #else TagLib::FileRef tag_file(utf16to8(info.GetFilename(), true).c_str()); #endif if (!tag_file.isNull()) { TagLib::Tag *tag = tag_file.tag(); tag->setArtist(info.GetArtist().c_str()); tag->setAlbum(info.GetAlbum().c_str()); tag->setTitle(info.GetTitle().c_str()); tag->setGenre(info.GetGenre().c_str()); tag->setYear(musik::Core::StringToInt(info.GetYear())); tag->setTrack(musik::Core::StringToInt(info.GetTrackNum())); tag->setComment(info.GetNotes().c_str()); tag_file.save(); } } catch (...) { ret = false; cout << "taglib crashed trying to write: " << info.GetFilename().c_str() << endl; } return ret; }
void getMp3Info(const WCHAR* fileName, MP3Info &info) { TagLib::FileRef f(fileName); if (!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); info.tag[0] = tag->title().toWString(); info.tag[1] = tag->artist().toWString(); info.tag[2] = tag->album().toWString(); info.tag[3] = tag->comment().toWString(); info.tag[4] = tag->genre().toWString(); info.year = tag->year(); info.track = tag->track(); TagLib::PropertyMap tags = f.file()->properties(); if (!f.isNull() && f.audioProperties()) { TagLib::AudioProperties *properties = f.audioProperties(); int seconds = properties->length() % 60; int minutes = (properties->length() - seconds) / 60; info.bitrate = properties->bitrate(); info.sample_rate = properties->sampleRate(); info.channels = properties->channels(); info.length_minutes = minutes; info.length_seconds = seconds; } } }
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 ) ); }
int handle_file(const char* filepath, const char* filekey, AudioFileRecordStore& record_store) { bool record_exists = record_store.find_record(filekey) != NULL; // Scanning a file for tags is expensive, so only do it if required. if(record_exists && !record_store.record_update_required(filekey)) { // no update reqquired so has been handled. return 1; } TagLib::FileRef f(filepath); if (!f.isNull() && f.tag()) { AudioFileRecord &record = record_store.get_record(filekey); record.update_start(); if (verbose) { TagLib::Tag *tag = f.tag(); std::cout << filepath << endl; std::cout << filekey << endl; std::cout << "-- TAG (basic) --" << endl; std::cout << "title - \"" << tag->title() << "\"" << endl; std::cout << "artist - \"" << tag->artist() << "\"" << endl; std::cout << "album - \"" << tag->album() << "\"" << endl; std::cout << "year - \"" << tag->year() << "\"" << endl; std::cout << "comment - \"" << tag->comment() << "\"" << endl; std::cout << "track - \"" << tag->track() << "\"" << endl; std::cout << "genre - \"" << tag->genre() << "\"" << endl; } TagLib::PropertyMap tags = f.file()->properties(); for(TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i) { for(TagLib::StringList::ConstIterator j = i->second.begin(); j != i->second.end(); ++j) { record.update(i->first.toCString(true), j->toCString(true)); } } if (f.audioProperties()) { TagLib::AudioProperties *properties = f.audioProperties(); record.update(audio_tags::BITRATE, properties->bitrate()); record.update(audio_tags::LENGTH, properties->length()); record.update(audio_tags::SAMPLERATE, properties->sampleRate()); record.update(audio_tags::CHANNELS, properties->channels()); } record.update_complete(); return 1; } return 0; }
TagLibTokenizer::TagLibTokenizer(const Document *pDocument) : Tokenizer(NULL), m_pTagDocument(NULL) { if (pDocument != NULL) { Url urlObj(pDocument->getLocation()); string pseudoContent; if ((urlObj.isLocal() == true) && (urlObj.getFile().empty() == false)) { string location(urlObj.getLocation()); string trackTitle; location += "/"; location += urlObj.getFile(); TagLib::FileRef fileRef(location.c_str(), false); if (fileRef.isNull() == false) { TagLib::Tag *pTag = fileRef.tag(); if ((pTag != NULL) && (pTag->isEmpty() == false)) { char yearStr[64]; trackTitle = pTag->title().to8Bit(); trackTitle += " "; trackTitle += pTag->artist().to8Bit(); pseudoContent = trackTitle; pseudoContent += " "; pseudoContent += pTag->album().to8Bit(); pseudoContent += " "; pseudoContent += pTag->comment().to8Bit(); pseudoContent += " "; pseudoContent += pTag->genre().to8Bit(); snprintf(yearStr, 64, " %u", pTag->year()); pseudoContent += yearStr; } } else { trackTitle = pseudoContent = pDocument->getTitle(); } m_pTagDocument = new Document(trackTitle, pDocument->getLocation(), pDocument->getType(), pDocument->getLanguage()); m_pTagDocument->setData(pseudoContent.c_str(), pseudoContent.length()); m_pTagDocument->setTimestamp(pDocument->getTimestamp()); m_pTagDocument->setSize(pDocument->getSize()); // Give the result to the parent class setDocument(m_pTagDocument); } } }
bool ReadTag(const musik::Core::String& fn, musik::Core::SongInfo& target) { bool ret = true; musik::Core::Filename mfn(fn); target.SetFilename(fn); target.SetFormat("Ogg Vorbis"); try { #if defined (WIN32) TagLib::FileRef tag_file(fn.c_str()); #else TagLib::FileRef tag_file(utf16to8(fn, true).c_str()); #endif if (!tag_file.isNull()) { if (tag_file.tag()) { TagLib::Tag *tag = tag_file.tag(); target.SetArtist(musik::Core::utf8to16(tag->artist().to8Bit(true))); target.SetAlbum(musik::Core::utf8to16(tag->album().to8Bit(true))); target.SetTitle(musik::Core::utf8to16(tag->title().to8Bit(true))); target.SetGenre(musik::Core::utf8to16(tag->genre().to8Bit(true))); target.SetNotes(musik::Core::utf8to16(tag->comment().to8Bit(true))); target.SetYear(musik::Core::IntToString(tag->year())); target.SetTrackNum(musik::Core::IntToString(tag->track())); } if (tag_file.audioProperties()) { TagLib::AudioProperties *properties = tag_file.audioProperties(); int duration = properties->length() * 1000; target.SetBitrate(musik::Core::IntToString(properties->bitrate())); target.SetDuration(musik::Core::IntToString(duration)); } } // if the title is empty, then use the // filename... if (target.GetTitle().IsEmpty()) { musik::Core::Filename MFN(fn); target.SetTitle(MFN.GetJustFilename()); } } catch (...) { ret = false; cout << "taglib crashed reading: " << fn.c_str() << endl; } return ret; }
void MediaController::metaDataChanged() { QString extra_data; QByteArray encoded = QFile::encodeName(current_file.path()); TagLib::FileRef ref(encoded.data(), true, TagLib::AudioProperties::Fast); if (ref.isNull()) { info_label->setText(i18n("Playing: <b>%1</b>", current_file.name())); return; } TagLib::Tag* tag = ref.tag(); if (!tag) { info_label->setText(i18n("Playing: <b>%1</b>", current_file.name())); return; } QString artist = t2q(tag->artist()); QString title = t2q(tag->title()); QString album = t2q(tag->album()); bool has_artist = !artist.isEmpty(); bool has_title = !title.isEmpty(); bool has_album = !album.isEmpty(); if (has_artist && has_title && has_album) { extra_data = i18n("<b>%2</b> - <b>%1</b> (Album: <b>%3</b>)", title, artist, album); info_label->setText(extra_data); } else if (has_title && has_artist) { extra_data = i18n("<b>%2</b> - <b>%1</b>", title, artist); info_label->setText(extra_data); } else if (has_title) { extra_data = i18n("<b>%1</b>", title); info_label->setText(extra_data); } else { info_label->setText(i18n("<b>%1</b>", current_file.name())); } }
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 (basic) --" << endl; cout << "title - \"" << tag->title() << "\"" << endl; cout << "artist - \"" << tag->artist() << "\"" << 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; TagLib::PropertyMap tags = f.file()->properties(); unsigned int longest = 0; for(TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i) { if (i->first.size() > longest) { longest = i->first.size(); } } cout << "-- TAG (properties) --" << endl; for(TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i) { for(TagLib::StringList::ConstIterator j = i->second.begin(); j != i->second.end(); ++j) { cout << left << std::setw(longest) << i->first << " - " << '"' << *j << '"' << 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 << ":" << setfill('0') << setw(2) << seconds << endl; } } return 0; }
int main(int argc, char *argv[]) { for(int i = 1; i < argc; i++) { cout << "path:" << argv[i] << endl; TagLib::FileRef f(argv[i]); if(!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); cout << "title:" << (tag->title()).toCString(true) << endl; cout << "artist:" << (tag->artist()).toCString(true) << endl; cout << "album:" << (tag->album()).toCString(true) << endl; cout << "albumartist:" << (tag->albumArtist()).toCString(true) << endl; cout << "track:" << tag->track() << endl; cout << "disc:" << tag->cdNr() << endl; } if(!f.isNull() && f.audioProperties()) { TagLib::AudioProperties *properties = f.audioProperties(); cout << "bitrate:" << properties->bitrate() << endl; cout << "length:" << properties->length() << endl; } if(i!=argc-1) cout << "---" << endl; } return 0; }
string scan_file(const char* path) { TagLib::FileRef f(path); if (!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); int filesize = boost::filesystem::file_size(path); int bitrate = 0; int duration = 0; if (f.audioProperties()) { TagLib::AudioProperties *properties = f.audioProperties(); duration = properties->length(); bitrate = properties->bitrate(); } string artist = tag->artist().toCString(true); string album = tag->album().toCString(true); string track = tag->title().toCString(true); boost::trim(artist); boost::trim(album); boost::trim(track); if (artist.length()==0 || track.length()==0) { return "{\"error\" : \"no tags\"}\n"; } string ext(toUtf8(boost::filesystem::extension(path))); string mimetype = ext2mime(boost::to_lower_copy(ext)); // turn it into a url by prepending file:// // because we pass all urls to curl: string urlpath = urlify( toUtf8(path) ); ostringstream os; os << "{ \"url\" : \"" << urlpath << "\"," " \"filesize\" : " << filesize << "," " \"mimetype\" : \"" << mimetype << "\"," " \"artist\" : \"" << tidy(artist) << "\"," " \"album\" : \"" << tidy(album) << "\"," " \"track\" : \"" << tidy(track) << "\"," " \"duration\" : " << duration << "," " \"bitrate\" : " << bitrate << "," " \"trackno\" : " << tag->track() << "}\n"; return os.str(); } return "{\"error\" : \"no tags\"}\n"; }
string scan_file(const char* path) { TagLib::FileRef f(path); if (!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); int bitrate = 0; int duration = 0; if (f.audioProperties()) { TagLib::AudioProperties *properties = f.audioProperties(); duration = properties->length(); bitrate = properties->bitrate(); } string artist = tag->artist().toCString(true); string album = tag->album().toCString(true); string track = tag->title().toCString(true); trim(artist); trim(album); trim(track); if (artist.length()==0 || track.length()==0) { return "{\"error\" : \"no tags\"}"; } string pathstr(path); string ext = pathstr.substr(pathstr.length()-4); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); string mimetype = ext2mime(ext); // turn it into a url by prepending file:// // because we pass all urls to curl: string urlpath = urlify( path ); ostringstream os; os << "{ \"url\" : \"" << esc(urlpath) << "\"," " \"mimetype\" : \"" << mimetype << "\"," " \"artist\" : \"" << tidy(artist) << "\"," " \"album\" : \"" << tidy(album) << "\"," " \"track\" : \"" << tidy(track) << "\"," " \"duration\" : " << duration << "," " \"bitrate\" : " << bitrate << "," " \"trackno\" : " << tag->track() << "}"; return os.str(); } return "{\"error\" : \"no tags\"}"; }
int main(int argc, char *argv[]) { if (argc < 3) return 1; string what(argv[1]); TagLib::FileRef f(argv[2]); if(!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); if (what == "title") cout << tag->title() << endl; if (what == "artist") cout << tag->artist() << endl; if (what == "album") cout << tag->album() << endl; if (what == "year") cout << tag->year() << endl; } return 0; }
Tune* tuneFromFile(const QString& file) { Tune* tune = new Tune(false); tune->file = file; TagLib::FileRef ref = fileName2TaglibRef(file); if(!ref.isNull()) { if(ref.tag()) { TagLib::Tag* tag = ref.tag(); tune->artist = safeTagLibString2QString( tag->artist() ); tune->album = safeTagLibString2QString( tag->album() ); tune->title = safeTagLibString2QString( tag->title() ); tune->trackNumber = QString::number( tag->track() ); tune->genre = safeTagLibString2QString( tag->genre() ); } Qomp::loadCover(tune, ref.file()); if(ref.audioProperties()) { TagLib::AudioProperties *prop = ref.audioProperties(); tune->duration = Qomp::durationSecondsToString( prop->length() ); tune->bitRate = QString::number( prop->bitrate() ); } tune->setMetadataResolved(true); } return tune; }
bool parseAndWrite(const char* location, Json::Writer& writer) { Json::Value metadata; metadata[LOCATION] = location; TagLib::FileRef f(location); if (f.isNull()){ return false; } if (f.tag() && !f.tag()->isEmpty()){ TagLib::Tag* tag = f.tag(); TagLib::String artist = tag->artist(); TagLib::String album = tag->artist(); TagLib::String title = tag->title(); uint track = tag->track(); uint year = tag->year(); metadata[TITLE] = title.toCString(true); metadata[ARTIST] = artist.toCString(true); metadata[ALBUM] = album.toCString(true); metadata[TRACK] = track; metadata[YEAR] = year; } std::cout << writer.write(metadata); return true; }
AlbumTrack::AlbumTrack(Album* album, QString trackPath) { this->path = trackPath; this->number = 0; this->artist = "Unknown Artist"; this->album = album; this->genre = "Unknown Genre"; TagLib::FileRef f(trackPath.toStdString().c_str()); if(!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); title = QString(tag->title().toCString()); number = tag->track(); artist = QString(tag->artist().toCString()); albumName = QString(tag->album().toCString()); genre = QString(tag->genre().toCString()); } if(!f.isNull() && f.audioProperties()) { TagLib::AudioProperties *properties = f.audioProperties(); duration = properties->length() * 1000; //Weil Fmod die gerne in Millisekunden hätte } }
JNIEXPORT jobjectArray JNICALL Java_TagLibReader_getTags (JNIEnv *env, jobject thisObj, jstring path) { const jchar *pathCStr = env->GetStringChars(path, NULL); TagLib::FileRef f(reinterpret_cast<const wchar_t*>(pathCStr)); jstring jartist; jstring jalbum; jstring jtitle; if(!f.isNull() && f.tag()) { TagLib::Tag *tag = f.tag(); jartist = env->NewStringUTF(tag->artist().toCString(true)); jalbum = env->NewStringUTF(tag->album().toCString(true)); jtitle = env->NewStringUTF(tag->title().toCString(true)); } else { return NULL; } jclass classString = env->FindClass("java/lang/String"); jobjectArray outJNIArray = env->NewObjectArray(3, classString, NULL); env->SetObjectArrayElement(outJNIArray, 0, jartist); env->SetObjectArrayElement(outJNIArray, 1, jalbum); env->SetObjectArrayElement(outJNIArray, 2, jtitle); return outJNIArray; }
// Use Taglib to parse tags from file and add entried to wxListCtrl void AddFromFile_Taglib(wxListCtrl *listctrl, const std::map< wxString, long > &mapping, const wxString &filename) { TagLib::FileRef f = TagLib::FileRef(filename.c_str(), TagLib::String::UTF8 ); //TODO: is c_str() safe? if ( f.isNull() ) { wxLogError(wxT("Error: TagLib could not read ") + filename + wxT(".")); return; } if ( ! f.tag() ) { wxLogError(wxT("Error: TagLib could not read the tags of file ") + filename + wxT(".")); return; } TagLib::Tag *tag = f.tag(); auto idx = listctrl->GetItemCount(); auto row_idx = listctrl->InsertItem(idx, wxString::Format(wxT("%d"), idx) ); // TODO: check return values listctrl->SetItem(row_idx, mapping.find("Artist")->second, wxString(tag->artist().to8Bit(true)) ); listctrl->SetItem(row_idx, mapping.find("Trackname")->second, wxString(tag->title().to8Bit(true))); listctrl->SetItem(row_idx, mapping.find("Album")->second, wxString(tag->album().to8Bit(true))); if ( f.audioProperties() ) { TagLib::AudioProperties *properties = f.audioProperties(); int seconds = properties->length() % 60; int minutes = (properties->length() - seconds) / 60; wxString timestr = wxString::Format("%d:%02d", minutes, seconds); listctrl->SetItem(row_idx, mapping.find("Time")->second, timestr); } }
void DataStore::addSongToLibrary(const Phonon::MediaSource& song, QSqlQuery &addQuery){ QString fileName = song.fileName(); QString songName; QString artistName; QString albumName; QString genre; int track; int duration; TagLib::FileRef f(fileName.toStdString().c_str()); if(!f.isNull() && f.tag() && f.audioProperties()){ TagLib::Tag *tag = f.tag(); songName = TStringToQString(tag->title()); artistName = TStringToQString(tag->artist()); albumName = TStringToQString(tag->album()); genre = TStringToQString(tag->genre()); duration = f.audioProperties()->length(); track = tag->track(); } else{ //TODO throw error return; } if(songName == ""){ songName = unknownSongTitle(); } if(artistName == ""){ artistName = unknownSongArtist(); } if(albumName == ""){ albumName = unknownSongAlbum(); } if(genre == ""){ genre = unknownGenre(); } Logger::instance()->log("adding song with title: " + songName + " to database"); library_song_id_t hostId =-1; addQuery.bindValue(":song", songName); addQuery.bindValue(":artist", artistName); addQuery.bindValue(":album", albumName); addQuery.bindValue(":genre", genre); addQuery.bindValue(":track", track); addQuery.bindValue(":file", fileName); addQuery.bindValue(":duration", duration); EXEC_INSERT( "Failed to add song library" << songName.toStdString(), addQuery, hostId, library_song_id_t) }
void FileStore::scan(const string & a_path) { if (!fs::exists(a_path)) return; if (fs::is_directory(a_path)) { fs::directory_iterator end; // default construction yields past-the-end for (fs::directory_iterator curr(a_path); curr != end; ++curr) { fs::path p = curr->path(); string s = p.string(); scan(s); } } else if (fs::is_regular_file(a_path)) { if (pathExists(a_path)) return; TagLib::FileRef file_ref(a_path.c_str(), false); if (!file_ref.isNull() && file_ref.tag()) { cerr << "indexing " << a_path << endl; TagLib::Tag *t = file_ref.tag(); string artist = t->artist().to8Bit(true); string album = t->album().to8Bit(true); string title = t->title().to8Bit(true); string genre = t->genre().to8Bit(true); string year = t->year() > 0 ? lexical_cast<string>(t->year()) : ""; string track = t->track() > 0 ? lexical_cast<string>(t->track()) : ""; string uri = "file://" + a_path; shared_ptr<UUID> fileID(generateID()); addField(*fileID, ARTIST, artist); addField(*fileID, ARTIST, artist); addField(*fileID, ALBUM, album); addField(*fileID, YEAR, year); addField(*fileID, TITLE, title); addField(*fileID, GENRE, genre); addField(*fileID, TRACK, track); addField(*fileID, URI, uri); } } }
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 - \"" << tag->album() << "\"" << endl; cout << "year - \"" << tag->year() << "\"" << endl; cout << "comment - \"" << tag->comment() << "\"" << endl; cout << "track - \"" << tag->track() << "\"" << endl; cout << "genre - \"" << tag->genre() << "\"" << 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; }
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; }
void Media::updateTags(Format format){ if(format == MP3){ TagLib::MPEG::File mp3(filePath(MP3).c_str()); TagLib::Tag *t = mp3.tag(); if(!t) return; t->setTitle(TagLib::String(title(), TagLib::String::UTF8)); t->setArtist(TagLib::String(artist().name(), TagLib::String::UTF8)); mp3.save(TagLib::MPEG::File::ID3v1 | TagLib::MPEG::File::ID3v2); } else if(format == Vorbis) { TagLib::Ogg::Vorbis::File vorbis(filePath(Vorbis).c_str()); TagLib::Tag *t = vorbis.tag(); if(!t) return; t->setTitle(TagLib::String(title(), TagLib::String::UTF8)); t->setArtist(TagLib::String(artist().name(), TagLib::String::UTF8)); vorbis.save(); } }
bool mediaTag(Artwork *art, TagLib::File *f) { Q_ASSERT(f != NULL); Q_ASSERT(f->tag()); TagLib::Tag *tag = f->tag(); art->filetype = FILETYPE_UNKNOWN; // The basic stuff!!! art->artist = TStringToQString(tag->artist()).trimmed(); art->album = TStringToQString(tag->album()).trimmed(); art->track = TStringToQString(tag->title()).trimmed(); art->genre = TStringToQString(tag->genre()).trimmed(); art->year = tag->year(); art->trackNo = tag->track(); // we need something to search on! if (art->artist == "" && art->album == "" && art->track == "") { return false; } // Any audio properties??? if (f->audioProperties()) { TagLib::AudioProperties *properties = f->audioProperties(); int seconds = properties->length() % 60; int minutes = (properties->length() - seconds) / 60; art->duration = minutes * 60 + seconds; art->bitRate = properties->bitrate(); art->sampleRate = properties->sampleRate(); art->channels = properties->channels(); } art->makeSearchable(); return true; }
void TagReader::ReadFile(const QString& filename, pb::tagreader::SongMetadata* song) const { const QByteArray url(QUrl::fromLocalFile(filename).toEncoded()); const QFileInfo info(filename); qLog(Debug) << "Reading tags from" << filename; song->set_basefilename(DataCommaSizeFromQString(info.fileName())); song->set_url(url.constData(), url.size()); song->set_filesize(info.size()); song->set_mtime(info.lastModified().toTime_t()); song->set_ctime(info.created().toTime_t()); std::unique_ptr<TagLib::FileRef> fileref(factory_->GetFileRef(filename)); if (fileref->isNull()) { qLog(Info) << "TagLib hasn't been able to read " << filename << " file"; return; } TagLib::Tag* tag = fileref->tag(); if (tag) { Decode(tag->title(), nullptr, song->mutable_title()); Decode(tag->artist(), nullptr, song->mutable_artist()); // TPE1 Decode(tag->album(), nullptr, song->mutable_album()); Decode(tag->genre(), nullptr, song->mutable_genre()); song->set_year(tag->year()); song->set_track(tag->track()); song->set_valid(true); } QString disc; QString compilation; // Handle all the files which have VorbisComments (Ogg, OPUS, ...) in the same // way; // apart, so we keep specific behavior for some formats by adding another // "else if" block below. if (TagLib::Ogg::XiphComment* tag = dynamic_cast<TagLib::Ogg::XiphComment*>(fileref->file()->tag())) { ParseOggTag(tag->fieldListMap(), nullptr, &disc, &compilation, song); } if (TagLib::MPEG::File* file = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) { if (file->ID3v2Tag()) { const TagLib::ID3v2::FrameListMap& map = file->ID3v2Tag()->frameListMap(); if (!map["TPOS"].isEmpty()) disc = TStringToQString(map["TPOS"].front()->toString()).trimmed(); if (!map["TBPM"].isEmpty()) song->set_bpm(TStringToQString(map["TBPM"].front()->toString()) .trimmed() .toFloat()); if (!map["TCOM"].isEmpty()) Decode(map["TCOM"].front()->toString(), nullptr, song->mutable_composer()); if (!map["TIT1"].isEmpty()) // content group Decode(map["TIT1"].front()->toString(), nullptr, song->mutable_grouping()); // Skip TPE1 (which is the artist) here because we already fetched it if (!map["TPE2"].isEmpty()) // non-standard: Apple, Microsoft Decode(map["TPE2"].front()->toString(), nullptr, song->mutable_albumartist()); if (!map["TCMP"].isEmpty()) compilation = TStringToQString(map["TCMP"].front()->toString()).trimmed(); if (!map["APIC"].isEmpty()) song->set_art_automatic(kEmbeddedCover); // Find a suitable comment tag. For now we ignore iTunNORM comments. for (int i = 0; i < map["COMM"].size(); ++i) { const TagLib::ID3v2::CommentsFrame* frame = dynamic_cast<const TagLib::ID3v2::CommentsFrame*>(map["COMM"][i]); if (frame && TStringToQString(frame->description()) != "iTunNORM") { Decode(frame->text(), nullptr, song->mutable_comment()); break; } } // Parse FMPS frames for (int i = 0; i < map["TXXX"].size(); ++i) { const TagLib::ID3v2::UserTextIdentificationFrame* frame = dynamic_cast<const TagLib::ID3v2::UserTextIdentificationFrame*>( map["TXXX"][i]); if (frame && frame->description().startsWith("FMPS_")) { ParseFMPSFrame(TStringToQString(frame->description()), TStringToQString(frame->fieldList()[1]), song); } } // Check POPM tags // We do this after checking FMPS frames, so FMPS have precedence, as we // will consider POPM tags iff song has no rating/playcount already set. if (!map["POPM"].isEmpty()) { const TagLib::ID3v2::PopularimeterFrame* frame = dynamic_cast<const TagLib::ID3v2::PopularimeterFrame*>( map["POPM"].front()); if (frame) { // Take a user rating only if there's no rating already set if (song->rating() <= 0 && frame->rating() > 0) { song->set_rating(ConvertPOPMRating(frame->rating())); } if (song->playcount() <= 0 && frame->counter() > 0) { song->set_playcount(frame->counter()); } } } } } else if (TagLib::FLAC::File* file = dynamic_cast<TagLib::FLAC::File*>(fileref->file())) { if (file->xiphComment()) { ParseOggTag(file->xiphComment()->fieldListMap(), nullptr, &disc, &compilation, song); #ifdef TAGLIB_HAS_FLAC_PICTURELIST if (!file->pictureList().isEmpty()) { song->set_art_automatic(kEmbeddedCover); } #endif } Decode(tag->comment(), nullptr, song->mutable_comment()); } else if (TagLib::MP4::File* file = dynamic_cast<TagLib::MP4::File*>(fileref->file())) { if (file->tag()) { TagLib::MP4::Tag* mp4_tag = file->tag(); const TagLib::MP4::ItemListMap& items = mp4_tag->itemListMap(); // Find album artists TagLib::MP4::ItemListMap::ConstIterator it = items.find("aART"); if (it != items.end()) { TagLib::StringList album_artists = it->second.toStringList(); if (!album_artists.isEmpty()) { Decode(album_artists.front(), nullptr, song->mutable_albumartist()); } } // Find album cover art if (items.find("covr") != items.end()) { song->set_art_automatic(kEmbeddedCover); } if (items.contains("disk")) { disc = TStringToQString( TagLib::String::number(items["disk"].toIntPair().first)); } if (items.contains(kMP4_FMPS_Rating_ID)) { float rating = TStringToQString(items[kMP4_FMPS_Rating_ID].toStringList().toString( '\n')).toFloat(); if (song->rating() <= 0 && rating > 0) { song->set_rating(rating); } } if (items.contains(kMP4_FMPS_Playcount_ID)) { int playcount = TStringToQString( items[kMP4_FMPS_Playcount_ID].toStringList().toString('\n')) .toFloat(); if (song->playcount() <= 0 && playcount > 0) { song->set_playcount(playcount); } } if (items.contains(kMP4_FMPS_Playcount_ID)) { int score = TStringToQString( items[kMP4_FMPS_Score_ID].toStringList().toString('\n')) .toFloat() * 100; if (song->score() <= 0 && score > 0) { song->set_score(score); } } if (items.contains("\251wrt")) { Decode(items["\251wrt"].toStringList().toString(", "), nullptr, song->mutable_composer()); } if (items.contains("\251grp")) { Decode(items["\251grp"].toStringList().toString(" "), nullptr, song->mutable_grouping()); } Decode(mp4_tag->comment(), nullptr, song->mutable_comment()); } } #ifdef TAGLIB_WITH_ASF else if (TagLib::ASF::File* file = dynamic_cast<TagLib::ASF::File*>(fileref->file())) { const TagLib::ASF::AttributeListMap& attributes_map = file->tag()->attributeListMap(); if (attributes_map.contains("FMPS/Rating")) { const TagLib::ASF::AttributeList& attributes = attributes_map["FMPS/Rating"]; if (!attributes.isEmpty()) { float rating = TStringToQString(attributes.front().toString()).toFloat(); if (song->rating() <= 0 && rating > 0) { song->set_rating(rating); } } } if (attributes_map.contains("FMPS/Playcount")) { const TagLib::ASF::AttributeList& attributes = attributes_map["FMPS/Playcount"]; if (!attributes.isEmpty()) { int playcount = TStringToQString(attributes.front().toString()).toInt(); if (song->playcount() <= 0 && playcount > 0) { song->set_playcount(playcount); } } } if (attributes_map.contains("FMPS/Rating_Amarok_Score")) { const TagLib::ASF::AttributeList& attributes = attributes_map["FMPS/Rating_Amarok_Score"]; if (!attributes.isEmpty()) { int score = TStringToQString(attributes.front().toString()).toFloat() * 100; if (song->score() <= 0 && score > 0) { song->set_score(score); } } } } #endif else if (tag) { Decode(tag->comment(), nullptr, song->mutable_comment()); } if (!disc.isEmpty()) { const int i = disc.indexOf('/'); if (i != -1) { // disc.right( i ).toInt() is total number of discs, we don't use this at // the moment song->set_disc(disc.left(i).toInt()); } else { song->set_disc(disc.toInt()); } } if (compilation.isEmpty()) { // well, it wasn't set, but if the artist is VA assume it's a compilation if (QStringFromStdString(song->artist()).toLower() == "various artists") { song->set_compilation(true); } } else { song->set_compilation(compilation.toInt() == 1); } if (fileref->audioProperties()) { song->set_bitrate(fileref->audioProperties()->bitrate()); song->set_samplerate(fileref->audioProperties()->sampleRate()); song->set_length_nanosec(fileref->audioProperties()->length() * kNsecPerSec); } // Get the filetype if we can song->set_type(GuessFileType(fileref.get())); // Set integer fields to -1 if they're not valid #define SetDefault(field) \ if (song->field() <= 0) { \ song->set_##field(-1); \ } SetDefault(track); SetDefault(disc); SetDefault(bpm); SetDefault(year); SetDefault(bitrate); SetDefault(samplerate); SetDefault(lastplayed); #undef SetDefault }