Commit Graph

603 Commits

Author SHA1 Message Date
Urs Fleisch
78c7208bc9 Integrate MP4 chapters into MP4::File 2026-04-23 11:03:23 -07:00
Ryan Francesconi
ba2441b378 corrected nanosecond unit change -> milliseconds
taglib/mp4/mp4chapterlist.h
• start​Time doc comment: 100​-nanosecond units → milliseconds

taglib/mp4/mp4chapterlist.cpp
• render​Chpl​Data: from​Long​Long(ch​.start​Time) → from​Long​Long(ch​.start​Time * 10000​LL)
• parse​Chpl​Data: ch​.start​Time = start​Time → ch​.start​Time = start​Time100ns / 10000​LL

taglib/mp4/mp4qtchapterlist.cpp
• read: current​Time * 10000000​.0 / timescale → current​Time * 1000​.0 / timescale
• build​Stts lambda: time100ns * timescale / 10000000​.0 → time​Ms * timescale / 1000​.0

tests/test_mp4.cpp
• All start​Time assignments and assertions divided by 10,000 (e.g. 300000000​LL → 30000​LL)
2026-04-23 11:03:23 -07:00
Ryan Francesconi
c5ea13bb34 overloads for read, write, remove
Changes made

mp4chapterlist.h
• Added (​MP4::​File*) overloads for read, write, remove
• Replaced broken class ​File; forward declaration with #include "mp4file​.h" (fixed a subtle C++ name-resolution linker bug where Atoms(​File*) resolved to MP4::​File* instead of Tag​Lib::​File*)

mp4chapterlist.cpp
• Refactored: path-based overloads are now thin wrappers that delegate to file-based overloads
• File-based overloads construct Atoms locally — no Atoms* in the public API
• Removed chpl​Header​Size = 9 constant; replaced the minimum-size guard in parse​Chpl​Data with a correct 5-byte check (the old constant was version-1 specific and would reject valid version-0 atoms)

mp4qtchapterlist.h
• Added (​MP4::​File*) overloads for read, write, remove
• Removed Atoms* parameters entirely from the public API

mp4qtchapterlist.cpp
• Same refactor: path-based overloads delegate; file-based overloads construct Atoms locally
• Added empty-chapter guard: write(​MP4::​File*, {}) delegates to remove(file) instead of writing a 0-sample chapter track

tests/test_mp4.cpp
• Added test​Chapter​List​File​API and test​QTChapter​List​File​API — exercise the full write/read/remove cycle via the file-based API
• Updated test bodies to use the simplified (​MP4::​File*) API (no MP4::​Atoms construction in test code)
2026-04-23 11:03:23 -07:00
Ryan Francesconi
4a73d73b20 MP4: Add QuickTime-style chapter track support
QuickTime-style chapter tracks are the native chapter format for
Apple's ecosystem. They use a disabled text track (hdlr type "text")
referenced by a chap track-reference in the audio track's tref box.
This format is recognized by QuickTime, iTunes/Music, Final Cut Pro,
Logic Pro, DaVinci Resolve, VLC, and most other MP4/M4A players. It
is also the format that AVFoundation reads natively via
AVAssetChapterMetadataGroup.

The implementation produces output that matches ffmpeg's chapter track
structure byte-for-byte: per-sample stts entries (required by
AVFoundation), encd atoms for UTF-8 text encoding, edts/elst edit
lists, gmhd with gmin+text media information, and disabled tkhd flags
(track_in_movie only).

Key behaviors:
- write() inserts tref + chapter trak as a single contiguous block,
  then appends text samples in an mdat atom at EOF
- Handles non-zero first chapter times by prepending a dummy chapter
  at time 0 (stripped on read)
- Overwrite support: removes existing chapter track before writing
- Preserves existing metadata tags and audio data integrity
- Uses timescale=1000 (milliseconds) for chapter track timing

7 new tests covering write/read round-trip, remove, overwrite, tag
preservation, empty file read, timestamp precision, and non-zero
first chapter handling.
2026-04-23 11:03:23 -07:00
Ryan Francesconi
9c56f191e5 MP4: Add Nero-style chapter marker support
Implement read/write/remove of Nero-style chapter markers (chpl atom)
in MP4 files. The chpl atom lives at moov/udta/chpl, storing up to 255
chapter entries with 100-nanosecond timestamps and UTF-8 titles.

Includes CppUnit tests covering round-trip read/write, remove, tag
preservation, and reading from files with no chapters.
2026-04-23 11:03:23 -07:00
Ryan Francesconi
d6a2134cf3 Clamp oversized RIFF chunk to available bytes instead of rejecting it (#1329)
Some encoders write a valid data chunk but with a slightly too-large
declared chunkSize, or place the data chunk beyond the declared RIFF
boundary. The previous behaviour called break, abandoning all remaining
chunks and making the file appear empty to taglib.

Lenient parsers (ffmpeg, QuickTime) handle this case by clamping the
chunk size to the bytes that actually remain in the file. Adopt the
same strategy: when chunkSize would exceed the file length, clamp it
and continue parsing rather than stopping early.
2026-04-04 12:47:49 +02:00
Ryan Francesconi
abadbb6768 Add BEXT and iXML chunk support to WAV files (#1323)
Read, write, and remove Broadcast Audio Extension (BEXT, EBU Tech 3285)
and iXML metadata chunks in WAV files. BEXT is widely used in broadcast
and professional audio for originator, description, time reference, and
loudness metadata. iXML is used by field recorders and DAWs for scene,
take, and track metadata.
2026-04-04 12:14:34 +02:00
Daniel
49510e7d5a Move MPEG check to end of content-based detection (#1319)
MPEG::File::isSupported() scans for frame sync bytes that can appear
in other files, causing them to be misidentified as MP3.

This also includes a test with such a file.
2026-04-04 08:01:41 +02:00
Daniel
7f2f2ddcaf Add tests for FileRef content-based detection via ByteVectorStream (#1318)
This covers all 18 formats supported by the content-based detection.
2026-04-04 07:43:56 +02:00
Felipe
9411bb161f Opus: Read output gain (#1320) 2026-03-31 11:14:44 -05:00
Urs Fleisch
3db0d48f4b Support edition, chapter and attachment UIDs in Matroska simple tags (#1311) 2026-02-24 06:53:23 +01:00
Stephen Booth
397b6c1de3 Add check for ID3v2 frame data length (#1300)
Also fix some wrong frame sizes in the unit tests.

---------

Co-authored-by: Urs Fleisch <ufleisch@users.sourceforge.net>
2026-01-31 08:24:54 +01:00
Stephen Booth
51f431c96a Verify the ID3v2 version and revision are not 0xFF (#1301) 2026-01-31 08:21:17 +01:00
Antoine Colombier
11e3eb05bd MP4: Add support for NI STEM (#1299) 2026-01-25 13:33:54 +01:00
Urs Fleisch
f4e7a742c3 Improve Matroska API
Make AttachedFile immutable. This is consistent with SimpleTag and
Chapter and avoids using attached files which do not have all required
attributes.
Provide methods to insert and remove a single simple tag, so that
they can be modified without setting all of them while still not
exposing internal lists to the API.
Use DATE_RECORDED instead of DATE_RELEASED for year() and the "DATE"
property. This is more consistent with other tag formats, e.g. for ID3v2
"TDRC" is used, which is the recording time.
2026-01-24 14:59:10 +01:00
Urs Fleisch
68a514f4a0 Matroska: Avoid inlined header methods, only install public headers 2026-01-24 14:59:10 +01:00
Urs Fleisch
607cd5bdf4 Matroska: Fix issues reported by static analysis, formatting, docs 2026-01-24 14:59:10 +01:00
Urs Fleisch
b625be5690 Support for Matroska chapters 2026-01-24 14:59:10 +01:00
Urs Fleisch
d2bf7e72d2 Unit tests for Matroska 2026-01-24 14:59:10 +01:00
Urs Fleisch
6fa3db1e51 C bindings, fileref, fix warnings 2026-01-24 14:59:10 +01:00
norma
e831f0929f Fix Unicode property keys in C bindings
The C bindings would convert a char* to String using the default
constructor, which uses the Latin1 encoding, breaking when a key
contains a Unicode character (e.g. an ID3v2 comment description).
2025-07-04 09:43:34 +02:00
Urs Fleisch
148cc9a921 Fix conversion compiler warnings
Using a release build with GCC 14.2.0 and -Wextra -Wconversion -Wall.
The generated binaries are not changed by this commit.
2025-06-25 22:08:09 +02:00
Urs Fleisch
88d6b18b4f Convert IPLS to TIPL and TMCL (#1274)
The involvement/involvee pairs which are supported for TIPL properties
(ARRANGER, ENGINEER, PRODUCER, DJ-MIX, MIX) are left in the TIPL
frame, other pairs are moved to a TMCL frame. This will result in a
consistent behavior for both ID3v2.3 and ID3v2.4 tags produced by
MusicBrainz Picard.
2025-06-21 10:45:43 +02:00
Urs Fleisch
d61a333f27 Map lowercase MusicBrainz TIPL keys to properties (#1274) 2025-06-21 10:45:43 +02:00
Urs Fleisch
fbbead3efd Support custom temp and tests directories (#1268) (#1270)
The following user-settable values for CMake are supported:

- TESTS_DIR: Tests directory, is path to unit test data when 'data' is
  appended. Can be used to run the unit tests on a target.
- TESTS_TMPDIR: Directory for temporary files created during unit tests,
  system tmpdir is used if undefined. Has to be defined on systems
  without global temporary directory.
2025-05-01 19:55:46 +02:00
Urs Fleisch
ee1931b811 Compile time configuration of supported formats (#1262)
CMake options WITH_APE, WITH_ASF, WITH_DSF, WITH_MOD, WITH_MP4,
WITH_RIFF, WITH_SHORTEN, WITH_TRUEAUDIO, WITH_VORBIS, by default,
they are all ON.
2025-02-02 12:24:26 +01:00
Stephen Booth
648f5e5882 Add Shorten (SHN) support (#1257)
* Add Shorten (SHN) support

* Add `<cmath>` include and use `std::log2`

* Use `uintptr_t` for buffer size calculations

* Work around `byteSwap` not using fixed width types

* Remove four-character codes

* Attempt to fix `static_assert`

* Revert previous commit

* Update `read_uint`* functions

* Use ByteVector for byte swaps

* Use different ByteVector ctor

* Rework variable-length input to use ByteVector

* Rename some variables

* Naming and formatting cleanup

* Add basic Shorten tests

* Rename a constant

* Rename `internalFileType` to `fileType`

* Add documentation on `fileType` meaning

* Add DO_NOT_DOCUMENT guard

* Fix shadowVariable issues reported by cppcheck

cppcheck --enable=all --inline-suppr \
  --suppress=noExplicitConstructor --suppress=unusedFunction \
  --suppress=missingIncludeSystem --project=compile_commands.json

* Formatting cleanup

* More explicit types

Reason for these changes: getRiceGolombCode(k, uInt32CodeSize) was
called with int k for uint32_t& argument.
There was also a warning from MSVC for line 299:
warning C4267: 'argument': conversion from 'size_t' to 'int'

* Additional explicit types

* Rename `SHN` namespace to `Shorten`

Also rename files to match

---------

Co-authored-by: Urs Fleisch <ufleisch@users.sourceforge.net>
2024-12-30 07:23:11 -06:00
Urs Fleisch
5b6f9ef848 Fix segfaults with String and ByteVector nullptr arguments (#1247) (#1248) 2024-11-02 06:39:21 +01:00
Urs Fleisch
cbe54d2f40 Support free form tags with MP4 properties (#1239) (#1240) 2024-07-29 20:24:33 +02:00
Stephen Booth
f3fb4d83a4 Skip unknown MP4 boxes (#1231) 2024-05-18 06:45:10 +02:00
Urs Fleisch
3d4428726e Fix parsing of ID3v2.2 frames (#1228) 2024-05-18 06:43:00 +02:00
Urs Fleisch
59ff35772e Fix building with -DBUILD_TESTING=ON -DBUILD_BINDINGS=OFF 2024-03-25 20:14:19 +01:00
Urs Fleisch
3784628155 Provide equal operator for MP4::Item
This is needed to generate MP4::ItemMap bindings with SWIG.
2024-03-25 20:13:55 +01:00
Rosen Penev
89af92333c clang-tidy: use dynamic_cast
Found with cppcoreguidelines-pro-type-static-cast-downcast

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-22 18:35:30 +01:00
Urs Fleisch
e49390c7c5 Inspection: Type can be replaced with auto 2024-01-21 20:46:27 +01:00
Urs Fleisch
7bcfb96098 Inspection: Code redundancies 2024-01-21 20:46:27 +01:00
Urs Fleisch
580b0b0c82 Inspection: Possibly unused #include directive 2024-01-21 20:46:27 +01:00
Urs Fleisch
570b40bdcd Inspection: Polymorphic class with non-virtual public destructor 2024-01-21 20:46:27 +01:00
Urs Fleisch
613355665c Inspection: Variable can be moved to inner scope 2024-01-21 20:46:27 +01:00
Urs Fleisch
5d921c6325 Inspection: Variable can be made constexpr 2024-01-21 20:46:27 +01:00
Urs Fleisch
b4f77a4d52 Inspection: Member function can be made const 2024-01-21 20:46:27 +01:00
Urs Fleisch
c907d8b273 Inspection: Functional-style cast is used instead of a C++ cast 2024-01-21 20:46:27 +01:00
Urs Fleisch
98175168f3 Inspection: Declaration and assignment can be joined 2024-01-21 20:46:27 +01:00
Urs Fleisch
73aff544b3 Inspection: C-style cast is used instead of a C++ cast 2024-01-21 20:46:27 +01:00
Rosen Penev
c2eb6b59b5 clang-tidy: avoid endl
Found with performance-avoid-endl

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Urs Fleisch
0318201fbd Make classes with destructor as only virtual member non-virtual
These classes are probably not meant to be used polymorphically.
2024-01-17 21:25:44 +01:00
Urs Fleisch
ef013b76db Add checks for the expected sizes of new public classes 2024-01-02 14:16:22 +01:00
Urs Fleisch
7dc8bfc806 Fix property mappings
For MP4 map ENCODEDBY to ©enc instead of ©too, which is now mapped to
ENCODING.
For ASF, add new properties ENCODINGTIME (WM/EncodingTime) and FILEWEBPAGE
(WM/AudioFileURL).
2023-12-24 08:42:15 +01:00
Urs Fleisch
56fa36934e Unify File constructors with ID3v2::FrameFactory parameter (#1196)
Make constructors consistent so that the FrameFactory is at the
end and optional. Mark the alternative constructors as deprecated.
2023-12-22 13:41:13 +01:00
Urs Fleisch
0dff3150c1 Remove UTF16LE means swap compatibility hack 2023-12-22 13:40:56 +01:00