C++ library for reading and writing MP4/M4A/AAC (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
C++ Other
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
aac Fix misc warnings Aug 4, 2018
adts Use constexpr where possible Jul 12, 2018
avc Replace typedef with using Jul 12, 2018
avi Fix documentation which was still using the old namespace Jun 3, 2018
flac Implement small TODOs for v8 Jul 12, 2018
id3 Handle unknown short IDs correctly when comparing ID3v2 frame IDs Jul 13, 2018
ivf Detect AV1 in IVF stream Jul 28, 2018
matroska Detect AV1 in MKV Jul 28, 2018
mp4 Improve coding style (after running clang-tidy) Aug 12, 2018
mpegaudio Fix warnings in MpegAudioFrame Jul 28, 2018
ogg Improve coding style (after running clang-tidy) Aug 12, 2018
opus Use constexpr where possible Jul 12, 2018
scripts Detect AV1 in IVF stream Jul 28, 2018
testfiles Test more methods of MediaFileInfo Aug 17, 2017
tests Fix leaking memory or file handles in StreamDataBlock descendants Aug 11, 2018
vorbis Fix typo occured -> occurred Jul 23, 2018
wav Detect AV1 in IVF stream Jul 28, 2018
.gitignore Apply clang-format later May 1, 2017
CMakeLists.txt Detect AV1 in IVF stream Jul 28, 2018
LICENSE Initial commit Apr 22, 2015
README.md Document usage, especially error handling Mar 6, 2018
abstractattachment.cpp Fix leaking memory or file handles in StreamDataBlock descendants Aug 11, 2018
abstractattachment.h Fix leaking memory or file handles in StreamDataBlock descendants Aug 11, 2018
abstractchapter.cpp Fix documentation which was still using the old namespace Jun 3, 2018
abstractchapter.h Apply clang-format Mar 7, 2018
abstractcontainer.cpp Fix documentation which was still using the old namespace Jun 3, 2018
abstractcontainer.h Refactor MediaFileInfo::createAppropriateTags() Mar 11, 2018
abstracttrack.cpp Fix documentation which was still using the old namespace Jun 3, 2018
abstracttrack.h Detect AV1 in IVF stream Jul 28, 2018
aspectratio.cpp Fix documentation which was still using the old namespace Jun 3, 2018
aspectratio.h Add AspectRatio::toString() Jul 28, 2018
backuphelper.cpp Fix typo occured -> occurred Jul 23, 2018
backuphelper.h Don't use global variable for backup directory Jul 12, 2018
basicfileinfo.cpp Fix documentation which was still using the old namespace Jun 3, 2018
basicfileinfo.h Apply clang-format Mar 7, 2018
caseinsensitivecomparer.h Apply clang-format Mar 7, 2018
diagnostics.cpp Refactor formatting list of values Jul 1, 2018
diagnostics.h Remove DiagPtr Jul 12, 2018
exceptions.cpp Fix documentation which was still using the old namespace Jun 3, 2018
exceptions.h Apply clang-format Mar 7, 2018
fieldbasedtag.h Adjust values()/setValues() to handle multiple values per text frame Jul 12, 2018
genericcontainer.h Replace typedef with using Jul 12, 2018
genericfileelement.h Replace typedef with using Jul 12, 2018
generictagfield.h Replace typedef with using Jul 12, 2018
global.h Apply clang-format later May 1, 2017
localeawarestring.cpp Apply clang-format Mar 7, 2018
localeawarestring.h Apply clang-format Mar 7, 2018
margin.h Apply clang-format Mar 7, 2018
mediafileinfo.cpp Detect AV1 in IVF stream Jul 28, 2018
mediafileinfo.h Fix typo occured -> occurred Jul 23, 2018
mediaformat.cpp Detect AV1 in MKV Jul 28, 2018
mediaformat.h Fix misc warnings Aug 4, 2018
positioninset.h Fix documentation which was still using the old namespace Jun 3, 2018
progressfeedback.cpp Document progress feedback Jun 3, 2018
progressfeedback.h Document progress feedback Jun 3, 2018
settings.h Apply clang-format Mar 14, 2018
signature.cpp Detect AV1 in IVF stream Jul 28, 2018
signature.h Detect AV1 in IVF stream Jul 28, 2018
size.cpp Apply clang-format Mar 7, 2018
size.h Apply clang-format Mar 7, 2018
tag.cpp Add Tag::supportsMultipleValues() Jul 13, 2018
tag.h Add Tag::supportsMultipleValues() Jul 13, 2018
tagtarget.cpp Fix documentation which was still using the old namespace Jun 3, 2018
tagtarget.h Replace typedef with using Jul 12, 2018
tagvalue.cpp Fix documentation which was still using the old namespace Jun 3, 2018
tagvalue.h Implement small TODOs for v8 Jul 12, 2018

README.md

Tag Parser

C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags.

Supported formats

The tag library can read and write the following tag formats:

  • iTunes-style MP4/M4A tags (MP4-DASH is supported)
  • ID3v1 and ID3v2 tags
    • conversion between ID3v1 and different versions of ID3v2 is possible
  • Vorbis, Opus and FLAC comments in Ogg streams
    • cover art via "METADATA_BLOCK_PICTURE" is supported
  • Vorbis comments and "METADATA_BLOCK_PICTURE" in raw FLAC streams
  • Matroska/WebM tags and attachments

File layout options

Tag position

The library allows you to choose whether tags should be placed at the beginning or at the end of an MP4/Matroska file.

Padding

Padding allows adding additional tag information without rewriting the entire file or appending the tag. Usage of padding can be configured:

  • minimum/maximum padding: The file is rewritten if the padding would fall below/exceed the specifed limits.
  • preferred padding: If the file needs to be rewritten the preferred padding is used.

Default value for minimum and maximum padding is zero. Hence the library will almost always have to rewrite the entire file to apply changes. To prevent this, set at least the maximum padding to a higher value.

It is also possible to force rewriting the entire file always.

Taking advantage of padding is currently not supported when dealing with Ogg streams (it is supported when dealing with raw FLAC streams).

Additional features

The library can also display technical information such as the ID, format, language, bitrate, duration, size, timestamps, sampling frequency, FPS and other information of the tracks.

It also allows to inspect and validate the element structure of MP4 and Matroska files.

Text encoding, Unicode support

The library is aware of different text encodings and can convert between different encodings using iconv.

Windows specific

A workaround to support filenames containing non-ASCII characters (despite the lack of an UTF-8 supporting std::fstream under Windows) can be enabled by adding -DUSE_NATIVE_FILE_BUFFER=ON to the CMake arguments when building c++utilities. It is not sufficient to specify this option only when building tagparser.

Usage

This example shows how to read and write tag fields in a format-independent way:

#include <tagparser/mediafileinfo.h>
#include <tagparser/diagnostics.h>

using namespace TagParser;

// create a MediaFileInfo for high-level access to overall functionality of the library
MediaFileInfo fileInfo;
// create container for errors, warnings, etc.
Diagnostics diag;

// open file (might throw ios_base::failure)
fileInfo.setPath("/path/to/some/file");
fileInfo.open();
// parse tags
// (might throw exception derived from Failure for fatal parsing error or ios_base::failure for IO errors)
fileInfo.parseTags(diag);

// get first tag as an object derived from the Tag class
auto tag = fileInfo.tags().at(0);
// extract title and convert it to UTF-8 std::string
// (toString() might throw ConversionException)
auto title = tag->value(KnownField::Title).toString(TagTextEncoding::Utf8);

// change album using an encoding suitable for the tag format
tag->setValue(KnownField::Album, TagValue("some UTF-8 string", TagTextEncoding::Utf8, tag->proposedTextEncoding()));

// create progress
AbortableProgressFeedback progress([callback for status update], [callback for percentage-only updates]);

// apply changes to the file on disk
// (might throw exception derived from Failure for fatal processing error or ios_base::failure for IO errors)
fileInfo.applyChanges(diag, progress);

Summary

  • So the most important class is MediaFileInfo providing access to everything else.
  • IO errors are propagated via standard std::ios_base::failure.
  • Fatal processing errors are propagated by throwing a class derived from Failure.
  • All operations which might generate warnings, non-fatal errors, ... take a Diagnostics object to store those messages.
  • All operations which can be aborted or provide progress feedback take a AbortableProgressFeedback object for callbacks and aborting.
  • Field values are stored using TagValue objects. Those objects erase the actual type similar to QVariant from the Qt framework.

Further documentation

For more examples check out the command line interface of Tag Editor. API documentation can be generated using Doxygen with make tagparser_apidoc.

Bugs, stability

It is recommend to create backups before editing because I can not test whether the library works with all kinds of files (when forcing rewrite a backup is always created).

Build instructions

The tagparser library depends on c++utilities and is built in the same way. It also depends on zlib. For checking integrity of testfiles, the OpenSSL crypto library is required.

TODOs

  • Support more formats (EXIF, PDF metadata, Theora, ...)
  • Support adding cue-sheet to FLAC files

More TODOs are tracked in the issue section at GitHub.