1package tags
2
3import (
4	"strconv"
5	"strings"
6
7	"github.com/nicksellen/audiotags"
8	"github.com/pkg/errors"
9)
10
11type Tags struct {
12	raw   map[string]string
13	props *audiotags.AudioProperties
14}
15
16func New(path string) (*Tags, error) {
17	raw, props, err := audiotags.Read(path)
18	if err != nil {
19		return nil, errors.Wrap(err, "audiotags module")
20	}
21	return &Tags{
22		raw:   raw,
23		props: props,
24	}, nil
25}
26
27func (t *Tags) firstTag(keys ...string) string {
28	for _, key := range keys {
29		if val, ok := t.raw[key]; ok {
30			return val
31		}
32	}
33	return ""
34}
35
36func (t *Tags) Title() string         { return t.firstTag("title") }
37func (t *Tags) BrainzID() string      { return t.firstTag("musicbrainz_trackid") }
38func (t *Tags) Artist() string        { return t.firstTag("artist") }
39func (t *Tags) Album() string         { return t.firstTag("album") }
40func (t *Tags) AlbumArtist() string   { return t.firstTag("albumartist", "album artist") }
41func (t *Tags) AlbumBrainzID() string { return t.firstTag("musicbrainz_albumid") }
42func (t *Tags) Genre() string         { return t.firstTag("genre") }
43func (t *Tags) Year() int             { return intSep(t.firstTag("date", "year"), "-") } // eg. 2019-6-11
44func (t *Tags) TrackNumber() int      { return intSep(t.firstTag("tracknumber"), "/") }  // eg. 5/12
45func (t *Tags) DiscNumber() int       { return intSep(t.firstTag("discnumber"), "/") }   // eg. 1/2
46func (t *Tags) Length() int           { return t.props.Length }
47func (t *Tags) Bitrate() int          { return t.props.Bitrate }
48
49func intSep(in, sep string) int {
50	if in == "" {
51		return 0
52	}
53	start := strings.SplitN(in, sep, 2)[0]
54	out, err := strconv.Atoi(start)
55	if err != nil {
56		return 0
57	}
58	return out
59}
60