Files
skills/docs/media/audio/audio-metadata/README.md
2026-05-29 08:20:56 +01:00

133 lines
14 KiB
Markdown

# @suaveplan/audio-metadata - Universal audio metadata extractor: parses ID3v1/v2, MP4/M4A atoms, FLAC Vorbis comments, Ogg, WAV, AIFF, and returns a normalised Track record.
## Summary
Universal audio metadata extractor that parses ID3v1/v2, MP4/M4A atoms, FLAC Vorbis comments, Ogg Vorbis, WAV RIFF, and AIFF/AIFC containers, returning a normalised `Track` record. Works in both Node.js and browser environments — zero native dependencies.
<!-- begin:auto-docs -->
## Documentation tree
- [extractor](./src/core/extractor/extractor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [extractor](./src/core/extractor/extractor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [metadata-error](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [buffer-utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
<!-- end:auto-docs --> - [extractor](./src/core/extractor/extractor.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [metadata-error](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_- [utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [buffer-utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [extractor](./src/core/extractor/extractor.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [metadata-error](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_- [utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [buffer-utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [extractor](./src/core/extractor/extractor.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [metadata-error](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_- [utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [buffer-utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [extractor](./src/core/extractor/extractor.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_ - [metadata-error](./src/errors/metadata-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_ - [aiff-id3](./src/parsers/aiff-id3/aiff-id3.md) — <!-- begin:auto-docs --> _(no submodules)_- [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_ - [flac-vorbis](./src/parsers/flac-vorbis/flac-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_ - [format-detector](./src/parsers/format-detector/format-detector.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_ - [id3v1](./src/parsers/id3v1/id3v1.md) — <!-- begin:auto-docs --> _(no submodules)_- [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_ - [id3v2](./src/parsers/id3v2/id3v2.md) — <!-- begin:auto-docs --> _(no submodules)_- [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_ - [mp4-atom](./src/parsers/mp4-atom/mp4-atom.md) — <!-- begin:auto-docs --> _(no submodules)_- [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_ - [ogg-vorbis](./src/parsers/ogg-vorbis/ogg-vorbis.md) — <!-- begin:auto-docs --> _(no submodules)_- [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_ - [wav-riff](./src/parsers/wav-riff/wav-riff.md) — <!-- begin:auto-docs --> _(no submodules)_- [utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_ - [buffer-utils](./src/utils/buffer-utils.md) — <!-- begin:auto-docs --> _(no submodules)_
## Installation
```bash
bun add @suaveplan/audio-metadata
```
## Quick Start
```ts
import { extractMetadata } from "@suaveplan/audio-metadata";
// From a Uint8Array (e.g. via fetch or FileReader)
const response = await fetch("/song.mp3");
const buffer = new Uint8Array(await response.arrayBuffer());
const track = await extractMetadata(buffer);
console.log(track.title); // "Come Together"
console.log(track.artist); // "The Beatles"
console.log(track.album); // "Abbey Road"
console.log(track.year); // 1969
console.log(track.format); // "id3v2"
```
## Supported Formats
| Format | Detection | Tags |
|--------|-----------|------|
| MP3 with ID3v2.2/2.3/2.4 | Header magic `ID3` | Full tag set + cover art |
| MP3 with ID3v1/1.1 | Trailer magic `TAG` | Fixed 128-byte fields |
| MP4/M4A | `ftyp`/`moov` atom | iTunes ilst atoms |
| FLAC | `fLaC` magic | Vorbis comments + stream info |
| Ogg Vorbis | `OggS` magic | Vorbis comment packet |
| WAV | `RIFF`+`WAVE` magic | LIST INFO chunks |
| AIFF/AIFC | `FORM`+`AIFF/AIFC` | Embedded ID3 chunk |
## API
### `extractMetadata(buffer, options?)`
Module-level convenience function. Returns a `Promise<Track>`.
### `MetadataExtractor` (class)
Singleton facade with multiple entry points:
- `extractFromBuffer(Uint8Array, options?): Promise<Track>`
- `extractFromArrayBuffer(ArrayBuffer, options?): Promise<Track>`
- `extractFromFile({ arrayBuffer(): Promise<ArrayBuffer> }, options?): Promise<Track>`
- `extractAudioMetadata(Uint8Array, options?): Promise<AudioMetadata>`
### Options
```ts
interface MetadataExtractionOptions {
skipCovers?: boolean; // Skip cover art. Default: false
maxCoverSize?: number; // Max cover bytes. Default: 5 MiB
skipLyrics?: boolean; // Skip lyrics. Default: false
}
```
### Track shape
```ts
interface Track {
title?: string;
artist?: string;
album?: string;
albumArtist?: string;
year?: number;
trackNumber?: number;
totalTracks?: number;
discNumber?: number;
totalDiscs?: number;
genre?: string;
comment?: string;
lyrics?: string;
cover?: { data: Uint8Array; mimeType: string; description?: string };
duration?: number; // seconds
bitrate?: number; // kbps
sampleRate?: number; // Hz
channels?: number;
format?: AudioFormat;
rawTags?: Record<string, string | string[]>;
}
```
## Module docs
- [`src/utils/buffer-utils.md`](src/utils/buffer-utils.md) — Binary read helpers
- [`src/parsers/format-detector/format-detector.md`](src/parsers/format-detector/format-detector.md) — Format detection
- [`src/parsers/id3v1/id3v1.md`](src/parsers/id3v1/id3v1.md) — ID3v1/1.1 parser
- [`src/parsers/id3v2/id3v2.md`](src/parsers/id3v2/id3v2.md) — ID3v2.2/2.3/2.4 parser
- [`src/parsers/mp4-atom/mp4-atom.md`](src/parsers/mp4-atom/mp4-atom.md) — MP4/M4A atom parser
- [`src/parsers/flac-vorbis/flac-vorbis.md`](src/parsers/flac-vorbis/flac-vorbis.md) — FLAC + Vorbis comments
- [`src/parsers/ogg-vorbis/ogg-vorbis.md`](src/parsers/ogg-vorbis/ogg-vorbis.md) — Ogg Vorbis parser
- [`src/parsers/wav-riff/wav-riff.md`](src/parsers/wav-riff/wav-riff.md) — WAV RIFF INFO parser
- [`src/parsers/aiff-id3/aiff-id3.md`](src/parsers/aiff-id3/aiff-id3.md) — AIFF/AIFC + ID3 parser
- [`src/core/extractor/extractor.md`](src/core/extractor/extractor.md) — MetadataExtractor facade
- [`src/errors/metadata-error.md`](src/errors/metadata-error.md) — Error codes