Initial commit
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
// Copyright 2015, David Howden
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package tag provides basic MP3 (ID3v1,2.{2,3,4}) and MP4 metadata parsing.
|
||||
package tag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ErrNoTagsFound is the error returned by ReadFrom when the metadata format
|
||||
// cannot be identified.
|
||||
var ErrNoTagsFound = errors.New("no tags found")
|
||||
|
||||
// ReadFrom parses audio file metadata tags (currently supports ID3v1,2.{2,3,4} and MP4).
|
||||
// This method attempts to determine the format of the data provided by the reader, and then
|
||||
// chooses ReadAtoms (MP4), ReadID3v2Tags (ID3v2.{2,3,4}) or ReadID3v1Tags as appropriate.
|
||||
// Returns non-nil error if the format of the given data could not be determined, or if
|
||||
// there was a problem parsing the data.
|
||||
func ReadFrom(r io.Reader) (Metadata, error) {
|
||||
b, err := readBytes(r, 11)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rr := io.MultiReader(bytes.NewReader(b), r)
|
||||
if string(b[4:11]) == "ftypM4A" {
|
||||
return ReadAtoms(rr)
|
||||
}
|
||||
if string(b[0:3]) == "ID3" {
|
||||
return ReadID3v2Tags(rr)
|
||||
}
|
||||
|
||||
m, err := ReadID3v1Tags(rr)
|
||||
if err != nil {
|
||||
if err == ErrNotID3v1 {
|
||||
err = ErrNoTagsFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Format is an enumeration of metadata types supported by this package.
|
||||
type Format string
|
||||
|
||||
const (
|
||||
ID3v1 Format = "ID3v1" // ID3v1 tag format.
|
||||
ID3v2_2 = "ID3v2.2" // ID3v2.2 tag format.
|
||||
ID3v2_3 = "ID3v2.3" // ID3v2.3 tag format (most common).
|
||||
ID3v2_4 = "ID3v2.4" // ID3v2.4 tag format.
|
||||
MP4 = "MP4" // MP4 tag (atom) format.
|
||||
)
|
||||
|
||||
// Metadata is an interface which is used to describe metadata retrieved by this package.
|
||||
type Metadata interface {
|
||||
// Format returns the metadata Format used to encode the data.
|
||||
Format() Format
|
||||
|
||||
// Title returns the title of the track.
|
||||
Title() string
|
||||
|
||||
// Album returns the album name of the track.
|
||||
Album() string
|
||||
|
||||
// Artist returns the artist name of the track.
|
||||
Artist() string
|
||||
|
||||
// AlbumArtist returns the album artist name of the track.
|
||||
AlbumArtist() string
|
||||
|
||||
// Composer returns the composer of the track.
|
||||
Composer() string
|
||||
|
||||
// Year returns the year of the track.
|
||||
Year() int
|
||||
|
||||
// Track returns the track number and total tracks, or zero values if unavailable.
|
||||
Track() (int, int)
|
||||
|
||||
// Disc returns the disc number and total discs, or zero values if unavailable.
|
||||
Disc() (int, int)
|
||||
|
||||
// Picture returns a picture, or nil if not avilable.
|
||||
Picture() *Picture
|
||||
|
||||
// Raw returns the raw mapping of retrieved tag names and associated values.
|
||||
// NB: tag/atom names are not standardised between formats.
|
||||
Raw() map[string]interface{}
|
||||
}
|
||||
Reference in New Issue
Block a user