[
https://issues.apache.org/jira/browse/TIKA-4779?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18096197#comment-18096197
]
ASF GitHub Bot commented on TIKA-4779:
--------------------------------------
dschmidt opened a new pull request, #2953:
URL: https://github.com/apache/tika/pull/2953
Part 2 of TIKA-4779, following up on #2947 with the three audio properties
that need parser work rather than plain mapping: `audio:bitrate` (average, bits
per second), `audio:is-variable-bitrate` and `audio:has-drm`, defined under
Tika's own namespace in `Audio.java`.
**MP3:** the parser already walks every audio frame for the duration, and
since frame duration does not depend on the bitrate, the plain mean over the
frames is the exact average and differing frame bitrates are an exact VBR
signal. The one special case is the Xing/Info/VBRI tag frame some encoders
write first: it is a valid MPEG frame without audio, often at a different
bitrate than the stream, so it is detected and excluded (a CBR file with an
Info tag would otherwise be misreported as VBR, there is a fixture proving
exactly that). I deliberately did not go the usual route of reading the bitrate
from the Xing table itself: the full frame walk already happens for the
duration, so the exact mean is free and works for files without any tag frame.
**Vorbis:** the identification header declares upper/nominal/lower rates.
Nominal maps to `audio:bitrate`; a zero-width bracket (upper == lower, no
nominal) also pins an exact rate. Fixed rate means all three declared rates
agree, or only a zero-width bracket is declared; anything else counts as
variable.
**MP4/M4A:** a `TikaMp4SoundHandler` (same extension pattern as TIKA-2861)
structurally walks the sample description entries. Protected sample entry
formats (`drms`, `enca`) set `audio:has-drm`; these markers are readable by
design since DRM encrypts the payload, not the metadata. The average bitrate
comes from the esds elementary stream descriptor, located as a child box of the
entry (honoring the version-dependent entry layout, QuickTime `wave` wrappers
and the optional ES descriptor fields). I deliberately avoided scanning the
stsd bytes for fourcc markers: codec private data or a URL field can legally
contain the string `sinf`, and a fixture covers that false positive.
For files with several audio tracks the properties reflect the last sound
track's sample description, consistent with how the existing MP4 audio metadata
behaves.
Note: the `hdlr` dispatch hook in `TikaMp4BoxHandler` overlaps with #2936;
whichever merges second has a trivial rebase.
Tests run against real files where the repo has them (`testMP4.m4a` with a
declared average of 256000, the constant bitrate MP3 fixtures, `testVORBIS.ogg`
copied from the integration tests). Synthetic fixtures cover only what no real
specimen exercises: a VBR MP3, a CBR MP3 with an Info tag frame, a `drms`
protected M4A and an M4A whose ES descriptor uses the optional fields.
> Audio parsers do not expose total track count (trackCount)
> ----------------------------------------------------------
>
> Key: TIKA-4779
> URL: https://issues.apache.org/jira/browse/TIKA-4779
> Project: Tika
> Issue Type: Improvement
> Reporter: Dominik Schmidt
> Priority: Major
>
> Tika does not expose the "total number of tracks on the album" for audio
> files, even though all common audio container formats carry this information
> and the parsers partially already read it.
> *Background*
> Audio metadata is mapped onto the XMP Dynamic Media schema ({{{}XMPDM{}}}),
> which defines {{xmpDM:trackNumber}} but has no property for the total track
> count. Since XMPDM cannot be extended upstream, Tika never picked up the
> value - but the information is present in the files:
> * *MP4/M4A:* the {{trkn}} atom contains two integers, track number and total
> track count. {{TikaUserDataBox.processIList()}} reads *both* values but only
> sets the first one and silently discards the second ({{{}numB{}}} is read and
> never used):
> {code:java}
> } else if ("trkn".equals(fieldName)) {
> if (toRead == 8) {
> long numA = reader.getUInt32();
> long numB = reader.getUInt32(); // total track count — discarded
> metadata.set(XMPDM.TRACK_NUMBER, (int)numA);
> }
> {code}
> (tika-parser-audiovideo-module,
> {{{}org.apache.tika.parser.mp4.boxes.TikaUserDataBox{}}})
> * *MP3/ID3v2:* the {{TRCK}} frame commonly has the form {{{}"3/12"{}}}. All
> ID3 handlers
> ({{{}ID3v22Handler{}}}/{{{}ID3v23Handler{}}}/{{{}ID3v24Handler{}}}) pass the
> raw string through, so the total ends up *embedded* in {{xmpDM:trackNumber}}
> as {{"3/12"}} — even though that property is declared
> {{{}externalInteger{}}}. The same applies to {{TPOS}} → {{xmpDM:discNumber}}
> (see {{{}Mp3ParserTest{}}}, which asserts {{"1/1"}} for discNumber). So for
> MP3 the value leaks through unstructured instead of being exposed as a proper
> field.
> * *OGG/FLAC:* the Vorbis comment {{TRACKTOTAL}} is not mapped at all
> ({{{}OggAudioParser{}}} only sets {{{}XMPDM.TRACK_NUMBER{}}}).
> *Proposal*
> # Introduce a property for the total track count. Since {{xmpDM}} has no
> such field, either a Tika-owned property (e.g. in a {{tika:}} namespace) or a
> documented non-standard extension.
> # Populate it in the three parsers: MP4 ({{{}numB{}}} from {{{}trkn{}}}),
> MP3 (split {{TRCK}} on {{{}"/"{}}}), OGG/FLAC ({{{}TRACKTOTAL{}}}).
> # While at it, consider normalizing {{xmpDM:trackNumber}} /
> {{xmpDM:discNumber}} to the plain number so the values actually conform to
> their declared integer type (possibly keeping the raw value elsewhere for
> backwards compatibility). Anyhow before 4.0.0 is about as good as timing can
> be for a breaking change
> The analogous question applies to the disc count ({{{}TPOS{}}} total, MP4
> {{disk}} atom second value).
> Willing to work on this, just let me know, how you would like to have it
> solved. Especially the property names.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)