-
Notifications
You must be signed in to change notification settings - Fork 2
/
library.go
153 lines (142 loc) · 3.5 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
146
147
148
149
150
151
152
153
// Date: 26/06/2019 // 2023/09/11
// Created By ybenel
package media
import (
"errors"
"os"
// "io/ioutil"
"path"
"sort"
"strings"
"sync"
mylog "github.com/M1ndo/TokYo/pkg/log"
)
// Library manages importing and retrieving video data.
type Library struct {
mu sync.RWMutex
Paths map[string]*Path
Videos map[string]*Video
}
// NewLibrary returns new instance of Library.
func NewLibrary() *Library {
lib := &Library{
Paths: make(map[string]*Path),
Videos: make(map[string]*Video),
}
return lib
}
// AddPath adds a media path to the library.
func (lib *Library) AddPath(p *Path) error {
lib.mu.Lock()
defer lib.mu.Unlock()
// make sure new path doesn't collide with existing ones
for _, p2 := range lib.Paths {
if p.Path == p2.Path {
return errors.New("media: duplicate library path")
}
if p.Prefix == p2.Prefix {
return errors.New("media: duplicate library prefix")
}
}
lib.Paths[p.Path] = p
return nil
}
// Import adds all valid videos from a given path.
func (lib *Library) Import(logger *mylog.Logger, p *Path) error {
files, err := os.ReadDir(p.Path)
// files, err := ioutil.ReadDir(p.Path)
if err != nil {
return err
}
for _, info := range files {
// log.Println(info.Name())
err = lib.Add(logger, path.Join(p.Path, info.Name()))
if err != nil {
// Ignore files that can't be parsed
continue
}
}
return nil
}
// Add adds a single video from a given file path.
func (lib *Library) Add(logger *mylog.Logger, filepath string) error {
// log.Println("Filepath: %s", filepath)
lib.mu.Lock()
defer lib.mu.Unlock()
d := path.Dir(filepath)
p, ok := lib.Paths[d]
if !ok {
logger.Log.Warn("media: path %s not found", d)
return errors.New("media: path not found")
}
// log.Println("P: %s", p) // Prints All files paths.
n := path.Base(filepath)
// log.Printf(n) // Prints all files in directory /videos
v, err := ParseVideo(p, n)
if err != nil {
logger.Log.Warn(err)
return err
}
// log.Println(v) // Prints array from tags returns metadata
lib.Videos[v.ID] = v
logger.Log.Info("Added:", v.Path)
return nil
}
// Remove removes a single video from a given file path.
func (lib *Library) Remove(logger *mylog.Logger, filepath string) {
lib.mu.Lock()
defer lib.mu.Unlock()
d := path.Dir(filepath)
p, ok := lib.Paths[d]
if !ok {
logger.Log.Warn("media: path %s not found", d)
return
}
n := path.Base(filepath)
// ID is name without extension
idx := strings.LastIndex(n, ".")
if idx == -1 {
idx = len(n)
}
id := n[:idx]
if len(p.Prefix) > 0 {
id = path.Join(p.Prefix, id)
}
v, ok := lib.Videos[id]
if ok {
delete(lib.Videos, id)
logger.Log.Info("Removed:", v.Path)
}
}
// Playlist returns a sorted Playlist of all videos.
func (lib *Library) Playlist() Playlist {
lib.mu.RLock()
defer lib.mu.RUnlock()
pl := make(Playlist, len(lib.Videos))
i := 0
for _, v := range lib.Videos {
pl[i] = v
i++
}
sort.Sort(pl)
return pl
}
// Handle Content Type Media
func (lib *Library) GetContentType(ext string) string {
contentTypes := map[string]string{
".mp4": "video/mp4",
".mp3": "audio/mpeg",
".webm": "video/webm",
".weba": "video/webm",
".flac": "audio/flac",
".ogg": "audio/ogg",
".m4a": "audio/m4a",
".m4r": "audio/m4a",
".opus": "audio/opus",
".wav": "audio/wav",
}
if contentType, ok := contentTypes[ext]; ok {
return contentType
}
return "application/octet-stream"
}