TIKA-4838: Expose the MP4 audio and video track codecs as FourCCs (audio:fourcc, video:fourcc) - #3062
Conversation
5452bf9 to
cc7b684
Compare
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Expose MP4/QuickTime track codec FourCCs as audio:format and video:format, including recovery of original codecs for protected streams via nested frma boxes.
Changes:
- Add new
Audio.FORMATandVideo.FORMATmetadata properties and register schema keys. - Populate
audio:format/video:formatfrom sample description entries, withfrmafallback for protected streams. - Add parser tests asserting the new metadata for audio-only and video+audio MP4s.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tika-parsers/.../MP4ParserTest.java | Adds assertions/tests for audio:format and video:format. |
| tika-parsers/.../TikaMp4VideoHandler.java | Extracts video codec FourCC and recovers original FourCC for protected video streams. |
| tika-parsers/.../TikaMp4SoundHandler.java | Extracts audio codec FourCC and recovers original FourCC for protected audio streams. |
| tika-metadata-schema/.../metadata-keys.json | Registers audio:format and video:format keys. |
| tika-metadata-schema/.../metadata-key-fields.json | Maps Audio.FORMAT/Video.FORMAT fields to the new keys. |
| tika-core/.../Video.java | Adds Video.FORMAT property with Javadoc. |
| tika-core/.../Audio.java | Adds Audio.FORMAT property with Javadoc. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
… video:format) TikaMp4SoundHandler/TikaMp4VideoHandler read the sample-entry format fourcc but only use it for other purposes (audio: DRM detection; video: nothing). Expose it as audio:format and video:format, each the track's four-character codec identifier (e.g. mp4a/alac/ac-3, avc1/hev1). This gives the per-track codec for video/* files, where xmpDM:audioCompressor does not fire and xmpDM:videoCompressor carries the compressor name. For protected streams the value is the protection scheme fourcc (drms/enca/encv/drmi); audio also sets audio:has-drm. Follows TIKA-4779, TIKA-4800 and TIKA-4802.
cc7b684 to
957f037
Compare
…ormats, not protection schemes
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
tika-core/src/main/java/org/apache/tika/metadata/Audio.java:92
- The Javadoc says
XMPDM#AUDIO_COMPRESSORis a “human-readable codec name”, but in MP4 parsing it is set from the file’s major brand (e.g., "M4A"), which is not the track codec. Please reword to avoid misrepresenting whatAUDIO_COMPRESSORcontains here.
* Distinct from {@link XMPDM#AUDIO_COMPRESSOR}, the human-readable codec name.
|
From my claude: Let me know what you think. |
Address review: move the sample entry loop into Mp4SampleEntries, shared by the sound and video handlers, handling size 0 (to end of box) and size 1 (largesize). Only expose a format fourcc when it is printable ASCII, with QuickTime's trailing padding spaces trimmed. Drop the misleading cross-ref to xmpDM:audioCompressor/videoCompressor, restore the ISO common encryption anchor on the enca comment and trim the test comment.
…deo:fourcc The value is the codec's four-character code, not a generic format name, and FourCCs are not MP4-specific (QuickTime, AVI and others use them), so expose them as audio:fourcc / video:fourcc and say so in the javadoc.
…om sinf/frma A protected entry (drms/enca/encv/drmi) keeps its original codec in the ProtectionSchemeInfoBox's OriginalFormatBox (ISO/IEC 14496-12, 8.12), so report that as the fourcc and leave the DRM fact to audio:has-drm; only a bare entry without sinf still reports the protected format itself. Synthetic fixtures built per the spec and FFmpeg's/GPAC's writers: testMP4_drm_frma.m4a (FairPlay drms with esds and sinf/frma mp4a), testMP4_encv.mp4 (testMP4Video.mp4 with an encv entry, sinf before btrt), testMP4_twoSampleEntries.m4a (mp4a then ac-3, guards last-entry-wins).
|
Thanks, all addressed:
Not sure which item 4 was, happy to look if you paste it. |
A header-only frma (size 8) passed the entry-bound check and read its format from the following box.
Adds
audio:fourccandvideo:fourcc, each the track's codec as a four-character code from the MP4/QuickTime sample description (audio:mp4a/alac/ac-3; video:avc1/hev1).TikaMp4SoundHandler/TikaMp4VideoHandleralready read the sample-entry fourcc (audio uses it to detectdrms/encaprotected streams; video ignored it); this exposes it as metadata. Because it comes from the track, both are set forvideo/*files, wherexmpDM:audioCompressordoes not fire andxmpDM:videoCompressorcarries the compressor name (encoder string, e.g. "Lavc… libx264"), not the codec fourcc. The stsd walk is shared between the handlers (Mp4SampleEntries), handling size 0 and largesize entries, and a fourcc is only exposed when it is printable ASCII, with QuickTime's trailing padding trimmed.For protected streams (
drms/enca/encv/drmi) the value is the original codec named by the protection scheme info (sinf/frma); a bare entry withoutsinfreports the protected format itself. Audio additionally setsaudio:has-drm. Both are per-stream values: with several tracks or sample entries they reflect the last one, likeaudio:bitrate/video:bitrate.Verified against an M4A (
mp4a), avideo/mp4with H.264 video + AAC audio (avc1+mp4a), a DRM-protected M4A withoutsinf(drms), and synthetic fixtures built per ISO/IEC 14496-12 8.12: a FairPlaydrmsentry withsinf/frma(mp4a), anencventry withsinf/frma(avc1), and a track with two sample entries (mp4athenac-3); metadata schema registries updated.https://issues.apache.org/jira/browse/TIKA-4838
Follows TIKA-4779, TIKA-4800 and TIKA-4802.