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