diff --git a/src/libs/av/impl/AvInfo.cpp b/src/libs/av/impl/AvInfo.cpp index b8fc392a..ff4d010d 100644 --- a/src/libs/av/impl/AvInfo.cpp +++ b/src/libs/av/impl/AvInfo.cpp @@ -215,7 +215,7 @@ MediaFile::getAttachedPictures(std::size_t nbMaxPictures) const LMS_LOG(AV, ERROR) << "CODEC ID " << avstream->codecpar->codec_id << " not handled in mime type conversion"; } - AVPacket pkt = avstream->attached_pic; + const AVPacket& pkt {avstream->attached_pic}; std::copy(pkt.data, pkt.data + pkt.size, std::back_inserter(picture.data)); diff --git a/src/libs/cover/impl/CoverArtGrabber.cpp b/src/libs/cover/impl/CoverArtGrabber.cpp index efd1c73c..64387d5a 100644 --- a/src/libs/cover/impl/CoverArtGrabber.cpp +++ b/src/libs/cover/impl/CoverArtGrabber.cpp @@ -78,30 +78,59 @@ getFromAvMediaFile(const Av::MediaFile& input) } std::optional -Grabber::getFromDirectory(const std::filesystem::path& p) const +Grabber::getFromDirectory(const std::filesystem::path& p, std::string_view preferredFileName) const { - for (auto coverPath : getCoverPaths(p)) - { - Image image; + const std::multimap coverPaths {getCoverPaths(p)}; - if (image.load(coverPath)) + auto tryLoadImage = [](const std::filesystem::path& p, Image& image) + { + if (!image.load(p)) + { + LMS_LOG(COVER, ERROR) << "Cannot load image in file '" << p.string() << "'"; + return false; + } + + return true; + }; + + auto tryLoadImageFromFilename = [&](std::string_view fileName, Image& image) + { + auto range {coverPaths.equal_range(std::string {fileName})}; + for (auto it {range.first}; it != range.second; ++it) + { + if (tryLoadImage(it->second, image)) + return true; + } + return false; + }; + + Image image; + + if (!preferredFileName.empty() && tryLoadImageFromFilename(preferredFileName, image)) + return image; + + for (std::string_view filename : _preferredFileNames) + { + if (tryLoadImageFromFilename(filename, image)) + return image; + } + + // Just pick one + for (const auto& [filename, coverPath] : coverPaths) + { + if (tryLoadImage(coverPath, image)) return image; - else - LMS_LOG(COVER, ERROR) << "Cannot load image in file '" << coverPath.string() << "'"; } - LMS_LOG(COVER, DEBUG) << "No cover found in directory '" << p.string() << "'"; return std::nullopt; } -std::vector +std::multimap Grabber::getCoverPaths(const std::filesystem::path& directoryPath) const { - std::vector res; + std::multimap res; std::error_code ec; - // TODO handle preferred file names - std::filesystem::directory_iterator itPath(directoryPath, ec); std::filesystem::directory_iterator itEnd; while (!ec && itPath != itEnd) @@ -121,7 +150,7 @@ Grabber::getCoverPaths(const std::filesystem::path& directoryPath) const continue; } - res.push_back(path); + res.emplace(std::filesystem::path{path}.filename().replace_extension("").string(), path); } return res; @@ -177,12 +206,12 @@ Grabber::getFromTrack(Database::Session& dbSession, Database::IdType trackId, st cover = getFromTrack(trackPath); if (!cover) - cover = getFromDirectory(trackPath.parent_path()); + cover = getFromDirectory(trackPath.parent_path(), trackPath.filename().replace_extension("").string()); if (!cover && isMultiDisc) { if (trackPath.parent_path().has_parent_path()) - cover = getFromDirectory(trackPath.parent_path().parent_path()); + cover = getFromDirectory(trackPath.parent_path().parent_path(), {}); } if (!cover) diff --git a/src/libs/cover/impl/CoverArtGrabber.hpp b/src/libs/cover/impl/CoverArtGrabber.hpp index a153b8b4..25eac8cc 100644 --- a/src/libs/cover/impl/CoverArtGrabber.hpp +++ b/src/libs/cover/impl/CoverArtGrabber.hpp @@ -20,10 +20,12 @@ #pragma once #include -#include +#include #include -#include +#include +#include #include +#include #include "cover/ICoverArtGrabber.hpp" #include "database/Types.hpp" @@ -101,8 +103,8 @@ namespace CoverArt Image getFromRelease(Database::Session& dbSession, Database::IdType releaseId, std::size_t size); std::optional getFromTrack(const std::filesystem::path& path) const; - std::vector getCoverPaths(const std::filesystem::path& directoryPath) const; - std::optional getFromDirectory(const std::filesystem::path& path) const; + std::multimap getCoverPaths(const std::filesystem::path& directoryPath) const; + std::optional getFromDirectory(const std::filesystem::path& path, std::string_view preferredFileName) const; std::unique_ptr _defaultCover; // unique_ptr to defer initializing @@ -117,7 +119,7 @@ namespace CoverArt static inline constexpr std::size_t _maxCacheEntries {1000}; static inline const std::vector _fileExtensions {".jpg", ".jpeg", ".png", ".bmp"}; // TODO parametrize static inline constexpr std::size_t _maxFileSize {10000000}; - static inline const std::vector _preferredFileNames {"cover", "front"}; // TODO parametrize + static inline const std::vector _preferredFileNames {"cover", "front"}; // TODO parametrize }; } // namespace CoverArt