diff options
| author | Nathan Perry <avaglir@gmail.com> | 2017-07-29 17:05:26 -0400 |
|---|---|---|
| committer | Nathan Perry <avaglir@gmail.com> | 2017-07-29 17:05:26 -0400 |
| commit | 4cd4870a85ed3b3d69d8455faeb7ca466dc42b7b (patch) | |
| tree | d035f16224bb0a9d756afbee20ad1dc2779dadb6 | |
| parent | eb12be6f8315973bfb3e39c259c00d325889c32c (diff) | |
first refactoring pass
| -rw-r--r-- | downloader/download_manager.go | 132 | ||||
| -rw-r--r-- | downloader/downloader.go | 32 |
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) |
