Accept opus files that don't fully parse, remove opus-specific tag parser

The libtags change is a bit of a hack... I think we're running into
tracks that have long lyrics tags, which pushes the other tags out onto
the next ogg page?
custom
jacqueline 1 year ago
parent 79a6dc1a3e
commit 32cee65809
  1. 2
      lib/libtags/opus.c
  2. 15
      src/database/include/tag_parser.hpp
  3. 62
      src/database/tag_parser.cpp

@ -63,7 +63,7 @@ tagopus(Tagctx *ctx)
ctx->buf[sz] = 0;
if((v = strchr(ctx->buf, '=')) == nil)
return -1;
continue;
*v++ = 0;
cbvorbiscomment(ctx, ctx->buf, v);
}

@ -20,12 +20,6 @@ class ITagParser {
-> std::shared_ptr<TrackTags> = 0;
};
class GenericTagParser : public ITagParser {
public:
auto ReadAndParseTags(const std::string& path)
-> std::shared_ptr<TrackTags> override;
};
class TagParserImpl : public ITagParser {
public:
TagParserImpl();
@ -33,8 +27,7 @@ class TagParserImpl : public ITagParser {
-> std::shared_ptr<TrackTags> override;
private:
std::map<std::string, std::unique_ptr<ITagParser>> extension_to_parser_;
GenericTagParser generic_parser_;
auto parseNew(const std::string& path) -> std::shared_ptr<TrackTags>;
/*
* Cache of tags that have already been extracted from files. Ideally this
@ -48,10 +41,4 @@ class TagParserImpl : public ITagParser {
// any of our UI.
};
class OpusTagParser : public ITagParser {
public:
auto ReadAndParseTags(const std::string& path)
-> std::shared_ptr<TrackTags> override;
};
} // namespace database

@ -6,14 +6,13 @@
#include "tag_parser.hpp"
#include <stdint.h>
#include <cstdint>
#include <cstdlib>
#include <iomanip>
#include <mutex>
#include "esp_log.h"
#include "ff.h"
#include "opusfile.h"
#include "spi.hpp"
#include "tags.h"
@ -21,16 +20,6 @@
namespace database {
const static std::array<std::pair<const char*, Tag>, 7> kVorbisIdToTag = {{
{"TITLE", Tag::kTitle},
{"ARTIST", Tag::kArtist},
{"ALBUM", Tag::kAlbum},
{"ALBUMARTIST", Tag::kAlbumArtist},
{"DISCNUMBER", Tag::kDisc},
{"TRACKNUMBER", Tag::kTrack},
{"GENRE", Tag::kGenres},
}};
static auto convert_tag(int tag) -> std::optional<Tag> {
switch (tag) {
case Ttitle:
@ -117,9 +106,7 @@ static void toc(Tagctx* ctx, int ms, int offset) {}
static const std::size_t kBufSize = 1024;
[[maybe_unused]] static const char* kTag = "TAGS";
TagParserImpl::TagParserImpl() {
extension_to_parser_["opus"] = std::make_unique<OpusTagParser>();
}
TagParserImpl::TagParserImpl() {}
auto TagParserImpl::ReadAndParseTags(const std::string& path)
-> std::shared_ptr<TrackTags> {
@ -132,18 +119,7 @@ auto TagParserImpl::ReadAndParseTags(const std::string& path)
}
}
ITagParser* parser = &generic_parser_;
auto dot_pos = path.find_last_of(".");
if (dot_pos != std::string::npos && path.size() - dot_pos > 1) {
std::string extension = path.substr(dot_pos + 1);
std::transform(extension.begin(), extension.end(), extension.begin(),
[](unsigned char c) { return std::tolower(c); });
if (extension_to_parser_.contains(extension)) {
parser = extension_to_parser_[extension].get();
}
}
std::shared_ptr<TrackTags> tags = parser->ReadAndParseTags(path);
std::shared_ptr<TrackTags> tags = parseNew(path);
if (!tags) {
return {};
}
@ -167,7 +143,7 @@ auto TagParserImpl::ReadAndParseTags(const std::string& path)
return tags;
}
auto GenericTagParser::ReadAndParseTags(const std::string& path)
auto TagParserImpl::parseNew(const std::string& path)
-> std::shared_ptr<TrackTags> {
libtags::Aux aux;
auto out = TrackTags::create();
@ -229,34 +205,4 @@ auto GenericTagParser::ReadAndParseTags(const std::string& path)
return out;
}
auto OpusTagParser::ReadAndParseTags(const std::string& path)
-> std::shared_ptr<TrackTags> {
auto lock = drivers::acquire_spi();
std::string vfs_path = "/sdcard" + path;
int err;
OggOpusFile* f = op_test_file(vfs_path.c_str(), &err);
if (f == NULL) {
ESP_LOGE(kTag, "opusfile tag parsing failed: %d", err);
return {};
}
const OpusTags* tags = op_tags(f, -1);
if (tags == NULL) {
ESP_LOGE(kTag, "no tags in opusfile");
op_free(f);
return {};
}
auto out = TrackTags::create();
out->encoding(Container::kOpus);
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);
return out;
}
} // namespace database

Loading…
Cancel
Save