martchus / tagparser Goto Github PK
View Code? Open in Web Editor NEWC++ library for reading and writing MP4/M4A/AAC (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
License: GNU General Public License v2.0
C++ library for reading and writing MP4/M4A/AAC (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
License: GNU General Public License v2.0
After editing tags of mp4 files, Playstation3 recognizes those files are broken (unplayable).
ffmpeg -i shows the following message:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x56489a625520] overread end of atom 'tkhd' by 4 bytes
Versions:
tageditor 2.2.5
tagparser 6.4.0
c++utilities 4.9.2
on ArchLinux(x86_64)
On tageditor2.2.3 and tagparser6.3.0, this issue doesn't occur.
This may be a Mac only issue, but it is not something that a Mac user can add a symlink to fix because the location is SIP protected and cannot be changed even with the use of sudo. It may be that on a linux machine this location works, I would recommend adding a try/catch here and looking in both places if this file is not doing this in error. If this and the other error were fixed I would be able to complete the Brew Formulae that you link to on the cpp-utilities readme and make installing on a Mac really easy.
This file: generate_iso_language_codes.cmake
looks for a file to include during compiling at this location:
usr/share/iso-codes/json
on a Mac the actual location is in:
usr/local/share/iso-codes/json
This is the case for all audio, video, and subtitle tracks in the MKV files I've tested.
Hi, I am trying to include tagparser library as a dependency in my project using the following in my CMakelist.txt
file.
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH true)
add_subdirectory(libs/cpp-utilities-5.10.0 c++utilities)
list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_SOURCE_DIR}/cmake/modules)
link_directories(${CPP_UTILITIES_BINARY_DIR})
add_subdirectory(libs/tagparser-9.4.0 tagparser)
link_directories(${TAG_PARSER_BINARY_DIR})
However, when I try to build it I get the following error:
Scanning dependencies of target tagparser
[ 47%] Building CXX object tagparser/CMakeFiles/tagparser.dir/aac/aaccodebook.cpp.o
In file included from /mnt/c/Users/padi/CLionProjects/autotag-cpp/libs/tagparser-9.4.0/aac/./aaccodebook.h:6,
from /mnt/c/Users/padi/CLionProjects/autotag-cpp/libs/tagparser-9.4.0/aac/aaccodebook.cpp:1:
/mnt/c/Users/padi/CLionProjects/autotag-cpp/libs/tagparser-9.4.0/aac/./../global.h:7:10: fatal error: c++utilities/application/global.h: No such file or directory
7 | #include <c++utilities/application/global.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [tagparser/CMakeFiles/tagparser.dir/build.make:82: tagparser/CMakeFiles/tagparser.dir/aac/aaccodebook.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:1608: tagparser/CMakeFiles/tagparser.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=x86_64-w64-mingw32-
[...]
Could not find a package configuration file provided by "c++utilities"
(requested version 5.0.0) with any of the following names:
c++utilitiesConfig.cmake
c++utilities-config.cmake
So as can be seen tagparser is requesting c++utilities version 5.0.0. But that
doesnt exist:
I was trying to compile tageditor on a mac (Big Sur) and tagparser is a dependency and I ran into this error at the "make" stage.
tagparser/mpegaudio/mpegaudioframe.cpp:55:123: error: use of overloaded operator '-' is ambiguous (with operand types 'std::basic_istream<char>::pos_type' (aka 'fpos<__mbstate_t>') and 'long')
"Frame 0x" % numberToString(m_header, 16u) % " at 0x" % numberToString<std::int64_t>(reader.stream()->tellg() - 4l, 16) + " is invalid.",
~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~
/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk/usr/include/c++/v1/string:555:37: note: candidate function
_LIBCPP_INLINE_VISIBILITY fpos operator- (streamoff __off) const {fpos __t(*this); __t -= __off; return __t;}
^
../tagparser/mpegaudio/mpegaudioframe.cpp:55:123: note: built-in candidate operator-(long long, long)
"Frame 0x" % numberToString(m_header, 16u) % " at 0x" % numberToString<std::int64_t>(reader.stream()->tellg() - 4l, 16) + " is invalid.",
I just made that line throw a static error since I did not know how to fix it, and then it installed fine.
For those trying to install on a mac, be absolutely sure you have the latest xCode Command Line Tools installed. After I installed them, it was not until I ran brew doctor
that I became aware that a fresh install of those tools was not the latest version and it needed to be updated. Running brew doctor
will give you the command to force the latest xCode CLT.
Build cpp-utulities without doxygen
>>> Emerging (1 of 4) media-sound/tagparser-9999::pg_overlay
>>> Unpacking source...
* Fetching git://github.com/Martchus/tagparser.git ...
git fetch git://github.com/Martchus/tagparser.git +HEAD:refs/git-r3/HEAD
git symbolic-ref refs/git-r3/media-sound/tagparser/5/__main__ refs/git-r3/HEAD
* Checking out git://github.com/Martchus/tagparser.git to /tmp/portage/media-sound/tagparser-9999/work/tagparser-9999 ...
git checkout --quiet refs/git-r3/HEAD
GIT update -->
repository: git://github.com/Martchus/tagparser.git
at the commit: 8663dedf8c96af7bade6dcb492eb213b43ac454a
>>> Source unpacked in /tmp/portage/media-sound/tagparser-9999/work
>>> Preparing source in /tmp/portage/media-sound/tagparser-9999/work/tagparser-9999 ...
>>> Source prepared.
>>> Configuring source in /tmp/portage/media-sound/tagparser-9999/work/tagparser-9999 ...
>>> Working in BUILD_DIR: "/tmp/portage/media-sound/tagparser-9999/work/tagparser-9999_build"
cmake -C /tmp/portage/media-sound/tagparser-9999/work/tagparser-9999_build/gentoo_common_config.cmake -G Unix Makefiles -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_TYPE=Gentoo -DCMAKE_USER_MAKE_RULES_OVERRIDE=/tmp/portage/media-sound/tagparser-9999/work/tagparser-9999_build/gentoo_rules.cmake -DCMAKE_TOOLCHAIN_FILE=/tmp/portage/media-sound/tagparser-9999/work/tagparser-9999_build/gentoo_toolchain.cmake /tmp/portage/media-sound/tagparser-9999/work/tagparser-9999
loading initial cache file /tmp/portage/media-sound/tagparser-9999/work/tagparser-9999_build/gentoo_common_config.cmake
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/x86_64-pc-linux-gnu-gcc
-- Check for working C compiler: /usr/bin/x86_64-pc-linux-gnu-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/x86_64-pc-linux-gnu-g++
-- Check for working CXX compiler: /usr/bin/x86_64-pc-linux-gnu-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Linking tagparser dynamically against c++utilities (c++utilities).
-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.8")
-- Linking tagparser dynamically against external library ZLIB (/usr/lib64/libz.so).
-- Using default CXX11 ABI (not forcing old CX11 ABI).
-- Using template for Config.cmake from tagparser installation.
-- Using template for doxygen from tagparser installation.
CMake Warning at /usr/share/c++utilities/cmake/modules/Doxygen.cmake:22 (message):
Doxygen not found, unable to add target for generating API documentation.
Call Stack (most recent call first):
CMakeLists.txt:179 (include)
CMake Error at CMakeLists.txt:180 (include):
include could not find load file:
ConfigHeader
-- <<< Gentoo configuration >>>
Build type Gentoo
Install path /usr
Compiler flags:
C -march=native -mtune=native -O2 -pipe -fomit-frame-pointer -fno-stack-protector
C++ -march=native -mtune=native -O2 -pipe -fomit-frame-pointer -fno-stack-protector
Linker flags:
Executable -Wl,-O1 -Wl,--as-needed
Module -Wl,-O1 -Wl,--as-needed
Shared -Wl,-O1 -Wl,--as-needed
I've tested this on a few different matroska files, and although startTime.toString() returns the correct starting times for the chapters, regardless of what file I test, the end time returned for every chapter is 00:36:00.
Martchus/tageditor#13 (comment):
Still does not work without OpenSSL:
CMake Error: The following variables are used in this project, but they are set to NOTFOUND. Please set them or make sure they are set and tested correctly in the CMake files: OPENSSL_INCLUDE_DIR (ADVANCED) used as include directory in directory /var/cache/glade/tagparser
Not sure why it worked when I tested a few hours ago. Need to further investigate this.
"Only text frame identifiers begin with "T", with the exception of the "TXXX" frame."
[ 50% 1/2] /usr/local/libexec/ccache/c++ -DCPP_UTILITIES_USE_NATIVE_FILE_BUFFER -I/usr/ports/multimedia/tagparser/work/tagparser-12.0.0 -I/usr/ports/multimedia/tagparser/work/.build -I/usr/ports/multimedia/tagparser/work/tagparser-12.0.0/.. -O2 -pipe -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing -I/usr/ports/multimedia/tagparser/work/stage/usr/local/include -isystem /usr/local/include -O2 -pipe -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing -I/usr/ports/multimedia/tagparser/work/stage/usr/local/include -isystem /usr/local/include -DNDEBUG -std=gnu++17 -fvisibility=hidden -MD -MT CMakeFiles/tagparser_tests.dir/cppunit.cpp.o -MF CMakeFiles/tagparser_tests.dir/cppunit.cpp.o.d -o CMakeFiles/tagparser_tests.dir/cppunit.cpp.o -c /usr/ports/multimedia/tagparser/work/.build/cppunit.cpp
[100% 2/2] : && /usr/local/libexec/ccache/c++ -O2 -pipe -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing -I/usr/ports/multimedia/tagparser/work/stage/usr/local/include -isystem /usr/local/include -O2 -pipe -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing -I/usr/ports/multimedia/tagparser/work/stage/usr/local/include -isystem /usr/local/include -DNDEBUG -fstack-protector-strong CMakeFiles/tagparser_tests.dir/tests/helper.cpp.o CMakeFiles/tagparser_tests.dir/tests/mediafileinfo.cpp.o CMakeFiles/tagparser_tests.dir/tests/overallflac.cpp.o CMakeFiles/tagparser_tests.dir/tests/overallgeneral.cpp.o CMakeFiles/tagparser_tests.dir/tests/overallmkv.cpp.o CMakeFiles/tagparser_tests.dir/tests/overallmp3.cpp.o CMakeFiles/tagparser_tests.dir/tests/overallmp4.cpp.o CMakeFiles/tagparser_tests.dir/tests/overallogg.cpp.o CMakeFiles/tagparser_tests.dir/tests/tagvalue.cpp.o CMakeFiles/tagparser_tests.dir/tests/testfilecheck.cpp.o CMakeFiles/tagparser_tests.dir/tests/utils.cpp.o CMakeFiles/tagparser_tests.dir/doc/example.cpp.o CMakeFiles/tagparser_tests.dir/cppunit.cpp.o -o tagparser_tests -L/usr/local/lib -Wl,-rpath,/usr/local/lib:/usr/ports/multimedia/tagparser/work/.build /usr/lib/libcrypto.so -lcppunit libtagparser.so.12.0.0 /usr/lib/libz.so /usr/local/lib/libc++utilities.so.5.24.0 && :
[ 0% 1/1] cd /usr/ports/multimedia/tagparser/work/.build && /usr/local/bin/ctest --force-new-ctest-process
Test project /usr/ports/multimedia/tagparser/work/.build
Start 1: tagparser_run_tests
1/1 Test #1: tagparser_run_tests ..............***Failed 0.01 sec
/usr/ports/multimedia/tagparser/work/tagparser-12.0.0/testfiles/
/usr/ports/multimedia/tagparser/work/tagparser-12.0.0/testfiles/
./testfiles/
Directory used to store working copies:
/usr/ports/multimedia/tagparser/work/.build/testworkingdir/
Executing test cases ...
....E.
MP4 parser
E.
MP3 parser
E.
OGG parser
E.
FLAC parser
E.
Matroska parser
E.
MP4 maker - testmode 0: tags after data
E.
MP3 maker - testmode 0: ID3v2 only
E.
OGG maker - testmode 0: modifying tag
E.
FLAC maker - testmode 0: modifying tag
E.
Matroska maker - testmode 0: tags after data, index after data
E.
Matroska maker - rewrite file with nested tags
E.........ld-elf.so.1: /usr/local/lib/libc++utilities.so.5: Undefined symbol "libiconv_open"
0% tests passed, 1 tests failed out of 1
Total Test time (real) = 0.01 sec
The following tests FAILED:
1 - tagparser_run_tests (Failed)
Errors while running CTest
FAILED: CMakeFiles/test.util
Version: 12.0.0
FreeBSD 13.2
I'm currently trying to add ReplayGain fields to the library as outlined in adding-new-fields.md. However, as far as I can tell, there's no way to handle multiple TXXX frames in an ID3 tag, as internallyGetKnownField
returns only one value even though there may be several such fields (differing only in their description) according to the ID3 specs.
Am I missing something or does the library currently simply not implement the reading/writing of more than one arbitrary TXXX frame?
When building on Ubuntu 16.10 ,I get the following error:
[100%] Linking CXX shared library libtagparser.so
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libz.a(deflate.o): relocation R_X86_64_PC32 against symbol `z_errmsg' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
CMakeFiles/tagparser.dir/build.make:1630: recipe for target 'libtagparser.so.6.4.0' failed
make[2]: *** [libtagparser.so.6.4.0] Error 1
CMakeFiles/Makefile2:170: recipe for target 'CMakeFiles/tagparser.dir/all' failed
make[1]: *** [CMakeFiles/tagparser.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2
I've checked libz and it is fPICed just fine.
"All text information frames supports multiple strings, stored as a null separated list, where null is reperesented by the termination code for the charater encoding."
So far language/locale specifications are extracted from various formats/places as-is. That means with this information can not be dealt with in a format-independent manner. It would make sense to at least track the format being used. It would also be nice to add functions to convert between the formats like the library currently deals with the different character sets.
Annoyingly Matroska files have 2 ways to specify the language so having multiple native formats needs to be taken into account as well.
How to compile the following examples?
#include <tagparser/mediafileinfo.h>
#include <tagparser/diagnostics.h>
#include <tagparser/progressfeedback.h>
// create a MediaFileInfo for high-level access to overall functionality of the library
auto fileInfo = MediaFileInfo();
// create container for errors, warnings, etc.
auto diag = Diagnostics();
// create handle to abort gracefully and get feedback during during long operations
auto progress = AbortableProgressFeedback([callback for status update], [callback for percentage-only updates]);
// open file (might throw ios_base::failure)
fileInfo.setPath("/path/to/some/file");
fileInfo.open();
// parse container format, tags, attachments and/or chapters as needed
// notes:
// - These functions might throw exceptions derived from ios_base::failure for IO errors and
// populate diag with possibly critical parsing messages you definitely want to check in production
// code.
// - Parsing a file can be expensive if the file is big or the disk IO is slow. You might want to
// run it in a separate thread.
// - At this point the parser does not make much use of the progress object.
fileInfo.parseContainerFormat(diag, progress);
fileInfo.parseTags(diag, progress);
fileInfo.parseAttachments(diag, progress);
fileInfo.parseChapters(diag, progress);
fileInfo.parseEverything(diag, progress); // just use that one if you want all over the above
// get tag as an object derived from the Tag class
// notes:
// - In real code you might want to check how many tags are assigned or use
// fileInfo.createAppropriateTags(…) to create tags as needed.
auto tag = fileInfo.tags().at(0);
// extract a field value and convert it to UTF-8 std::string (toString() might throw ConversionException)
#include <tagparser/tag.h>
#include <tagparser/tagvalue.h>
auto title = tag->value(TagParser::KnownField::Title).toString(TagParser::TagTextEncoding::Utf8);
// change a field value using an encoding suitable for the tag format
tag->setValue(KnownField::Album, TagValue("some UTF-8 string", TagTextEncoding::Utf8, tag->proposedTextEncoding()));
// get/remove/create attachments
#include <tagparser/abstractattachment.h>
if (auto *const container = fileInfo.container()) {
for (auto i = 0, count = container->attachmentCount(); i != count; ++i) {
auto attachment = container->attachment(i);
if (attachment->mimeType() == "image/jpeg") {
attachment->setIgnored(true); // remove existing attachment
}
}
// create new attachment
auto attachment = container->createAttachment();
attachment->setName("cover.jpg");
attachment->setFile(cover, diag);
}
// apply changes to the file on disk
// notes:
// - Might throw exception derived from TagParser::Failure for fatal processing error or ios_base::failure
// for IO errors.
// - Applying changes can be expensive if the file is big or the disk IO is slow. You might want to
// run it in a separate thread.
// - Use progress.tryToAbort() from another thread or an interrupt handler to abort gracefully without leaving
// the file in an inconsistent state.
// - Be sure everything has been parsed before as the library needs to be aware of the whole file structure.
fileInfo.parseEverything(diag, progress);
fileInfo.applyChanges(diag, progress);
TagParser::TagValue(float)
no longer works, was this intentional?
tag->setValue(TagParser::KnownField::Rating, TagParser::TagValue(song.rating()));
/home/jonas/Projects/strawberry/strawberry/ext/libstrawberry-tagreader/tagreadertagparser.cpp: In member function ‘virtual bool TagReaderTagParser::SaveSongRatingToFile(const QString&, const spb::tagreader::SongMetadata&) const’:
/home/jonas/Projects/strawberry/strawberry/ext/libstrawberry-tagreader/tagreadertagparser.cpp:472:87: error: call of overloaded ‘TagValue(float)’ is ambiguous
472 | tag->setValue(TagParser::KnownField::Rating, TagParser::TagValue(song.rating()));
| ^
In file included from /usr/include/tagparser/tag.h:6,
from /home/jonas/Projects/strawberry/strawberry/ext/libstrawberry-tagreader/tagreadertagparser.cpp:30:
/usr/include/tagparser/tagvalue.h:153:5: note: candidate: ‘TagParser::TagValue::TagValue(TagParser::TagValue&&)’
153 | TagValue(TagValue &&other) = default;
| ^~~~~~~~
/usr/include/tagparser/tagvalue.h:152:5: note: candidate: ‘TagParser::TagValue::TagValue(const TagParser::TagValue&)’
152 | TagValue(const TagValue &other);
| ^~~~~~~~
/usr/include/tagparser/tagvalue.h:341:8: note: candidate: ‘TagParser::TagValue::TagValue(uint64_t)’
341 | inline TagParser::TagValue::TagValue(std::uint64_t value)
| ^~~~~~~~~
/usr/include/tagparser/tagvalue.h:333:8: note: candidate: ‘TagParser::TagValue::TagValue(int)’
333 | inline TagValue::TagValue(int value)
| ^~~~~~~~
make[2]: *** [ext/libstrawberry-tagreader/CMakeFiles/libstrawberry-tagreader.dir/build.make:126: ext/libstrawberry-tagreader/CMakeFiles/libstrawberry-tagreader.dir/tagreadertagparser.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:437: ext/libstrawberry-tagreader/CMakeFiles/libstrawberry-tagreader.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
How to solve this problem?
-- Linking tagparser against special library for std::filesystem support is not required.
-- Found required OpenSSL targets (OpenSSL::Crypto)
-- Configuring project tagparser
-- Using default CXX11 ABI of libstdc++ (not forcing old CX11 ABI).
CMake Warning at /usr/local/share/c++utilities/cmake/modules/BasicConfig.cmake:353 (message):
Format rules for clang-format not found.
Call Stack (most recent call first):
CMakeLists.txt:203 (include)
https://github.com/Microsoft/vcpkg
I was wondering if you had any thoughts of making this library available through vcpkg? I'm currently using it for a project of mine but thought it could help spread the use of it if made available more easily.
I'm not that familiar with matroska, so I don't know if there's a defined standard for how they are stored, but would it be possible to have a convenience function for getting the cover (or support for KnownField::Cover in the matroska parser somehow, I guess), instead of checking the attachments manually?
You should probably link https://github.com/Martchus/cpp-utilities directly in your README.md because it's not obvious that you are referring another one of your own repositories when you say that "cpp-utilities" is required for CMake.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.