Cover* FileHelper::extractCover() { Cover *cover = nullptr; switch (_fileType) { case EXT_MP3: { TagLib::MPEG::File *mpegFile = static_cast<TagLib::MPEG::File*>(_file); if (mpegFile && mpegFile->hasID3v2Tag()) { // Look for picture frames only TagLib::ID3v2::FrameList listOfMp3Frames = mpegFile->ID3v2Tag()->frameListMap()["APIC"]; // It's possible to have more than one picture per file! if (!listOfMp3Frames.isEmpty()) { for (TagLib::ID3v2::FrameList::ConstIterator it = listOfMp3Frames.begin(); it != listOfMp3Frames.end() ; it++) { // Cast a Frame* to AttachedPictureFrame* TagLib::ID3v2::AttachedPictureFrame *pictureFrame = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it); if (pictureFrame) { // Performs a deep copy of the cover QByteArray b = QByteArray(pictureFrame->picture().data(), pictureFrame->picture().size()); cover = new Cover(b, QString(pictureFrame->mimeType().toCString(true))); } } } } else if (mpegFile && mpegFile->hasID3v1Tag()) { qDebug() << Q_FUNC_INFO << "Not implemented for ID3v1Tag"; } break; } case EXT_FLAC: { if (TagLib::FLAC::File *flacFile = static_cast<TagLib::FLAC::File*>(_file)) { auto list = flacFile->pictureList(); for (auto it = list.begin(); it != list.end() ; it++) { TagLib::FLAC::Picture *p = *it; if (p->type() == TagLib::FLAC::Picture::FrontCover) { // Performs a deep copy of the cover QByteArray b = QByteArray(p->data().data(), p->data().size()); cover = new Cover(b, QString(p->mimeType().toCString(true))); break; } } } break; } default: qDebug() << Q_FUNC_INFO << "Not implemented for this file type" << _fileType << _file << _fileInfo.absoluteFilePath(); break; } return cover; }
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(); } }