asf

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: May 24, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package asf reads and writes ASF / WMA file metadata.

ASF (Advanced Systems Format) is Microsoft's audio/video container. .wma audio files and .wmv video files both use it; this package handles only the tag metadata and treats every audio / video data object as opaque bytes that round-trip verbatim.

Two metadata objects are recognised:

  • Content Description Object — the five classic fields (Title, Author, Copyright, Description, Rating) stored as length-prefixed UTF-16LE strings.

  • Extended Content Description Object — a list of typed name / value descriptors. Common names like WM/AlbumTitle, WM/Year, WM/Genre, WM/TrackNumber, WM/AlbumArtist, WM/Composer, and WM/Picture are exposed via the high-level accessors below; the raw Descriptor slice is accessible for callers that need full control.

All other top-level Header child objects (File Properties, Stream Properties, Header Extension, Codec List, …) and the Data + Index objects following the header are preserved byte-for-byte across writes.

Memory: Read loads the entire post-header region (Data Object plus any Index objects, i.e. effectively the audio body) into memory so WriteFile can re-emit it after the rewritten header. This is fine for typical music files but expensive for multi-GB WMV. A streaming rewrite is left for a future release.

A *File is not safe for concurrent use.

Index

Constants

View Source
const (
	NameAlbumTitle  = "WM/AlbumTitle"
	NameAlbumArtist = "WM/AlbumArtist"
	NameComposer    = "WM/Composer"
	NameGenre       = "WM/Genre"
	NameYear        = "WM/Year"
	NameTrackNumber = "WM/TrackNumber"
	NamePartOfSet   = "WM/PartOfSet"
	NameTrack       = "WM/Track" // zero-indexed; deprecated in favour of TrackNumber
	NamePicture     = "WM/Picture"
	NameProvider    = "WM/Provider"
	NamePublisher   = "WM/Publisher"
	NameMediaClass  = "WM/MediaClassPrimaryID"
)

Well-known Extended Content Description names.

Variables

View Source
var (
	// ErrNoASF is returned by Read when the input does not begin
	// with the ASF Header Object GUID.
	ErrNoASF = errors.New("asf: not an ASF / WMA stream")

	// ErrTruncated is returned when an object's declared size
	// exceeds the available bytes.
	ErrTruncated = errors.New("asf: object size exceeds stream")
)

Errors returned by this package.

Functions

func IsHeaderGUID

func IsHeaderGUID(b []byte) bool

IsHeaderGUID reports whether the first 16 bytes of b match the ASF Header Object GUID. Used by tunetag.Detect to recognise .wma / .wmv files without having to parse the full header.

Types

type Descriptor

type Descriptor struct {
	Name  string
	Type  DescriptorType
	Value []byte // raw bytes; helpers below decode/encode common types
}

Descriptor is one Extended Content Description entry.

func (Descriptor) String

func (d Descriptor) String() string

String returns the value as a UTF-8 string if the descriptor's type is TypeString; otherwise empty.

func (Descriptor) Uint32

func (d Descriptor) Uint32() uint32

Uint32 returns the value as a uint32 if the descriptor's type is TypeDWord or TypeWord; otherwise 0.

type DescriptorType

type DescriptorType uint16

DescriptorType is the on-disk type code for an Extended Content Description Object descriptor value.

const (
	TypeString DescriptorType = 0
	TypeBinary DescriptorType = 1
	TypeBool   DescriptorType = 2
	TypeDWord  DescriptorType = 3
	TypeQWord  DescriptorType = 4
	TypeWord   DescriptorType = 5
)

type File

type File struct {
	// Content Description Object fields. Empty strings cause the
	// corresponding entry to be dropped (or the whole object
	// removed if all five are empty).
	Title       string
	Author      string
	Copyright   string
	Description string
	Rating      string

	// Extended Content Description Object descriptors in stream
	// order. Modify directly or via the accessors below.
	Extended []Descriptor
	// contains filtered or unexported fields
}

File holds the parsed metadata of an ASF / WMA file plus enough bookkeeping to rewrite it without disturbing the audio.

func Read

func Read(rs io.ReadSeeker) (*File, error)

Read parses an ASF stream and returns a populated *File. The audio body is captured into File.trailer for re-emission by WriteFile.

func ReadFile

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

ReadFile is a convenience wrapper around Read.

func (*File) AddPicture

func (f *File) AddPicture(p *Picture)

AddPicture appends a WM/Picture descriptor.

func (*File) Album

func (f *File) Album() string

Album returns WM/AlbumTitle.

func (*File) AlbumArtist

func (f *File) AlbumArtist() string

AlbumArtist returns WM/AlbumArtist.

func (*File) Artist

func (f *File) Artist() string

Artist returns the track artist. The Content Description Object's Author field is the canonical location for a per-track artist; WM/AlbumArtist (in the Extended Content Description Object) is a fallback for files that only populate the album artist. SetArtist writes to Author so this round-trips.

func (*File) Comment

func (f *File) Comment() string

Comment returns the CDO Description field (the closest analogue to a "comment").

func (*File) Composer

func (f *File) Composer() string

Composer returns WM/Composer.

func (*File) DiscNumber

func (f *File) DiscNumber() (n, total int)

DiscNumber returns (number, total) from WM/PartOfSet, which is conventionally "n" or "n/total" as a string.

func (*File) FindExt

func (f *File) FindExt(name string) *Descriptor

FindExt returns a pointer to the first Extended Content Description descriptor whose name matches (case-sensitive). nil if absent.

func (*File) Genre

func (f *File) Genre() string

Genre returns WM/Genre.

func (*File) GetExt

func (f *File) GetExt(name string) string

GetExt returns the string value of the named descriptor (only for TypeString descriptors), or "".

func (*File) Pictures

func (f *File) Pictures() []*Picture

Pictures returns every WM/Picture descriptor decoded as a Picture. Decoding errors are silently skipped; the raw bytes remain accessible via File.Extended.

func (*File) RemovePictures

func (f *File) RemovePictures()

RemovePictures deletes every WM/Picture descriptor.

func (*File) SetAlbum

func (f *File) SetAlbum(s string)

SetAlbum sets WM/AlbumTitle.

func (*File) SetArtist

func (f *File) SetArtist(s string)

SetArtist writes to the CDO Author field (the most-compatible location). Callers that specifically want WM/AlbumArtist can use SetExt(NameAlbumArtist, …) directly.

func (*File) SetComposer

func (f *File) SetComposer(s string)

SetComposer sets WM/Composer.

func (*File) SetDiscNumber

func (f *File) SetDiscNumber(n, total int)

SetDiscNumber sets WM/PartOfSet.

func (*File) SetExt

func (f *File) SetExt(name, value string)

SetExt sets or replaces a string-valued descriptor. Empty value removes it.

func (*File) SetGenre

func (f *File) SetGenre(s string)

SetGenre sets WM/Genre.

func (*File) SetTrackNumber

func (f *File) SetTrackNumber(n, total int)

SetTrackNumber sets WM/TrackNumber. When total > 0 the value is stored as "n/total"; otherwise a plain decimal string.

func (*File) SetYear

func (f *File) SetYear(year int)

SetYear sets WM/Year (stored as a string for compatibility).

func (*File) TrackNumber

func (f *File) TrackNumber() (n, total int)

TrackNumber returns (number, total). WM/TrackNumber is typically a uint32; some writers store "n/total" as a string.

func (*File) WriteFile

func (f *File) WriteFile(path string) error

WriteFile rewrites path with the current metadata. The audio body and any non-metadata Header child objects are preserved byte-for-byte.

func (*File) Year

func (f *File) Year() int

Year returns the WM/Year value as an integer, falling back to the first four digits of any string form.

type GUID

type GUID [16]byte

GUID is a 16-byte Microsoft globally-unique identifier as stored on disk in ASF files. The first three fields (Data1, Data2, Data3) are little-endian; the last two (Data4) are a raw 8-byte sequence. This matches Microsoft's wire encoding.

Display order is the canonical "8-4-4-4-12 hex" form used in the ASF spec, e.g. 75B22630-668E-11CF-A6D9-00AA0062CE6C.

func (GUID) String

func (g GUID) String() string

type Picture

type Picture struct {
	Type        uint8
	MIME        string
	Description string
	Data        []byte
}

Picture is one cover-art entry from a WM/Picture descriptor. The on-disk format is:

1 byte   picture type (matches ID3v2 APIC values)
4 bytes  data length (LE uint32)
N bytes  MIME type (UTF-16LE, NUL-terminated)
N bytes  description (UTF-16LE, NUL-terminated)
N bytes  image data

func DecodePicture

func DecodePicture(raw []byte) (*Picture, error)

DecodePicture decodes the body of a WM/Picture descriptor (Type=TypeBinary) into a Picture.

func (*Picture) Encode

func (p *Picture) Encode() []byte

Encode produces the descriptor value bytes for a WM/Picture entry. Caller is responsible for wrapping the result in a Descriptor with Type=TypeBinary.

Jump to

Keyboard shortcuts

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