Any appetite for a 'normalisation' layer over non-std tags?
adam.szmigin at xsco.net
Sun Apr 9 09:54:17 UTC 2017
Dear TagLib devs,
Firstly, many thanks to all the contributors on TagLib - it is an
excellent library and it has benefited me greatly in a number of
projects I've undertaken.
For a TagLib user wishing to read "exotic" tags, i.e. those that are not
available via FileRef::tag(), it looks like the user has to construct a
specific File sub-class and work with the different tag() (or ID3v2Tag()
/ xiphComment() etc!) methods to get what they want. How to proceed
varies based on the file format, and also to some extent what tagging
application was used that wrote the original tags.
The issue I find is that the tags I often work with for music are not so
"exotic", but essential: they include things like album-artist, disc
number, composer. There is no universal standard for these fields
across all file types that I know of.
So, I have found myself writing a normalisation layer over the top of
TagLib, which both instantiates the appropriate File sub-class given a
path, and also tries a few different approaches to get values for this
extended range of common but non-standardised tag fields. Here is the
broad interface to give an idea:
metadata(const boost::filesystem::path &path);
bool has_tag() const;
std::string album() const;
std::string album_artist() const;
std::string artist() const;
std::string comment() const;
std::string composer() const;
std::string copyright() const;
std::string date() const;
std::string disc_number() const;
std::string disc_total() const;
std::string encoded_by() const;
std::string genre() const;
std::string original_artist() const;
std::string title() const;
std::string track_number() const;
std::string track_total() const;
std::string url() const;
Examples of format-specific manipulation include things like this:
std::string disc_number() const
auto val = prop("DISCNUMBER"); // Uses TagLib::xx::File::properties()
// Remove anything after forward slash, if format is "DISC/TOTAL".
auto pos = val.find_first_of('/');
if (pos != std::string::npos)
// Remove leading zeroes
val.erase(0, std::min(val.find_first_not_of('0'), val.size()-1));
*My question is:* from a read-only perspective (and maybe read/write),
is there any appetite for a normalisation layer like this over the top
of TagLib? It could either be a part of TagLib, or a separate project.
(Ignore the use of boost and std::string vs String in the example..
It's just illustrative. The example was taken from a recent project I'm
working on where the "normalisation" layer is not designed to be
I'd also appreciate any feedback from the TagLib gurus on whether I'm
"doing it right" regarding the above process of normalisation.
More information about the taglib-devel