133 lines
14 KiB
Markdown
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
|
|
|