# mp4-atom _(no submodules)_ ## Purpose Parses iTunes-style metadata from MP4/M4A audio containers by walking the MPEG-4 ISO Base Media box (atom) tree. The parser navigates `moov → udta → meta → ilst` (with a fallback to `moov → meta → ilst` for non-standard files) and decodes all standard iTunes tag atoms into a normalised `Track` record. The implementation is pure binary — it uses no external XML or MP4 libraries, operating directly on a `Uint8Array` with the shared `buffer-utils` helpers. ## Features - Generic box/atom tree walker (`iterBoxes`) with graceful handling of corrupted sizes and EOF-marker boxes - Supports both `moov/udta/meta/ilst` and `moov/meta/ilst` layouts - Decodes UTF-8 text atoms: `©nam`, `©ART`, `©alb`, `aART`, `©day`, `©gen`, `©cmt`, `©lyr` - Parses `trkn` and `disk` integer-pair atoms into `trackNumber / totalTracks` and `discNumber / totalDiscs` - Handles `gnre` numeric genre index (1-based ID3v1 list) and `©gen` free-text genre - Cover art extraction from `covr/data` with MIME-type detection (JPEG=0x0d, PNG=0x0e) - Options: `skipCovers`, `maxCoverSize` ## Usage: Basic Example ```ts import { parseMp4 } from "@suaveplan/audio-metadata/parsers/mp4-atom"; const track = parseMp4(m4aBuffer); console.log(track.title); // "Bohemian Rhapsody" console.log(track.year); // 1975 ``` ## Usage: Advanced Example ```ts import { parseMp4 } from "@suaveplan/audio-metadata/parsers/mp4-atom"; const track = parseMp4(m4aBuffer, { skipCovers: false, maxCoverSize: 1024 * 1024, // 1 MiB limit }); if (track.cover) { console.log(track.cover.mimeType); // "image/jpeg" or "image/png" console.log(track.cover.data.length); // bytes } ``` ## API Reference ### `parseMp4(buffer, options?)` ```ts function parseMp4( buffer: Uint8Array, options?: { skipCovers?: boolean; maxCoverSize?: number; }, ): Track ``` | Parameter | Type | Description | |-----------|------|-------------| | `buffer` | `Uint8Array` | Full MP4/M4A file buffer | | `options.skipCovers` | `boolean` | Skip cover art extraction | | `options.maxCoverSize` | `number` | Maximum cover bytes to accept (default 5 MiB) | **Returns:** `Track` object; `{}` if no `ilst` atom is found. ## Implementation Notes Each MP4 box starts with a 4-byte big-endian size (including the 8-byte header) followed by a 4-byte ASCII type code. A size of `0` means the box extends to the end of the file; a size of `1` means a 64-bit extended size follows — 64-bit boxes are skipped because they are not used for metadata in practice. The `meta` box includes a 4-byte version+flags prefix before its children, which `parseMp4` skips by advancing `dataOffset + 4` before searching for `ilst`. The `©` prefix in atom names (Unicode U+00A9) matches the raw Latin-1 byte `0xa9` written by all major encoders. Track/disc number parsing reads a 6-byte big-endian structure: 2 bytes padding, 2 bytes number, 2 bytes total.