aboutsummaryrefslogtreecommitdiff
path: root/downloader
diff options
context:
space:
mode:
Diffstat (limited to 'downloader')
-rw-r--r--downloader/download_manager.go82
-rw-r--r--downloader/downloader.go29
2 files changed, 70 insertions, 41 deletions
diff --git a/downloader/download_manager.go b/downloader/download_manager.go
index c0ceecb..16054ae 100644
--- a/downloader/download_manager.go
+++ b/downloader/download_manager.go
@@ -12,6 +12,7 @@ const (
Clear DlMessage = iota
Pause
Play
+ Skip
)
type playBundle struct {
@@ -43,50 +44,61 @@ func NewManager(s *discordgo.Session, guildID string, voiceChanID string) *Downl
}
func (m *DownloadManager) playFromQueue() {
- for dl := range m.dls {
- conn, err := m.session.ChannelVoiceJoin(m.guildID, m.voiceID, false, false)
- if err != nil {
- log.Errorf("unable to connect to the voice channel: %q", err)
- time.Sleep(1 * time.Second)
- break
- }
+ for {
+ select {
+ case <-m.PlayState: // ignore play state updates while not playing anything
+ case dl := <-m.dls:
+ conn, err := m.session.ChannelVoiceJoin(m.guildID, m.voiceID, false, false)
+ if err != nil {
+ log.Errorf("unable to connect to the voice channel: %q", err)
+ time.Sleep(1 * time.Second)
+ break
+ }
- out, _ := dl.Start()
+ m.session.UpdateStatus(0, dl.info.Url.Host)
+ out := dl.Start()
- playState := Play
- conn.Speaking(true)
+ playState := Play
+ conn.Speaking(true)
- cleanup := func() {
- conn.Speaking(false)
- conn.Disconnect()
- }
+ cleanup := func() {
+ conn.Speaking(false)
+ conn.Disconnect()
+ m.session.UpdateStatus(0, "literally nothing")
+ }
- inner:
- for {
- switch playState {
- case Clear:
- for {
- select {
- case <-m.PlayState:
- default:
- }
- }
- break inner
- case Pause:
- playState = <-m.PlayState
- case Play:
- select { // first check if we have a state update message coming in
- case playState = <-m.PlayState:
- case elem, ok := <-out:
- if !ok {
- break inner
+ inner:
+ for {
+ switch playState {
+ case Clear:
+ dl.Stop()
+ for {
+ select {
+ case dl := <-m.dls:
+ dl.Stop()
+ dl.Start() // this is a hacky way of ensuring all the wavs are closed and cleaned up
+ default:
+ }
}
+ break inner
+ case Skip:
+ break inner
+ case Pause:
+ playState = <-m.PlayState
+ case Play:
+ select { // first check if we have a state update message coming in
+ case playState = <-m.PlayState:
+ case elem, ok := <-out:
+ if !ok {
+ break inner
+ }
- conn.OpusSend <- elem
+ conn.OpusSend <- elem
+ }
}
}
+ cleanup()
}
- cleanup()
}
}
diff --git a/downloader/downloader.go b/downloader/downloader.go
index 6abe7f0..b7645da 100644
--- a/downloader/downloader.go
+++ b/downloader/downloader.go
@@ -62,13 +62,21 @@ func (d *downloader) Stop() {
})
}
-func (d *downloader) Start() (<-chan []byte, <-chan struct{}) {
+func (d *downloader) Start() <-chan []byte {
out := make(chan []byte, 1024)
- done := make(chan struct{}, 1)
go func() {
- defer close(done)
defer close(out)
+ select {
+ case <-d.done:
+ for wavB := range d.pb {
+ wavB.wav.Stop()
+ wavB.cleanup()
+ }
+ return
+ default:
+ }
+
for wavB := range d.pb {
wavB.wav.Start(out)
@@ -78,17 +86,22 @@ func (d *downloader) Start() (<-chan []byte, <-chan struct{}) {
wavB.cleanup()
case <-wavB.wav.Done:
- break
}
}
}()
- return out, done
+ return out
}
func (d *downloader) schedule() {
defer close(d.pb)
for i := 0; ; i++ {
+ select {
+ case <-d.done:
+ return
+ default:
+ }
+
clipStart := time.Duration(i)*clipTime + d.StartTime
clipEnd := time.Duration(i+1)*clipTime + d.StartTime
@@ -107,7 +120,11 @@ func (d *downloader) schedule() {
return
}
- d.pb <- wavb
+ select {
+ case d.pb <- wavb:
+ case <-d.done:
+ return
+ }
}
}