bool KFlacPlugin::readInfo( KFileMetaInfo& info, uint what ) { if ( info.path().isEmpty() ) // remote file return false; bool readComment = false; bool readTech = false; if (what & (KFileMetaInfo::Fastest | KFileMetaInfo::DontCare | KFileMetaInfo::ContentInfo)) readComment = true; if (what & (KFileMetaInfo::Fastest | KFileMetaInfo::DontCare | KFileMetaInfo::TechnicalInfo)) readTech = true; TagLib::File *file = 0; if (info.mimeType() == "audio/x-flac") file = new TagLib::FLAC::File(QFile::encodeName(info.path()).data(), readTech); #ifdef TAGLIB_1_2 else file = new TagLib::Ogg::FLAC::File(QFile::encodeName(info.path()).data(), readTech); #endif if (!file || !file->isValid()) { kdDebug(7034) << "Couldn't open " << file->name() << endl; delete file; return false; } if(readComment && file->tag()) { KFileMetaInfoGroup commentgroup = appendGroup(info, "Comment"); QString date = file->tag()->year() > 0 ? QString::number(file->tag()->year()) : QString::null; QString track = file->tag()->track() > 0 ? QString::number(file->tag()->track()) : QString::null; appendItem(commentgroup, "Title", TStringToQString(file->tag()->title()).stripWhiteSpace()); appendItem(commentgroup, "Artist", TStringToQString(file->tag()->artist()).stripWhiteSpace()); appendItem(commentgroup, "Album", TStringToQString(file->tag()->album()).stripWhiteSpace()); appendItem(commentgroup, "Date", date); appendItem(commentgroup, "Comment", TStringToQString(file->tag()->comment()).stripWhiteSpace()); appendItem(commentgroup, "Tracknumber", track); appendItem(commentgroup, "Genre", TStringToQString(file->tag()->genre()).stripWhiteSpace()); } if (readTech && file->audioProperties()) { KFileMetaInfoGroup techgroup = appendGroup(info, "Technical"); TagLib::FLAC::Properties *properties = (TagLib::FLAC::Properties*)(file->audioProperties()); appendItem(techgroup, "Bitrate", properties->bitrate()); appendItem(techgroup, "Sample Rate", properties->sampleRate()); appendItem(techgroup, "Sample Width", properties->sampleWidth()); appendItem(techgroup, "Channels", properties->channels()); appendItem(techgroup, "Length", properties->length()); } delete file; return true; }
void import_flac_file(const std::string& filename) { //std::cerr << "import_flac_file " << filename << std::endl; TagLib::FLAC::File file(filename.c_str()); auto tag = file.tag(); auto artist_name = tag->artist().to8Bit(true); auto album_title = tag->album().to8Bit(true); auto track_title = tag->title().to8Bit(true); auto artist = dm::artist::find_by_name(artist_name); if ( artist.is_null() ) { // Create artist. artist.name(artist_name); artist.save(); } auto album = artist.find_album_by_title(album_title); if ( album.is_null() ) { // Create album. album.title(album_title); album.member("artist", json::object{ { "id", artist.id() }, { "name", artist.name() } }); album.save(); // Add album to artist albums. artist.add_album(album); artist.save(); } auto track = album.find_track_by_title_and_number(track_title, tag->track()); // Set/update track attributes. track.title(track_title); track.track_number(tag->track()); track.disc_number(1); // Create track source object. json::object source{ { "name", "local" }, { "uri", filename } }; TagLib::FLAC::Properties* properties = file.audioProperties(); if ( properties ) { track.duration(properties->length()); } TagLib::Ogg::XiphComment* xiph_comment = file.xiphComment(); if ( xiph_comment ) { auto field_map = xiph_comment->fieldListMap(); json::object replaygain; for ( auto& field : field_map ) { if ( field.first == "TRACK NUMBER" || field.first == "TRACKNUMBER" ) { if ( field.second.size() > 0 ) { track.track_number(std::stoi(field.second[0].to8Bit())); } else { std::cerr << "field='" << field.first << "' string list size=" << field.second.size() << std::endl; } } else if ( field.first == "DISC NUMBER" || field.first == "DISCNUMBER" ) { if ( field.second.size() > 0 ) { track.disc_number(std::stoi(field.second[0].to8Bit())); } else { std::cerr << "field='" << field.first << "' string list size=" << field.second.size() << std::endl; } } else if ( field.first == "REPLAYGAIN_REFERENCE_LOUDNESS" ) { auto ref_loudness = std::stod(field.second[0].to8Bit()); replaygain["reference_loudness"] = ref_loudness; } else if ( field.first == "REPLAYGAIN_TRACK_GAIN" ) { auto gain = std::stod(field.second[0].to8Bit()); replaygain["track_gain"] = gain; } } if ( !replaygain.empty() ) { source["replaygain"] = replaygain; } } const TagLib::List<TagLib::FLAC::Picture*>& images = file.pictureList(); if ( images.size() > 0 ) { TagLib::FLAC::Picture* image = images[0]; if ( image->mimeType() == "image/jpeg" ) { auto cover = dm::album_cover::find_by_album_id(album.id()); if ( cover.is_null() ) { cover.format("jpg"); cover.data(reinterpret_cast<const char*>(image->data().data()), image->data().size()); cover.save(); } } else { std::cerr << "unhandled image mime type - " << filename << " images=" << images.size() << ", mime type " << image->mimeType() << std::endl; } } track.artist(artist); track.album(album); track.source(std::move(source)); if ( track.id_is_null() ) { // Create track id. track.save(); // Add new track to album. album.add_track(track); album.save(); } else { track.save(); } }