Documentation
¶
Overview ¶
Package tunetag is a pure Go audio metadata library supporting MP3 (ID3v1, ID3v2.2/2.3/2.4), FLAC (Vorbis Comment + Picture), MP4/M4A (iTunes-style ilst), WAV (RIFF LIST/INFO and embedded id3 chunks), AIFF / AIFC (text chunks + embedded ID3), Ogg Vorbis / Ogg Opus (Vorbis Comment, read+write with full re-paging), APEv2 (Monkey's Audio .ape, WavPack .wv, or any file with an APEv2 trailer), raw ADTS AAC (.aac, with optional ID3v2 prefix and ID3v1 trailer), and ASF / WMA (Content Description + Extended Content Description). It reads and writes tags using only the Go standard library — no cgo and no bundled native binaries.
Decision tree ¶
Pick the entry point based on whether you need read or write access:
- For read-only access where the file's container does not matter, use Detect (to identify the format) and Open (which returns a Tag interface exposing the common fields).
- For format-specific reads and writes, use the typed openers OpenMP3, OpenFLAC, OpenMP4, OpenWAV, OpenAIFF, OpenOgg, OpenAPE, OpenAAC, or OpenASF. Each returns a value from the respective subpackage that supports the full set of mutations and a WriteFile method.
- To erase every metadata block from a file while preserving the audio body, call Strip.
Read-only Tag interface ¶
The Tag interface returned by Open exposes only fields that are universally meaningful across formats (Title, Artist, Album, Year, Genre, Track, Disc, Composer, Comment, AlbumArtist, Pictures). Writes deliberately are not on this interface because each format's setter semantics differ in ways that a unified API would obscure (notably the multiple genre representations on MP4 and the Vorbis case-sensitivity rules on FLAC).
Format-specific subpackages ¶
- github.com/cabbagekobe/tunetag/id3v1: ID3v1 / v1.1 trailer.
- github.com/cabbagekobe/tunetag/id3v2: ID3v2.2 / 2.3 / 2.4.
- github.com/cabbagekobe/tunetag/flac: Vorbis Comment + Picture blocks; unknown blocks round-trip verbatim.
- github.com/cabbagekobe/tunetag/mp4: iTunes-style ilst, including freeform "----" atoms.
- github.com/cabbagekobe/tunetag/wav: RIFF LIST/INFO entries and embedded "id3 " chunks (ID3v2 inside WAV).
- github.com/cabbagekobe/tunetag/aiff: NAME / AUTH / "(c) " / ANNO text chunks and embedded "ID3 " chunks.
- github.com/cabbagekobe/tunetag/ogg: Vorbis Comment metadata from Ogg Vorbis and Ogg Opus streams (read+write; the writer re-pages the comment packet and renumbers / re-CRCs subsequent pages as needed). Cover art via Xiph's METADATA_BLOCK_PICTURE convention.
- github.com/cabbagekobe/tunetag/ape: APEv2 tags at the end of any file, including Monkey's Audio (.ape) and WavPack (.wv). Cover art via "Cover Art (Front)" / "(Back)" / "(Other)" binary items.
- github.com/cabbagekobe/tunetag/aac: raw ADTS AAC, with optional leading ID3v2 and trailing ID3v1.
- github.com/cabbagekobe/tunetag/asf: ASF / WMA Content Description Object + Extended Content Description Object, with WM/Picture decode and encode helpers.
Concurrency ¶
None of the per-format value types (Tag, *id3v2.Tag, *flac.File, *mp4.File, *wav.File, *aiff.File, *ogg.File, *ape.Tag, *aac.File, *asf.File) are safe for concurrent use. The pure parsing entry points (Detect, id3v2.Read, flac.Read, mp4.Read, wav.Read, aiff.Read, ogg.Read, ape.Read, aac.Read, asf.Read) are re-entrant as long as each call uses its own reader.
Index ¶
- Variables
- func OpenAAC(path string) (*aac.File, error)
- func OpenAIFF(path string) (*aiff.File, error)
- func OpenAPE(path string) (*ape.Tag, error)
- func OpenASF(path string) (*asf.File, error)
- func OpenFLAC(path string) (*flac.File, error)
- func OpenMP4(path string) (*mp4.File, error)
- func OpenOgg(path string) (*ogg.File, error)
- func OpenWAV(path string) (*wav.File, error)
- func SniffImageMIME(b []byte) string
- func Strip(path string) error
- type Format
- type MP3
- type Picture
- type PictureType
- type Tag
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrUnknownFormat is returned by Detect and Open when the input // does not match any supported container. ErrUnknownFormat = errors.New("tunetag: unknown format") // ErrEmptyFile is returned by Detect and Open when the input has // zero bytes. errors.Is(err, ErrUnknownFormat) reports true so // existing callers that only branch on ErrUnknownFormat keep // working. ErrEmptyFile = &detectError{msg: "tunetag: empty file"} // ErrFileTooSmall is returned by Detect and Open when the input // is shorter than any supported tag header can be. As with // ErrEmptyFile, errors.Is(err, ErrUnknownFormat) reports true. ErrFileTooSmall = &detectError{msg: "tunetag: file too small to contain any tag"} )
Functions ¶
func OpenAAC ¶ added in v0.1.3
OpenAAC opens a raw ADTS AAC file. Both a leading ID3v2 tag and a trailing ID3v1 tag are recognised; an untagged file is represented by a *aac.File with V2 == V1 == nil.
func OpenAIFF ¶ added in v0.1.3
OpenAIFF opens an AIFF / AIFC file for read-write metadata access. The returned *aiff.File exposes the NAME / AUTH / "(c) " / ANNO text chunks via Text + Annotations and any embedded "ID3 " chunk via ID3.
func OpenAPE ¶ added in v0.1.3
OpenAPE locates and parses an APEv2 tag at the end of path. The audio container itself can be anything: APEv2 is the canonical tag format for Monkey's Audio (.ape) and WavPack (.wv) but is also valid on MP3, MPC, OFR, and others.
func OpenASF ¶ added in v0.1.3
OpenASF opens an ASF / WMA file. The returned *asf.File exposes the Content Description Object fields (Title / Author / Copyright / Description / Rating) plus the Extended Content Description Object descriptors (Extended) and any embedded WM/Picture entries.
func OpenFLAC ¶
OpenFLAC opens a FLAC file for read-write metadata access.
Example ¶
ExampleOpenFLAC shows the Vorbis Comment workflow: get the (creating-if-absent) VorbisComment block, mutate it, and call WriteFile to persist.
package main
import (
"log"
"github.com/cabbagekobe/tunetag"
)
func main() {
f, err := tunetag.OpenFLAC("/path/to/song.flac")
if err != nil {
log.Fatal(err)
}
vc := f.VorbisComment()
vc.Set("TITLE", "New Title")
vc.Set("DATE", "2026")
if err := f.WriteFile("/path/to/song.flac"); err != nil {
log.Fatal(err)
}
}
Output:
func OpenMP4 ¶
OpenMP4 opens an MP4 / M4A file for read-write metadata access.
Example ¶
ExampleOpenMP4 demonstrates editing an MP4 / M4A. The library auto-promotes 32-bit stco chunk offsets to 64-bit co64 when a rewrite would otherwise overflow; freeform "----" items are preserved.
package main
import (
"log"
"github.com/cabbagekobe/tunetag"
)
func main() {
m, err := tunetag.OpenMP4("/path/to/song.m4a")
if err != nil {
log.Fatal(err)
}
m.Tag.SetTitle("New Title")
m.Tag.SetArtist("New Artist")
m.Tag.SetTrack(3, 12)
if err := m.WriteFile("/path/to/song.m4a"); err != nil {
log.Fatal(err)
}
}
Output:
func OpenOgg ¶ added in v0.1.3
OpenOgg opens an Ogg (Vorbis or Opus) file. The returned *ogg.File is read-only; writing Ogg comments is not yet implemented.
func OpenWAV ¶ added in v0.1.3
OpenWAV opens a WAV (RIFF/WAVE) file for read-write metadata access. The returned *wav.File exposes the LIST/INFO entries and any embedded id3 chunk via its Info field and ID3 field.
func SniffImageMIME ¶ added in v0.1.3
SniffImageMIME returns a best-effort image MIME type sniffed from the leading bytes of b. Recognised: JPEG, PNG, GIF, BMP. Returns "" when no signature matches.
This is intended for callers building Picture-like values for containers that do not carry MIME alongside the image data (notably APEv2 and Vorbis Comment's METADATA_BLOCK_PICTURE before the FLAC PICTURE block fields are filled in). It is deliberately narrower than net/http.DetectContentType — only image formats are tested, so non-image input always returns "" rather than a spurious match.
func Strip ¶
Strip removes every metadata block at path, leaving the audio body intact. The format is auto-detected; ID3v2 is removed by rewriting the file without the leading tag, ID3v1 by truncating the trailer, FLAC by replacing all metadata blocks with a single empty STREAMINFO + minimal padding, and MP4 by emptying ilst.
Example ¶
ExampleStrip removes every metadata block from a file, leaving the audio body untouched.
package main
import (
"log"
"github.com/cabbagekobe/tunetag"
)
func main() {
if err := tunetag.Strip("/path/to/song.mp3"); err != nil {
log.Fatal(err)
}
}
Output:
Types ¶
type Format ¶
type Format int
Format identifies the on-disk container of an audio file.
func Detect ¶
func Detect(rs io.ReadSeeker) (Format, error)
Detect inspects the start (and, when needed, the end) of rs to identify the container format. The seek position of rs is restored before returning when possible.
On failure the returned error is one of:
- ErrEmptyFile when rs is zero bytes long,
- ErrFileTooSmall when rs is shorter than any supported tag header can be,
- ErrUnknownFormat otherwise.
ErrEmptyFile and ErrFileTooSmall are refinements of ErrUnknownFormat — errors.Is reports true for both, so callers that only branch on ErrUnknownFormat keep working unchanged.
type MP3 ¶
type MP3 struct {
V2 *id3v2.Tag // may be nil if the file had only an ID3v1 trailer
V1 *id3v1.Tag // may be nil
}
MP3 carries the parsed ID3v2 and/or ID3v1 tags from an MP3 file. V2 is preferred; V1 is exposed for inspection.
func OpenMP3 ¶
OpenMP3 returns the parsed ID3v2 (preferred) and/or ID3v1 tag found in path.
Example ¶
ExampleOpenMP3 demonstrates editing an MP3's ID3v2 tag in place and writing it back to disk. tunetag.OpenMP3 returns both the v2 and v1 parses; writes go through the v2 representation.
package main
import (
"log"
"github.com/cabbagekobe/tunetag"
"github.com/cabbagekobe/tunetag/id3v2"
)
func main() {
mp3, err := tunetag.OpenMP3("/path/to/song.mp3")
if err != nil {
log.Fatal(err)
}
if mp3.V2 == nil {
// Build a fresh ID3v2.4 tag.
mp3.V2 = &id3v2.Tag{Version: id3v2.V24, Padding: id3v2.DefaultPadding}
}
mp3.V2.SetTitle("New Title")
mp3.V2.SetArtist("New Artist")
if err := mp3.V2.WriteFile("/path/to/song.mp3"); err != nil {
log.Fatal(err)
}
}
Output:
type Picture ¶
type Picture struct {
MIME string
Type PictureType
Description string
Data []byte
}
Picture is an embedded image attached to an audio file.
type PictureType ¶
type PictureType uint8
PictureType is the role of an embedded picture. The 21 values are shared between ID3v2 APIC frames and FLAC METADATA_BLOCK_PICTURE.
const ( PictureOther PictureType = 0 PictureFileIcon32 PictureType = 1 PictureFileIcon PictureType = 2 PictureCoverFront PictureType = 3 PictureCoverBack PictureType = 4 PictureLeafletPage PictureType = 5 PictureMedia PictureType = 6 PictureLeadArtist PictureType = 7 PictureArtist PictureType = 8 PictureConductor PictureType = 9 PictureBand PictureType = 10 PictureComposer PictureType = 11 PictureLyricist PictureType = 12 PictureRecordingLocation PictureType = 13 PictureDuringRecording PictureType = 14 PictureDuringPerformance PictureType = 15 PictureMovieScreenshot PictureType = 16 PictureBrightColouredFish PictureType = 17 PictureIllustration PictureType = 18 PictureBandLogo PictureType = 19 PicturePublisherLogo PictureType = 20 )
type Tag ¶
type Tag interface {
Title() string
Artist() string
AlbumArtist() string
Album() string
Year() int
TrackNumber() (n, total int)
DiscNumber() (n, total int)
Genre() string
Composer() string
Comment() string
Pictures() []Picture
Format() Format
}
Tag is the read-only common interface implemented by every format-specific tag type. Setters are intentionally absent — write semantics differ enough between formats that a unified setter API would be misleading. Use the format subpackages for writes.
func Open ¶
Open auto-detects the container at path and returns a read-only Tag for the most informative metadata block in the file.
- MP3: ID3v2 if present, otherwise ID3v1.
- FLAC / MP4: the corresponding format-specific reader.
- WAV: embedded "id3 " chunk if present, else LIST/INFO.
- AIFF / AIFC: embedded "ID3 " chunk if present, else NAME / AUTH / "(c) " / ANNO text chunks.
- Ogg (Vorbis / Opus): the codec's comment header.
- APEv2 (.ape, .wv, or any file with a trailing APEv2 tag).
- AAC: leading ID3v2 if present, else trailing ID3v1, else an empty tag (so untagged .aac files still resolve).
- ASF / WMA: the Content Description Object fields, with WM/AlbumArtist (in the Extended Content Description Object) preferred over the CDO's Author field when both exist.
For format-specific writes, use OpenMP3, OpenFLAC, OpenMP4, OpenWAV, OpenAIFF, OpenOgg, OpenAPE, OpenAAC, or OpenASF directly.
Example ¶
ExampleOpen shows the simplest read path: auto-detect the container and pull out a handful of common fields via the read-only Tag interface.
package main
import (
"fmt"
"log"
"github.com/cabbagekobe/tunetag"
)
func main() {
tag, err := tunetag.Open("/path/to/song.mp3")
if err != nil {
log.Fatal(err)
}
fmt.Println(tag.Format(), tag.Title(), "/", tag.Artist())
}
Output:
Directories
¶
| Path | Synopsis |
|---|---|
|
Package aac handles raw ADTS-framed AAC files.
|
Package aac handles raw ADTS-framed AAC files. |
|
Package aiff reads and writes AIFF (FORM/AIFF) and AIFC (FORM/AIFC) file metadata.
|
Package aiff reads and writes AIFF (FORM/AIFF) and AIFC (FORM/AIFC) file metadata. |
|
Package ape reads and writes APEv2 tags.
|
Package ape reads and writes APEv2 tags. |
|
Package asf reads and writes ASF / WMA file metadata.
|
Package asf reads and writes ASF / WMA file metadata. |
|
cmd
|
|
|
tunetag
command
tunetag is a command-line driver for the tunetag library.
|
tunetag is a command-line driver for the tunetag library. |
|
Package flac reads and writes FLAC metadata blocks.
|
Package flac reads and writes FLAC metadata blocks. |
|
Package id3v1 reads and writes ID3v1 / ID3v1.1 trailer tags (the fixed 128-byte block at the end of an MP3 file).
|
Package id3v1 reads and writes ID3v1 / ID3v1.1 trailer tags (the fixed 128-byte block at the end of an MP3 file). |
|
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").
|
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"). |
|
internal
|
|
|
mp4test
Package mp4test provides minimal MP4 byte-blob fixtures for the mp4 package tests.
|
Package mp4test provides minimal MP4 byte-blob fixtures for the mp4 package tests. |
|
Package mp4 reads and writes iTunes-style metadata from MP4 / M4A containers.
|
Package mp4 reads and writes iTunes-style metadata from MP4 / M4A containers. |
|
Package ogg reads Vorbis Comment metadata from Ogg Vorbis and Ogg Opus streams.
|
Package ogg reads Vorbis Comment metadata from Ogg Vorbis and Ogg Opus streams. |
|
Package wav reads and writes WAV (RIFF/WAVE) file metadata.
|
Package wav reads and writes WAV (RIFF/WAVE) file metadata. |