3.3 KiB
id3v1
(no submodules)
Purpose
Parses the 128-byte ID3v1 and ID3v1.1 tag that lives at the very end of an MP3 file. ID3v1 is the oldest and most widely supported tag format; while its fixed-length fields and limited character encoding make it inferior to ID3v2, it remains prevalent in older libraries and legacy rips.
The parser returns a Track object with normalised fields and a rawTags map so callers can inspect the original values before transformation.
Features
- Detects presence of the "TAG" magic marker at
buffer.length - 128 - Reads title (30 bytes), artist (30 bytes), album (30 bytes), year (4 bytes), comment (28–30 bytes), and genre index (1 byte)
- Implements the ID3v1.1 track-number extension: if comment byte 28 is
0x00and byte 29 is non-zero, byte 29 is the track number - Maps the genre byte to the 192-entry Winamp-extended genre list
- Strips trailing null bytes and ASCII whitespace from every field
- Returns an empty
Trackwhen the tag is absent or the buffer is shorter than 128 bytes
Usage: Basic Example
import { parseId3v1 } from "@suaveplan/audio-metadata/parsers/id3v1";
const buf = new Uint8Array(256);
// write "TAG" at offset 128
buf[128] = 0x54; buf[129] = 0x41; buf[130] = 0x47;
// write title "My Song"
const enc = new TextEncoder();
enc.encodeInto("My Song", buf.subarray(131));
const track = parseId3v1(buf);
// { title: "My Song", format: "id3v1", ... }
Usage: Advanced Example
import { parseId3v1 } from "@suaveplan/audio-metadata/parsers/id3v1";
// Build a minimal ID3v1.1 buffer with track number
const buf = new Uint8Array(128);
buf[0] = 0x54; buf[1] = 0x41; buf[2] = 0x47; // "TAG"
new TextEncoder().encodeInto("Dark Side", buf.subarray(3, 33)); // title
new TextEncoder().encodeInto("Pink Floyd", buf.subarray(33, 63)); // artist
new TextEncoder().encodeInto("The Wall", buf.subarray(63, 93)); // album
new TextEncoder().encodeInto("1979", buf.subarray(93, 97)); // year
// comment bytes 28=0, 29=track number
buf[125] = 0x00;
buf[126] = 3; // track 3
buf[127] = 17; // Rock genre
const track = parseId3v1(buf);
console.log(track.artist); // "Pink Floyd"
console.log(track.trackNumber); // 3
console.log(track.genre); // "Rock"
API Reference
parseId3v1(buffer)
function parseId3v1(buffer: Uint8Array): Track
| Parameter | Type | Description |
|---|---|---|
buffer |
Uint8Array |
Full audio file buffer (must be ≥ 128 bytes for a tag to be present) |
Returns: A Track object. All fields are optional; an empty Track ({}) is returned when no ID3v1 tag is found.
Does not throw. Out-of-bounds buffers and missing tags produce an empty result.
Implementation Notes
Latin-1 encoding is used for all field reads because the ID3v1 specification predates UTF-8 adoption in audio tags; using TextDecoder("utf-8") would corrupt characters in the 0x80–0xFF range. The ID3v1.1 track-number detection checks byte offsets 28 and 29 of the comment region (absolute offsets 125 and 126 from the tag start), consistent with the de-facto standard introduced by Michael Mutschler in 1997. Null-termination stripping uses a regex to remove all trailing \0 characters before trimming whitespace, because some encoders pad fields with spaces rather than nulls.