diff --git a/go.mod b/go.mod index f336c448..ad6ccb48 100644 --- a/go.mod +++ b/go.mod @@ -9,20 +9,19 @@ require ( github.com/cespare/xxhash v1.1.0 github.com/disintegration/imaging v1.6.2 github.com/dustin/go-humanize v1.0.0 - github.com/faiface/beep v1.0.2 + github.com/faiface/beep v1.0.3-0.20210817042730-1c98bf641535 github.com/google/uuid v1.1.2 // indirect + github.com/gopherjs/gopherwasm v1.0.0 // indirect github.com/gorilla/mux v1.8.0 github.com/gorilla/securecookie v1.1.1 github.com/gorilla/sessions v1.2.1 github.com/hajimehoshi/go-mp3 v0.3.1 // indirect - github.com/hajimehoshi/oto v0.7.0 // indirect github.com/huandu/xstrings v1.3.2 // indirect github.com/imdario/mergo v0.3.11 // indirect github.com/jinzhu/gorm v1.9.16 github.com/josephburnett/jd v0.0.0-20191228205456-aa1a7c66b42f github.com/karrick/godirwalk v1.16.1 github.com/kr/pretty v0.1.0 // indirect - github.com/mewkiz/flac v1.0.6 // indirect github.com/mewkiz/pkg v0.0.0-20200702171441-dd47075182ea // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/reflectwalk v1.0.1 // indirect @@ -38,6 +37,7 @@ require ( golang.org/x/exp v0.0.0-20201229011636-eab1b5eb1a03 // indirect golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect golang.org/x/sys v0.0.0-20201223074533-0d417f636930 // indirect + gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/gormigrate.v1 v1.6.0 ) diff --git a/go.sum b/go.sum index fd84a8d3..c26f371b 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,7 @@ cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -32,8 +33,11 @@ github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DP github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/faiface/beep v1.0.2 h1:UB5DiRNmA4erfUYnHbgU4UB6DlBOrsdEFRtcc8sCkdQ= github.com/faiface/beep v1.0.2/go.mod h1:1yLb5yRdHMsovYYWVqYLioXkVuziCSITW1oarTeduQM= +github.com/faiface/beep v1.0.3-0.20210817042730-1c98bf641535 h1:391d1LXITcjNUsoeXUY21E5UCsmFz/W3ft9sInjynDI= +github.com/faiface/beep v1.0.3-0.20210817042730-1c98bf641535/go.mod h1:6I8p6kK2q4opL/eWb+kAkk38ehnTunWeToJB+s51sT4= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell v1.1.1/go.mod h1:K1udHkiR3cOtlpKG5tZPD5XxrF7v2y7lDq7Whcj+xkQ= +github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= github.com/go-audio/audio v1.0.0/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs= github.com/go-audio/riff v1.0.0/go.mod h1:l3cQwc85y79NQFCRB7TiPoNiaijp6q8Z0Uv38rVG498= github.com/go-audio/wav v1.0.0/go.mod h1:3yoReyQOsiARkvPl3ERCi8JFjihzG6WhjYpZCf5zAWE= @@ -63,6 +67,7 @@ github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/hajimehoshi/go-mp3 v0.1.1/go.mod h1:4i+c5pDNKDrxl1iu9iG90/+fhP37lio6gNhjCx9WBJw= +github.com/hajimehoshi/go-mp3 v0.3.0/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM= github.com/hajimehoshi/go-mp3 v0.3.1 h1:pn/SKU1+/rfK8KaZXdGEC2G/KCB2aLRjbTCrwKcokao= github.com/hajimehoshi/go-mp3 v0.3.1/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM= github.com/hajimehoshi/oto v0.1.1/go.mod h1:hUiLWeBQnbDu4pZsAhOnGqMI1ZGibS6e2qhQdfpwz04= @@ -70,6 +75,8 @@ github.com/hajimehoshi/oto v0.3.1/go.mod h1:e9eTLBB9iZto045HLbzfHJIc+jP3xaKrjZTg github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI= github.com/hajimehoshi/oto v0.7.0 h1:4HbTRhNuHd4SdFfA4vhIgmwvVO3qWueHK+fF1cButpg= github.com/hajimehoshi/oto v0.7.0/go.mod h1:wovJ8WWMfFKvP587mhHgot/MBr4DnNy9m6EepeVGnos= +github.com/hajimehoshi/oto v0.7.1 h1:I7maFPz5MBCwiutOrz++DLdbr4rTzBsbBuV2VpgU9kk= +github.com/hajimehoshi/oto v0.7.1/go.mod h1:wovJ8WWMfFKvP587mhHgot/MBr4DnNy9m6EepeVGnos= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/icza/bitio v1.0.0 h1:squ/m1SHyFeCA6+6Gyol1AxV9nmPPlJFT8c2vKdj3U8= @@ -79,6 +86,7 @@ github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBD github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jfreymuth/oggvorbis v1.0.0/go.mod h1:abe6F9QRjuU9l+2jek3gj46lu40N4qlYxh2grqkLEDM= +github.com/jfreymuth/oggvorbis v1.0.1/go.mod h1:NqS+K+UXKje0FUYUPosyQ+XTVvjmVjps1aEZH1sumIk= github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0= github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs= @@ -108,6 +116,7 @@ github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lucasb-eyer/go-colorful v0.0.0-20181028223441-12d3b2882a08/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4= +github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= @@ -117,6 +126,8 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW github.com/mewkiz/flac v1.0.5/go.mod h1:EHZNU32dMF6alpurYyKHDLYpW1lYpBZ5WrXi/VuNIGs= github.com/mewkiz/flac v1.0.6 h1:OnMwCWZPAnjDndjEzLynOZ71Y2U+/QYHoVI4JEKgKkk= github.com/mewkiz/flac v1.0.6/go.mod h1:yU74UH277dBUpqxPouHSQIar3G1X/QIclVbFahSd1pU= +github.com/mewkiz/flac v1.0.7 h1:uIXEjnuXqdRaZttmSFM5v5Ukp4U6orrZsnYGGR3yow8= +github.com/mewkiz/flac v1.0.7/go.mod h1:yU74UH277dBUpqxPouHSQIar3G1X/QIclVbFahSd1pU= github.com/mewkiz/pkg v0.0.0-20190919212034-518ade7978e2/go.mod h1:3E2FUC/qYUfM8+r9zAwpeHJzqRVVMIYnpzD/clwWxyA= github.com/mewkiz/pkg v0.0.0-20200702171441-dd47075182ea h1:LUvH2BZ4TRTtGAm7IPkIgdZ7rOobER2WQ/h5VUIwm9c= github.com/mewkiz/pkg v0.0.0-20200702171441-dd47075182ea/go.mod h1:3E2FUC/qYUfM8+r9zAwpeHJzqRVVMIYnpzD/clwWxyA= @@ -205,6 +216,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/server/jukebox/jukebox.go b/server/jukebox/jukebox.go index f857deda..7cbaf767 100644 --- a/server/jukebox/jukebox.go +++ b/server/jukebox/jukebox.go @@ -32,7 +32,6 @@ type Jukebox struct { playing bool sr beep.SampleRate // used to notify the player to re read the members - updates chan update quit chan struct{} done chan bool info *strmInfo @@ -46,25 +45,6 @@ type strmInfo struct { format beep.Format } -type updateType string - -const ( - set updateType = "set" - clear updateType = "clear" - skip updateType = "skip" - add updateType = "add" - remove updateType = "remove" - stop updateType = "stop" - start updateType = "start" -) - -type update struct { - action updateType - index int - tracks []*db.Track - skipOffset int -} - type updateSpeaker struct { index int offset int @@ -74,7 +54,6 @@ func New(musicPath string) *Jukebox { return &Jukebox{ musicPath: musicPath, sr: beep.SampleRate(48000), - updates: make(chan update), speaker: make(chan updateSpeaker, 1), done: make(chan bool), quit: make(chan struct{}), @@ -89,8 +68,6 @@ func (j *Jukebox) Listen() error { select { case <-j.quit: return nil - case update := <-j.updates: - j.doUpdate(update) case speaker := <-j.speaker: if err := j.doUpdateSpeaker(speaker); err != nil { log.Printf("error in jukebox: %v", err) @@ -103,66 +80,15 @@ func (j *Jukebox) Quit() { j.quit <- struct{}{} } -func (j *Jukebox) doUpdate(u update) { - j.Lock() - switch u.action { - case set: - j.playlist = u.tracks - j.Unlock() - case clear: - speaker.Clear() - j.playing = false - j.playlist = []*db.Track{} - j.Unlock() - case skip: - speaker.Clear() - j.index = u.index - j.playing = true - j.Unlock() - j.speaker <- updateSpeaker{index: j.index, offset: u.skipOffset} - case add: - if len(j.playlist) == 0 { - j.playlist = u.tracks - j.playing = true - j.index = 0 - j.Unlock() - j.speaker <- updateSpeaker{index: 0} - return - } - j.playlist = append(j.playlist, u.tracks...) - j.Unlock() - case remove: - if u.index < 0 || u.index >= len(j.playlist) { - j.Unlock() - return - } - j.playlist = append(j.playlist[:u.index], j.playlist[u.index+1:]...) - j.Unlock() - case stop: - if j.info != nil { - j.playing = false - j.info.ctrlStrmr.Paused = true - } - j.Unlock() - case start: - if j.info != nil { - j.playing = true - j.info.ctrlStrmr.Paused = false - } - j.Unlock() - } -} - func (j *Jukebox) doUpdateSpeaker(su updateSpeaker) error { + j.Lock() + defer j.Unlock() if su.index >= len(j.playlist) { - j.Lock() j.playing = false - j.Unlock() + speaker.Clear() return nil } - j.Lock() j.index = su.index - j.Unlock() f, err := os.Open(path.Join( j.musicPath, j.playlist[su.index].RelPath(), @@ -181,7 +107,6 @@ func (j *Jukebox) doUpdateSpeaker(su updateSpeaker) error { if err != nil { return err } - j.Lock() j.info = &strmInfo{} j.info.strm = streamer.(beep.StreamSeekCloser) if su.offset != 0 { @@ -195,7 +120,6 @@ func (j *Jukebox) doUpdateSpeaker(su updateSpeaker) error { j.sr, j.info.strm, ) j.info.format = format - j.Unlock() speaker.Play(beep.Seq(&j.info.ctrlStrmr, beep.Callback(func() { j.speaker <- updateSpeaker{index: su.index + 1} }))) @@ -203,47 +127,70 @@ func (j *Jukebox) doUpdateSpeaker(su updateSpeaker) error { } func (j *Jukebox) SetTracks(tracks []*db.Track) { - j.updates <- update{ - action: set, - tracks: tracks, - } + j.Lock() + defer j.Unlock() + j.playlist = tracks } func (j *Jukebox) AddTracks(tracks []*db.Track) { - j.updates <- update{ - action: add, - tracks: tracks, + j.Lock() + if len(j.playlist) == 0 { + j.playlist = tracks + j.playing = true + j.index = 0 + j.Unlock() + j.speaker <- updateSpeaker{index: 0} + return } + j.playlist = append(j.playlist, tracks...) + j.Unlock() } func (j *Jukebox) RemoveTrack(i int) { - j.updates <- update{ - action: remove, - index: i, + j.Lock() + defer j.Unlock() + if i < 0 || i >= len(j.playlist) { + return } + j.playlist = append(j.playlist[:i], j.playlist[i+1:]...) } func (j *Jukebox) Skip(i int, offset int) { - j.updates <- update{ - action: skip, - index: i, - skipOffset: offset, - } + speaker.Clear() + j.Lock() + j.index = i + j.playing = true + j.Unlock() + j.speaker <- updateSpeaker{index: j.index, offset: offset} } func (j *Jukebox) ClearTracks() { - j.updates <- update{action: clear} + speaker.Clear() + j.Lock() + defer j.Unlock() + j.playing = false + j.playlist = []*db.Track{} } func (j *Jukebox) Stop() { - j.updates <- update{action: stop} + j.Lock() + defer j.Unlock() + if j.info != nil { + j.playing = false + j.info.ctrlStrmr.Paused = true + } } func (j *Jukebox) Start() { - j.updates <- update{action: start} + if j.info != nil { + j.playing = true + j.info.ctrlStrmr.Paused = false + } } func (j *Jukebox) GetStatus() Status { + j.Lock() + defer j.Unlock() position := 0 if j.info != nil { length := j.info.format.SampleRate.D(j.info.strm.Position())