Fix missing track number issues

This commit is contained in:
jacqueline
2023-09-06 12:38:40 +10:00
parent dad14baa73
commit 63215ccf16
4 changed files with 51 additions and 22 deletions
+5 -1
View File
@@ -5,10 +5,13 @@
*/
#include "index.hpp"
#include <stdint.h>
#include <cstdint>
#include <variant>
#include "komihash.h"
#include "leveldb/write_batch.h"
#include "records.hpp"
namespace database {
@@ -49,6 +52,7 @@ static auto missing_component_text(const Track& track, Tag tag)
case Tag::kTitle:
return track.TitleOrFilename();
case Tag::kAlbumTrack:
return "0000";
case Tag::kDuration:
default:
return {};
+5 -4
View File
@@ -309,7 +309,8 @@ auto EncodeIndexKey(const IndexKey& key) -> OwningSlice {
// Construct the footer.
out << kFieldSeparator;
if (key.track) {
out << TrackIdToBytes(*key.track).data;
auto encoded = TrackIdToBytes(*key.track);
out << encoded.data;
}
return OwningSlice(out.str());
}
@@ -394,9 +395,9 @@ auto ParseIndexKey(const leveldb::Slice& slice) -> std::optional<IndexKey> {
buffer = {};
in.get(buffer);
if (buffer.str().size() > 1) {
std::string raw_id = buffer.str().substr(1);
result.track = BytesToTrackId(raw_id);
std::string id_str = buffer.str();
if (id_str.size() > 1) {
result.track = BytesToTrackId(id_str.substr(1));
}
return result;
+40 -17
View File
@@ -17,7 +17,26 @@
namespace database {
auto convert_tag(int tag) -> std::optional<Tag> {
const static std::array<std::pair<const char*, Tag>, 5> kVorbisIdToTag = {{
{"TITLE", Tag::kTitle},
{"ARTIST", Tag::kArtist},
{"ALBUM", Tag::kAlbum},
{"TRACKNUMBER", Tag::kAlbumTrack},
{"GENRE", Tag::kGenre},
}};
static auto convert_track_number(int number) -> std::string {
std::ostringstream oss;
oss << std::setw(4) << std::setfill('0') << number;
return oss.str();
}
static auto convert_track_number(const std::string& raw) -> std::string {
uint32_t as_int = std::atoi(raw.c_str());
return convert_track_number(as_int);
}
static auto convert_tag(int tag) -> std::optional<Tag> {
switch (tag) {
case Ttitle:
return Tag::kTitle;
@@ -92,10 +111,6 @@ static void tag(Tagctx* ctx,
return;
}
if (*tag == Tag::kAlbumTrack) {
uint32_t as_int = std::atoi(v);
std::ostringstream oss;
oss << std::setw(4) << std::setfill('0') << as_int;
value = oss.str();
}
aux->tags->set(*tag, value);
}
@@ -137,6 +152,21 @@ auto TagParserImpl::ReadAndParseTags(const std::string& path, TrackTags* out)
return false;
}
// There wasn't a track number found in the track's tags. Try to synthesize
// one from the filename, which will sometimes have a track number at the
// start.
if (!out->at(Tag::kAlbumTrack)) {
auto slash_pos = path.find_last_of("/");
if (slash_pos != std::string::npos && path.size() - slash_pos > 1) {
out->set(Tag::kAlbumTrack, path.substr(slash_pos + 1));
}
}
// Normalise track numbers; they're usually treated as strings, but we would
// like to sort them lexicographically.
out->set(Tag::kAlbumTrack,
convert_track_number(out->at(Tag::kAlbumTrack).value_or("0")));
{
std::lock_guard<std::mutex> lock{cache_mutex_};
cache_.Put(path, *out);
@@ -226,18 +256,11 @@ auto OpusTagParser::ReadAndParseTags(const std::string& path, TrackTags* out)
}
out->encoding(Container::kOpus);
const char* tag = NULL;
tag = opus_tags_query(tags, "TITLE", 0);
if (tag != NULL) {
out->set(Tag::kTitle, tag);
}
tag = opus_tags_query(tags, "ARTIST", 0);
if (tag != NULL) {
out->set(Tag::kArtist, tag);
}
tag = opus_tags_query(tags, "ALBUM", 0);
if (tag != NULL) {
out->set(Tag::kAlbum, tag);
for (const auto& pair : kVorbisIdToTag) {
const char* tag = opus_tags_query(tags, pair.first, 0);
if (tag != NULL) {
out->set(pair.second, tag);
}
}
op_free(f);
+1
View File
@@ -45,6 +45,7 @@ auto TrackTags::Hash() const -> uint64_t {
HashString(&stream, at(Tag::kTitle).value_or(""));
HashString(&stream, at(Tag::kArtist).value_or(""));
HashString(&stream, at(Tag::kAlbum).value_or(""));
HashString(&stream, at(Tag::kAlbumTrack).value_or(""));
return komihash_stream_final(&stream);
}