summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Perry <avaglir@gmail.com>2017-07-29 17:05:26 -0400
committerNathan Perry <avaglir@gmail.com>2017-07-29 17:05:26 -0400
commit4cd4870a85ed3b3d69d8455faeb7ca466dc42b7b (patch)
treed035f16224bb0a9d756afbee20ad1dc2779dadb6
parenteb12be6f8315973bfb3e39c259c00d325889c32c (diff)
first refactoring pass
-rw-r--r--downloader/download_manager.go132
-rw-r--r--downloader/downloader.go32
2 files changed, 64 insertions, 100 deletions
diff --git a/downloader/download_manager.go b/downloader/download_manager.go
index d6f3fa0..8f9e8a3 100644
--- a/downloader/download_manager.go
+++ b/downloader/download_manager.go
@@ -11,18 +11,15 @@ type DlMessage int
const (
Clear DlMessage = iota
Pause
- Resume
+ Play
)
-type connUpdate int
-
-const (
- attach connUpdate = iota
- detach
-)
+type playBundle struct {
+ data <-chan []byte
+ conn *discordgo.VoiceConnection
+}
type DownloadManager struct {
- conn *discordgo.VoiceConnection
session *discordgo.Session
guildID string
voiceID string
@@ -32,25 +29,23 @@ type DownloadManager struct {
playStateChan chan DlMessage
proxyStateChan chan DlMessage
- connUpdate chan connUpdate
- proxyChan chan []byte
+ proxyChan chan playBundle
}
const proxyBufSize = 512
func NewManager(s *discordgo.Session, guildID string, voiceChanID string) *DownloadManager {
dm := &DownloadManager{
- session: s,
- dls: make(chan *downloader),
- connUpdate: make(chan connUpdate, 1),
- PlayState: make(chan DlMessage),
- guildID: guildID,
- voiceID: voiceChanID,
+ session: s,
+ dls: make(chan *downloader),
+ PlayState: make(chan DlMessage),
+ guildID: guildID,
+ voiceID: voiceChanID,
playStateChan: make(chan DlMessage),
proxyStateChan: make(chan DlMessage),
- proxyChan: make(chan []byte, proxyBufSize),
+ proxyChan: make(chan playBundle),
}
go dm.teeStateMessages()
@@ -68,88 +63,55 @@ func (m *DownloadManager) teeStateMessages() {
}
func (m *DownloadManager) proxyOpusPackets() {
- attachState := detach
- playState := Resume
- clear := false
-
loop:
- for {
- if playState == Pause {
- select {
- case playState = <-m.proxyStateChan:
- continue loop
- }
- }
+ for bundle := range m.proxyChan {
+ playState := Play
+ bundle.conn.Speaking(true)
- select { // first check if we have a state update message coming in
- case playState = <-m.proxyStateChan:
- continue loop
- default:
+ cleanup := func() {
+ bundle.conn.Speaking(false)
+ bundle.conn.Disconnect()
}
- // if we're clearing, empty
- if clear {
- for {
- select {
- case <-m.proxyChan:
+ for {
+ switch playState {
+ case Clear:
+ for {
+ select {
+ case <-m.proxyChan:
+ default:
+ }
+ }
+ cleanup()
+ continue loop
+ case Pause:
+ playState = <-m.proxyStateChan
+ case Play:
+ select { // first check if we have a state update message coming in
case playState = <-m.proxyStateChan:
- continue loop
- default:
+ case bundle.conn.OpusSend <- <-bundle.data:
}
}
}
-
- select {
- case upd := <-m.connUpdate:
- attachState = upd
- default:
- }
-
- if attachState == attach {
- select {
- case attachState = <-m.connUpdate:
- case m.conn.OpusSend <- <-m.proxyChan:
- }
- } else {
- select {
- case attachState = <-m.connUpdate:
- }
- }
+ cleanup()
}
}
func (m *DownloadManager) playFromQueue() {
- //timer := time.After(5*time.Second)
-
- for {
- select {
- case dl := <-m.dls:
- if m.conn == nil {
- ch, 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
- }
-
- m.conn = ch
- m.connUpdate <- attach
- }
+ for dl := range m.dls {
+ ch, 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
+ }
- m.conn.Speaking(true)
- // todo: figure out how to do disconnection checking
- dl.SendOn(m.proxyChan)
- <-dl.done
- m.conn.Speaking(false)
- //case <-timer:
- // if m.conn != nil {
- // m.connUpdate<-detach
- // if err := m.conn.Disconnect(); err != nil {
- // log.Errorf("disconnecting from voice connection: %q", err)
- // }
- // m.conn = nil
- // }
+ out, done := dl.Start()
+ m.proxyChan <- playBundle{
+ data: out,
+ conn: ch,
}
+ <-done
}
}
diff --git a/downloader/downloader.go b/downloader/downloader.go
index c9fc864..6abe7f0 100644
--- a/downloader/downloader.go
+++ b/downloader/downloader.go
@@ -15,9 +15,9 @@ import (
type downloader struct {
Url string
- Start time.Duration
- Duration time.Duration
- End time.Duration
+ StartTime time.Duration
+ Duration time.Duration
+ EndTime time.Duration
once sync.Once
done chan struct{}
@@ -42,9 +42,9 @@ func newDownload(url string, startTime, dur time.Duration) (*downloader, error)
dl := &downloader{
Url: url,
- Start: startTime,
- Duration: dur,
- End: startTime + dur,
+ StartTime: startTime,
+ Duration: dur,
+ EndTime: startTime + dur,
done: make(chan struct{}, 1),
pb: make(chan *wavBundle, preloadCount),
@@ -62,13 +62,15 @@ func (d *downloader) Stop() {
})
}
-func (d *downloader) SendOn(ch chan<- []byte) <-chan struct{} {
- out := make(chan struct{}, 1)
+func (d *downloader) Start() (<-chan []byte, <-chan struct{}) {
+ out := make(chan []byte, 1024)
+ done := make(chan struct{}, 1)
go func() {
+ defer close(done)
defer close(out)
for wavB := range d.pb {
- wavB.wav.Start(ch)
+ wavB.wav.Start(out)
select {
case <-d.done:
@@ -81,22 +83,22 @@ func (d *downloader) SendOn(ch chan<- []byte) <-chan struct{} {
}
}()
- return out
+ return out, done
}
func (d *downloader) schedule() {
defer close(d.pb)
for i := 0; ; i++ {
- clipStart := time.Duration(i)*clipTime + d.Start
- clipEnd := time.Duration(i+1)*clipTime + d.Start
+ clipStart := time.Duration(i)*clipTime + d.StartTime
+ clipEnd := time.Duration(i+1)*clipTime + d.StartTime
- if clipStart >= d.End {
+ if clipStart >= d.EndTime {
return
}
dur := clipTime
- if clipEnd > d.End {
- dur = d.End - clipStart
+ if clipEnd > d.EndTime {
+ dur = d.EndTime - clipStart
}
wavb, err := d.downloadSegment(clipStart, dur)