lms-metadata: added an option to specify the parser to use
This commit is contained in:
@@ -43,15 +43,15 @@ _LMS_ primarily relies on tags to organize your music collection but also suppor
|
|||||||
### Filtering
|
### Filtering
|
||||||
It is possible to apply global filters on your collection using `genre`, `mood`, `grouping`, `language`, and by music library. More tags, including custom ones, can be added in the database administration settings.
|
It is possible to apply global filters on your collection using `genre`, `mood`, `grouping`, `language`, and by music library. More tags, including custom ones, can be added in the database administration settings.
|
||||||
|
|
||||||
__Note__: You can use the `lms-metadata` tool to get an idea of the tags parsed by _LMS_ using [TagLib](https://github.com/taglib/taglib).
|
__Note__: You can use the `lms-metadata` tool to get an idea of the tags parsed by _LMS_.
|
||||||
|
|
||||||
### Multiple artists
|
### Multiple artists
|
||||||
_LMS_ works best when using the default Picard settings, where the `artist` tag contains a single display-friendly value, and the `artists` tag holds the actual artist names. This ensures a cleaner, more organized representation of artist names, when multiple artists are involved.
|
_LMS_ works best when using the default [Picard](https://picard.musicbrainz.org/) settings, where the `artist` tag contains a single display-friendly value, and the `artists` tag holds the actual artist names. This ensures a cleaner, more organized representation of artist names, when multiple artists are involved.
|
||||||
|
|
||||||
### Multiple album artists
|
### Multiple album artists
|
||||||
While LMS can manage multiple album artists using the `albumartist` tag, it works better when using the custom `albumartists` and `albumartistssort` tags, similar to how it handles regular artist tags.
|
While LMS can manage multiple album artists using the `albumartist` tag, it works better when using the custom `albumartists` and `albumartistssort` tags, similar to how it handles regular artist tags.
|
||||||
|
|
||||||
__Note__: if you use [Picard](https://picard.musicbrainz.org/), add the following script to include these tags:
|
__Note__: if you use Picard, add the following script to include these tags:
|
||||||
```
|
```
|
||||||
$setmulti(albumartists,%_albumartists%)
|
$setmulti(albumartists,%_albumartists%)
|
||||||
$setmulti(albumartistssort,%_albumartists_sort%)
|
$setmulti(albumartistssort,%_albumartists_sort%)
|
||||||
|
|||||||
@@ -27,7 +27,9 @@
|
|||||||
#include <Wt/WDate.h>
|
#include <Wt/WDate.h>
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
#include "core/EnumSet.hpp"
|
||||||
#include "core/StreamLogger.hpp"
|
#include "core/StreamLogger.hpp"
|
||||||
|
#include "core/String.hpp"
|
||||||
#include "metadata/Exception.hpp"
|
#include "metadata/Exception.hpp"
|
||||||
#include "metadata/IParser.hpp"
|
#include "metadata/IParser.hpp"
|
||||||
|
|
||||||
@@ -241,7 +243,8 @@ int main(int argc, char* argv[])
|
|||||||
options.add_options()
|
options.add_options()
|
||||||
("help,h", "Display this help message")
|
("help,h", "Display this help message")
|
||||||
("tag-delimiter", program_options::value<std::vector<std::string>>()->default_value(std::vector<std::string>{}, "[]"), "Tag delimiters (multiple allowed)")
|
("tag-delimiter", program_options::value<std::vector<std::string>>()->default_value(std::vector<std::string>{}, "[]"), "Tag delimiters (multiple allowed)")
|
||||||
("artist-tag-delimiter", program_options::value<std::vector<std::string>>()->default_value(std::vector<std::string>{}, "[]"), "Artist tag delimiters (multiple allowed)");
|
("artist-tag-delimiter", program_options::value<std::vector<std::string>>()->default_value(std::vector<std::string>{}, "[]"), "Artist tag delimiters (multiple allowed)")
|
||||||
|
("parser", program_options::value<std::vector<std::string>>()->default_value(std::vector<std::string>{ "taglib" }, "[taglib]"), "Parser to be used (value can be \"taglib\" or \"ffmpeg\")");
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
program_options::options_description hiddenOptions{ "Hidden options" };
|
program_options::options_description hiddenOptions{ "Hidden options" };
|
||||||
@@ -274,13 +277,39 @@ int main(int argc, char* argv[])
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vm.count("file"))
|
if (vm.count("file") == 0)
|
||||||
{
|
{
|
||||||
std::cout << "NO INPUT FILE!" << std::endl;
|
std::cerr << "No input file provided" << std::endl;
|
||||||
displayHelp(std::cerr);
|
displayHelp(std::cerr);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class Parser
|
||||||
|
{
|
||||||
|
Taglib,
|
||||||
|
Ffmpeg,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (vm.count("parser") == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "You must specify at least one parser" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
core::EnumSet<Parser> parsers;
|
||||||
|
for (const std::string& strParser : vm["parser"].as<std::vector<std::string>>())
|
||||||
|
{
|
||||||
|
if (core::stringUtils::stringCaseInsensitiveEqual(strParser, "taglib"))
|
||||||
|
parsers.insert(Parser::Taglib);
|
||||||
|
else if (core::stringUtils::stringCaseInsensitiveEqual(strParser, "ffmpeg"))
|
||||||
|
parsers.insert(Parser::Ffmpeg);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Invalid parser name '" << strParser << "'" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const auto& inputFiles{ vm["file"].as<std::vector<std::string>>() };
|
const auto& inputFiles{ vm["file"].as<std::vector<std::string>>() };
|
||||||
const auto& tagDelimiters{ vm["tag-delimiter"].as<std::vector<std::string>>() };
|
const auto& tagDelimiters{ vm["tag-delimiter"].as<std::vector<std::string>>() };
|
||||||
const auto& artistTagDelimiters{ vm["artist-tag-delimiter"].as<std::vector<std::string>>() };
|
const auto& artistTagDelimiters{ vm["artist-tag-delimiter"].as<std::vector<std::string>>() };
|
||||||
@@ -304,34 +333,40 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
std::cout << "Parsing file '" << file << "'" << std::endl;
|
std::cout << "Parsing file '" << file << "'" << std::endl;
|
||||||
|
|
||||||
try
|
if (parsers.contains(Parser::Ffmpeg))
|
||||||
{
|
{
|
||||||
std::cout << "Using av:" << std::endl;
|
try
|
||||||
|
{
|
||||||
|
std::cout << "Using Ffmpeg:" << std::endl;
|
||||||
|
|
||||||
auto parser{ metadata::createParser(metadata::ParserBackend::AvFormat, metadata::ParserReadStyle::Accurate) };
|
auto parser{ metadata::createParser(metadata::ParserBackend::AvFormat, metadata::ParserReadStyle::Accurate) };
|
||||||
parser->setArtistTagDelimiters(artistTagDelimiters);
|
parser->setArtistTagDelimiters(artistTagDelimiters);
|
||||||
parser->setDefaultTagDelimiters(tagDelimiters);
|
parser->setDefaultTagDelimiters(tagDelimiters);
|
||||||
|
|
||||||
parse(*parser, file);
|
parse(*parser, file);
|
||||||
}
|
}
|
||||||
catch (metadata::Exception& e)
|
catch (metadata::Exception& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Parsing failed: " << e.what() << std::endl;
|
std::cerr << "Parsing failed: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
if (parsers.contains(Parser::Taglib))
|
||||||
{
|
{
|
||||||
std::cout << "Using TagLib:" << std::endl;
|
try
|
||||||
|
{
|
||||||
|
std::cout << "Using TagLib:" << std::endl;
|
||||||
|
|
||||||
auto parser{ metadata::createParser(metadata::ParserBackend::TagLib, metadata::ParserReadStyle::Accurate) };
|
auto parser{ metadata::createParser(metadata::ParserBackend::TagLib, metadata::ParserReadStyle::Accurate) };
|
||||||
parser->setArtistTagDelimiters(artistTagDelimiters);
|
parser->setArtistTagDelimiters(artistTagDelimiters);
|
||||||
parser->setDefaultTagDelimiters(tagDelimiters);
|
parser->setDefaultTagDelimiters(tagDelimiters);
|
||||||
|
|
||||||
parse(*parser, file);
|
parse(*parser, file);
|
||||||
}
|
}
|
||||||
catch (metadata::Exception& e)
|
catch (metadata::Exception& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Parsing failed: " << e.what() << std::endl;
|
std::cerr << "Parsing failed: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user