id3v2

package
v0.0.0-...-d95e946 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package id3v2 reads and writes ID3v2.2, v2.3, and v2.4 tags (the variable-length block at the start of an MP3 file marked with "ID3").

Reading

Read parses any of the three supported revisions; v2.2 frame IDs are normalised to their canonical 4-character v2.3/2.4 equivalents when known, so callers always look frames up by the modern names (e.g. "TIT2", "APIC"). Tag-level unsynchronisation is undone transparently. The extended header (v2.3 / v2.4) is skipped on read and not preserved on write.

Writing

Encode emits a tag at t.Version. V23 and V24 are first-class; V22 is also supported but the writer errors out on any frame whose canonical 4-character ID has no v2.2 equivalent (PRIV, TSO2 and other v2.4-only fields). The default Padding is 1024 bytes; raise it to leave room for in-place edits in the surrounding file.

The v2.4 footer flag is honoured: setting Flags=FlagFooter on a V24 tag emits a 10-byte "3DI" trailer after the frames and forces padding to 0 (the spec requires footer and padding be exclusive). Tag-level unsynchronisation and the extended header are never emitted on output.

A *Tag is not safe for concurrent use.

Index

Constants

View Source
const DefaultPadding = 1024

DefaultPadding is the number of zero bytes Read attaches to a tag so that callers can re-encode in place without growing the file.

View Source
const HeaderSize = 10

HeaderSize is the on-disk size of the ID3v2 tag header in bytes.

View Source
const MaxSynchsafe uint32 = 1<<28 - 1

MaxSynchsafe is the largest value that fits in a 28-bit synchsafe integer (4 bytes, top bit of each byte zero).

Variables

View Source
var ErrCannotEncodeLatin1 = errors.New("id3v2: text contains non-Latin-1 characters")

ErrCannotEncodeLatin1 is returned by encodeString when the input contains code points outside the ISO-8859-1 range.

View Source
var ErrNoTag = errors.New("id3v2: no tag found")

ErrNoTag is returned by Read when the input does not begin with the "ID3" magic bytes.

View Source
var ErrSynchsafeOverflow = errors.New("id3v2: synchsafe value exceeds 28 bits")

ErrSynchsafeOverflow is returned by encodeSynchsafe when the value exceeds 2^28-1.

View Source
var ErrUnsupportedVersion = errors.New("id3v2: unsupported tag version")

ErrUnsupportedVersion is returned when the major revision is not 2, 3, or 4.

Functions

This section is empty.

Types

type CommentFrame

type CommentFrame struct {
	Encoding    Encoding
	Language    string // 3-character ISO-639-2 code, e.g. "eng"; "XXX" if unknown
	Description string
	Text        string
}

CommentFrame is the COMM frame: a per-language, per-description comment string.

func (*CommentFrame) Encode

func (f *CommentFrame) Encode(v Version, w io.Writer) error

func (*CommentFrame) ID

func (f *CommentFrame) ID() string

type Encoding

type Encoding uint8

Encoding identifies the text encoding byte that prefixes most ID3v2 textual fields. Every value of Encoding can be read; on write, EncUTF16BE and EncUTF8 are valid only for v2.4 frames.

const (
	EncISO88591 Encoding = 0 // Latin-1, null-terminated with one zero byte
	EncUTF16    Encoding = 1 // UTF-16 with BOM, null-terminated with two zero bytes
	EncUTF16BE  Encoding = 2 // UTF-16BE without BOM (v2.4 only), null-terminated with two zero bytes
	EncUTF8     Encoding = 3 // UTF-8 (v2.4 only), null-terminated with one zero byte
)

func (Encoding) String

func (e Encoding) String() string

type Flags

type Flags uint8

Flags are the bit flags carried in the tag-level header byte at offset 5. Not every flag is valid in every version; see the ID3v2 specifications for details.

const (
	FlagUnsync       Flags = 1 << 7 // valid in v2.2/v2.3/v2.4
	FlagExtended     Flags = 1 << 6 // v2.3/v2.4
	FlagExperimental Flags = 1 << 5 // v2.3/v2.4
	FlagFooter       Flags = 1 << 4 // v2.4 only
)

type Frame

type Frame interface {
	ID() string
	Encode(v Version, w io.Writer) error
}

Frame is one ID3v2 frame. The internal ID is the canonical 4-character v2.3/v2.4 form; v2.2 IDs are normalised on read and re-emitted in their original form when written back to v2.2.

type GenericFrame

type GenericFrame struct {
	// FrameID is the canonical 4-character ID (e.g. "TIT2").
	// For unknown v2.2 IDs without a known canonical form the raw
	// 3-character ID is used instead and is treated specially when
	// re-emitting to v2.2.
	FrameID string
	// Body is the raw frame contents excluding the frame header.
	Body []byte
	// StatusFlags / FormatFlags are the two flag bytes from the
	// v2.3 / v2.4 frame header. Always zero for v2.2 frames.
	StatusFlags byte
	FormatFlags byte
}

GenericFrame is the fallback representation when a frame's body is not recognised by any typed parser. Its raw bytes are preserved verbatim for loss-less round-trip.

func (*GenericFrame) Encode

func (f *GenericFrame) Encode(v Version, w io.Writer) error

func (*GenericFrame) ID

func (f *GenericFrame) ID() string
type Header struct {
	Version Version
	Flags   Flags
	// Size is the byte length of the payload that follows the header
	// (frames + padding, plus extended header when present). It does
	// not include the 10-byte header itself, nor the 10-byte v2.4
	// footer.
	Size uint32
}

Header is the parsed 10-byte ID3v2 tag header.

type PictureFrame

type PictureFrame struct {
	Encoding    Encoding
	MIME        string // e.g. "image/jpeg"
	PictureType uint8  // see tunetag.PictureType (0..20)
	Description string
	Data        []byte
}

PictureFrame is the APIC (v2.3/v2.4) / PIC (v2.2) attached picture frame. v2.2 PIC is read transparently as APIC: the 3-char image format is converted to a MIME type on read, and APIC is always emitted on write since v2.2 writing is not supported.

func (*PictureFrame) Encode

func (f *PictureFrame) Encode(v Version, w io.Writer) error

func (*PictureFrame) ID

func (f *PictureFrame) ID() string

type PrivFrame

type PrivFrame struct {
	Owner string
	Data  []byte
}

PrivFrame is the PRIV private frame. The Owner identifies the producer (often a URL or email); Data is opaque application bytes.

func (*PrivFrame) Encode

func (f *PrivFrame) Encode(v Version, w io.Writer) error

func (*PrivFrame) ID

func (f *PrivFrame) ID() string

type Tag

type Tag struct {
	Version Version
	Flags   Flags
	Frames  []Frame // preserved in the order seen on disk
	Padding int     // target padding bytes for the next Encode
}

Tag is the in-memory representation of an ID3v2 tag.

func Read

func Read(r io.Reader) (*Tag, error)

Read parses an ID3v2 tag from the start of r. ErrNoTag is returned when r does not begin with the ID3v2 magic bytes.

func ReadFile

func ReadFile(path string) (*Tag, error)

ReadFile is a convenience wrapper around Read.

func (*Tag) AddFrame

func (t *Tag) AddFrame(f Frame)

AddFrame appends f to t.Frames.

func (*Tag) Album

func (t *Tag) Album() string

func (*Tag) AlbumArtist

func (t *Tag) AlbumArtist() string

func (*Tag) Artist

func (t *Tag) Artist() string

func (*Tag) Comment

func (t *Tag) Comment() string

Comment returns the text of the first COMM frame, or "".

func (*Tag) Composer

func (t *Tag) Composer() string

func (*Tag) DiscNumber

func (t *Tag) DiscNumber() (n, total int)

func (*Tag) Encode

func (t *Tag) Encode(w io.Writer) error

Encode writes the tag (header + frames + padding) to w.

func (*Tag) Genre

func (t *Tag) Genre() string

func (*Tag) PictureFrames

func (t *Tag) PictureFrames() []*PictureFrame

PictureFrames returns every APIC frame in tag order. It is primarily a helper for the top-level wrapper that converts these to tunetag.Picture; callers can use them directly too.

func (*Tag) RemoveFrames

func (t *Tag) RemoveFrames(id string)

RemoveFrames removes every frame with the given canonical ID.

func (*Tag) SetAlbum

func (t *Tag) SetAlbum(s string)

func (*Tag) SetAlbumArtist

func (t *Tag) SetAlbumArtist(s string)

func (*Tag) SetArtist

func (t *Tag) SetArtist(s string)

func (*Tag) SetComposer

func (t *Tag) SetComposer(s string)

func (*Tag) SetGenre

func (t *Tag) SetGenre(s string)

func (*Tag) SetText

func (t *Tag) SetText(id, value string)

SetText replaces (or, if absent, appends) the TextFrame for id with a single value. An empty value removes any existing frame. The encoding is auto-selected per the tag version.

func (*Tag) SetTitle

func (t *Tag) SetTitle(s string)

func (*Tag) Title

func (t *Tag) Title() string

func (*Tag) TrackNumber

func (t *Tag) TrackNumber() (n, total int)

TrackNumber and DiscNumber parse "n/total" or "n" from TRCK and TPOS respectively. Missing components are 0.

func (*Tag) WriteFile

func (t *Tag) WriteFile(path string) error

WriteFile writes t into path, replacing any existing ID3v2 tag at the start of the file. The audio body following the existing tag is preserved unchanged.

When the new tag (header + frames + Padding) fits within the bytes occupied by the previous tag, it is written in place and the padding is grown to keep the audio offset stable. Otherwise the file is rewritten to a temporary file in the same directory and renamed atomically.

func (*Tag) Year

func (t *Tag) Year() int

Year extracts a four-digit year from TYER (v2.3) or the leading digits of TDRC (v2.4). Returns 0 if neither is present or parses.

type TextFrame

type TextFrame struct {
	FrameID  string
	Encoding Encoding
	Text     []string
}

TextFrame represents any T*** frame other than TXXX. Multiple values are stored in Text and emitted null-separated; v2.3 readers that strictly follow the spec will see only the first value, but mutagen / TagLib / foobar2000 all interpret the convention.

func (*TextFrame) Encode

func (f *TextFrame) Encode(v Version, w io.Writer) error

func (*TextFrame) ID

func (f *TextFrame) ID() string

func (*TextFrame) String

func (f *TextFrame) String() string

String is a convenience accessor for the first value.

type UFIDFrame

type UFIDFrame struct {
	Owner      string
	Identifier []byte
}

UFIDFrame is the unique file identifier frame. The Owner is a Latin-1 owner identifier (URL or email-like) and Identifier is up to 64 bytes of opaque data per spec.

func (*UFIDFrame) Encode

func (f *UFIDFrame) Encode(v Version, w io.Writer) error

func (*UFIDFrame) ID

func (f *UFIDFrame) ID() string

type URLFrame

type URLFrame struct {
	FrameID string
	URL     string
}

URLFrame represents any W*** frame other than WXXX. The URL is always Latin-1 per the spec.

func (*URLFrame) Encode

func (f *URLFrame) Encode(v Version, w io.Writer) error

func (*URLFrame) ID

func (f *URLFrame) ID() string

type UnsynchronisedLyricsFrame

type UnsynchronisedLyricsFrame struct {
	Encoding    Encoding
	Language    string
	Description string
	Text        string
}

UnsynchronisedLyricsFrame is the USLT frame; its body layout is identical to COMM.

func (*UnsynchronisedLyricsFrame) Encode

func (*UnsynchronisedLyricsFrame) ID

type UserTextFrame

type UserTextFrame struct {
	Encoding    Encoding
	Description string
	Value       string
}

UserTextFrame is the TXXX user-defined text frame, which stores a description-keyed string value.

func (*UserTextFrame) Encode

func (f *UserTextFrame) Encode(v Version, w io.Writer) error

func (*UserTextFrame) ID

func (f *UserTextFrame) ID() string

type UserURLFrame

type UserURLFrame struct {
	Encoding    Encoding
	Description string
	URL         string
}

UserURLFrame is the WXXX user-defined URL frame.

func (*UserURLFrame) Encode

func (f *UserURLFrame) Encode(v Version, w io.Writer) error

func (*UserURLFrame) ID

func (f *UserURLFrame) ID() string

type Version

type Version uint8

Version is the major ID3v2 revision (2, 3, or 4). Frame syntax, frame-ID length, and tag-level flag semantics differ between versions. The minor revision is always treated as 0.

const (
	V22 Version = 2
	V23 Version = 3
	V24 Version = 4
)

func (Version) FrameIDLen

func (v Version) FrameIDLen() int

FrameIDLen returns the byte length of a frame identifier in this version: 3 for v2.2, 4 for v2.3 and v2.4.

func (Version) String

func (v Version) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL