/
library.go
145 lines (123 loc) · 2.87 KB
/
library.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package library
import (
"github.com/wtolson/go-taglib"
"io/ioutil"
"mime"
"path/filepath"
"strings"
)
type Library struct {
albums []*Album
songLoadReceiver func(s *Song)
loadFinishReceiver func()
}
// New() returns an initialised instance of Library.
func New() *Library {
return &Library{albums: make([]*Album, 0)}
}
func (l *Library) SetSongLoadReceiver(rec func(s *Song)) {
l.songLoadReceiver = rec
}
func (l *Library) SetLoadFinishReceiver(rec func()) {
l.loadFinishReceiver = rec
}
// ImportFromDir() imports all songs in a directory, recursively.
func (l *Library) ImportFromDir(dir string) {
l.importFromDir(dir)
if l.loadFinishReceiver != nil {
l.loadFinishReceiver()
}
}
func (l *Library) importFromDir(dir string) {
ls, err := ioutil.ReadDir(dir)
if err != nil {
return
}
for _, file := range ls {
if file.IsDir() {
l.importFromDir(dir + "/" + file.Name())
} else {
l.ImportSong(dir + "/" + file.Name())
}
}
}
// GetPathAudioFormat() returns the audio format of the audio file located at path.
func GetPathAudioFormat(path string) AudioFormat {
mt := mime.TypeByExtension(filepath.Ext(path))
if strings.Contains(mt, "flac") {
return FLAC
} else if strings.Contains(mt, "ogg") {
return OGG_VORBIS // TODO make sure audio is vorbis
} else if strings.Contains(mt, "mpeg") || strings.Contains(mt, "mp3") {
return MP3
}
return UNKNOWN
}
func (l *Library) openAlbum(name, artist string) *Album {
for _, a := range l.albums {
if a.name == name {
return a
}
}
a := &Album {name: name, artist: artist, songs: make([]*Song, 0)}
l.albums = append(l.albums, a)
return a
}
// ImportSong() imports a single song into the library.
func (l *Library) ImportSong(path string) {
form := GetPathAudioFormat(path)
if form == UNKNOWN {
return
}
tags, err := taglib.Read(path)
if err != nil {
return
}
album := l.openAlbum(tags.Album(), tags.Artist())
s := &Song {format: form, path: path, title: tags.Title(), track: tags.Track(), album: album}
s.tgain, _ = s.LoadGain(GAIN_TRACK)
s.again, _ = s.LoadGain(GAIN_ALBUM)
album.addSong(s)
tags.Close()
if l.songLoadReceiver != nil {
l.songLoadReceiver(s)
}
}
func (l *Library) GetAlbum(name string) *Album {
for _, a := range l.albums {
if a.name == name {
return a
}
}
return nil
}
func (l *Library) Albums() []*Album {
return l.albums
}
func (l *Library) UntaggedAlbums() []*Album {
ret := make([]*Album, 0)
for _, a := range l.albums {
if !a.tagged {
ret = append(ret, a)
}
}
return ret
}
func (l *Library) TaggedSongs() []*Song {
ret := make([]*Song, 0)
for _, a := range l.albums {
for _, s := range a.songs {
if s.Gain(GAIN_TRACK) != "?" || s.Gain(GAIN_ALBUM) != "?" {
ret = append(ret, s)
}
}
}
return ret
}
func (l *Library) String() string {
ret := ""
for _, a := range l.albums {
ret += a.String() + "\n"
}
return ret[:len(ret) - 1]
}