UI: use codec info in database instead of rescanning files

This commit is contained in:
emeric
2025-11-26 22:20:37 +01:00
parent 37d603d72c
commit c70935a5a2
8 changed files with 153 additions and 46 deletions
@@ -679,6 +679,14 @@ namespace lms::db
return utils::fetchQuerySingleResult(session()->query<int>("SELECT COALESCE(AVG(t.bitrate), 0) FROM track t").where("release_id = ?").bind(getId()).where("bitrate > 0"));
}
std::vector<CodecType> Release::getCodecs() const
{
assert(session());
// Get the codec ordered by frequency
return utils::fetchQueryResults(session()->query<CodecType>("SELECT t.codec FROM track t").where("release_id = ?").bind(getId()).groupBy("t.codec").orderBy("COUNT(t.id) DESC"));
}
std::vector<Artist::pointer> Release::getArtists(TrackArtistLinkType linkType) const
{
assert(session());
+91
View File
@@ -73,4 +73,95 @@ namespace lms::db
return allowedAudioBitrates.find(bitrate) != std::cend(allowedAudioBitrates);
}
core::LiteralString containerTypeToString(ContainerType type)
{
switch (type)
{
case ContainerType::Unknown:
break;
case ContainerType::AIFF:
return "AIFF";
case ContainerType::APE:
return "APE";
case ContainerType::ASF:
return "ASF";
case ContainerType::DSF:
return "DSF";
case ContainerType::FLAC:
return "FLAC";
case ContainerType::MP4:
return "MP4";
case ContainerType::MPC:
return "MPC";
case ContainerType::MPEG:
return "MPEG";
case ContainerType::Ogg:
return "Ogg";
case ContainerType::Shorten:
return "Shorten";
case ContainerType::TrueAudio:
return "TrueAudio";
case ContainerType::WAV:
return "WAV";
case ContainerType::WavPack:
return "WavPack";
}
return "Unknown";
}
core::LiteralString codecTypeToString(CodecType type)
{
switch (type)
{
case CodecType::Unknown:
break;
case CodecType::AAC:
return "AAC";
case CodecType::AC3:
return "AC3";
case CodecType::ALAC:
return "ALAC";
case CodecType::APE:
return "APE";
case CodecType::DSD:
return "DSD";
case CodecType::EAC3:
return "EAC3";
case CodecType::FLAC:
return "FLAC";
case CodecType::MP3:
return "MP3";
case CodecType::MP4ALS:
return "MP4ALS";
case CodecType::MPC7:
return "MPC7";
case CodecType::MPC8:
return "MPC8";
case CodecType::Opus:
return "Opus";
case CodecType::PCM:
return "PCM";
case CodecType::Shorten:
return "Shorten";
case CodecType::TrueAudio:
return "TrueAudio";
case CodecType::Vorbis:
return "Vorbis";
case CodecType::WavPack:
return "WavPack";
case CodecType::WMA1:
return "WMA1";
case CodecType::WMA2:
return "WMA2";
case CodecType::WMA9Pro:
return "WMA9Pro";
case CodecType::WMA9Lossless:
return "WMA9Lossless";
}
return "Unknown";
}
} // namespace lms::db
@@ -279,6 +279,7 @@ namespace lms::db
std::optional<std::string> getCopyright() const;
std::optional<std::string> getCopyrightURL() const;
std::size_t getMeanBitrate() const;
std::vector<CodecType> getCodecs() const;
// Accessors
std::string_view getName() const { return _name; }
@@ -286,6 +286,8 @@ namespace lms::db
WavPack = 13,
};
core::LiteralString containerTypeToString(ContainerType type);
enum class CodecType
{
Unknown = 0,
@@ -312,4 +314,6 @@ namespace lms::db
WMA9Pro = 20,
WMA9Lossless = 21,
};
core::LiteralString codecTypeToString(CodecType type);
} // namespace lms::db
+34
View File
@@ -1214,6 +1214,40 @@ namespace lms::db::tests
checkExpectedBitrate(192); // 0 should not be taken into account
}
TEST_F(DatabaseFixture, Release_codec)
{
ScopedRelease release1{ session, "MyRelease1" };
ScopedTrack track1{ session };
ScopedTrack track2{ session };
ScopedTrack track3{ session };
ScopedTrack track4{ session };
{
auto transaction{ session.createReadTransaction() };
ASSERT_EQ(release1->getCodecs().size(), 0);
}
{
auto transaction{ session.createWriteTransaction() };
track1.get().modify()->setCodec(CodecType::FLAC);
track1.get().modify()->setRelease(release1.get());
track2.get().modify()->setCodec(CodecType::MP3);
track2.get().modify()->setRelease(release1.get());
track3.get().modify()->setCodec(CodecType::MP3);
track3.get().modify()->setRelease(release1.get());
track4.get().modify()->setCodec(CodecType::AAC);
track4.get().modify()->setRelease(release1.get());
}
{
auto transaction{ session.createReadTransaction() };
EXPECT_EQ(release1->getCodecs(), (std::vector<CodecType>{ CodecType::MP3, CodecType::FLAC, CodecType::AAC }));
}
}
TEST_F(DatabaseFixture, Release_trackCount)
{
ScopedRelease release1{ session, "MyRelease1" };