diff options
| author | Nathan Perry <avaglir@gmail.com> | 2017-07-28 22:13:56 -0400 |
|---|---|---|
| committer | Nathan Perry <avaglir@gmail.com> | 2017-07-28 22:13:56 -0400 |
| commit | 85d19683f6619150ff949822e1bb118472241d13 (patch) | |
| tree | 806ca6b689c1ca4e39430685c37939d9ea5a20ad | |
| parent | f48248693839d803490ef92fc5ba89e25024ab96 (diff) | |
downloadmanager working
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | downloader/download_manager.go | 84 | ||||
| -rw-r--r-- | downloader/downloader.go | 14 | ||||
| -rw-r--r-- | thulani.go | 24 |
4 files changed, 96 insertions, 28 deletions
@@ -1 +1,3 @@ config.json +*.pprof +main diff --git a/downloader/download_manager.go b/downloader/download_manager.go index fb7e883..004efc1 100644 --- a/downloader/download_manager.go +++ b/downloader/download_manager.go @@ -1,15 +1,89 @@ package downloader +import ( + "time" +) + // DownloadManager handles a download for a particular song. type DownloadManager struct { Url string - dlChans []<-chan []byte + Start time.Duration + Duration time.Duration + End time.Duration + + pb chan (<-chan []byte) + + info videoInfo } -func NewDownload(url string) DownloadManager { - return DownloadManager{ - Url: url, - dlChans: []<-chan []byte{}, +const clipTime = 10 * time.Second +const preloadCount = 5 + +func NewDownload(url string, startTime, dur time.Duration) (*DownloadManager, error) { + vInfo, err := info(url) + if err != nil { + return nil, err + } + + if dur == 0 { + dur = vInfo.Duration - startTime } + + dl := &DownloadManager{ + Url: url, + + Start: startTime, + Duration: dur, + End: startTime + dur, + + pb: make(chan (<-chan []byte), preloadCount), + info: *vInfo, + } + + go dl.schedule() + + return dl, nil +} + +func (d *DownloadManager) SendOn(ch chan<- []byte) <-chan struct{} { + out := make(chan struct{}, 1) + + go func() { + defer close(out) + for c := range d.pb { + for b := range c { + ch <- b + } + } + }() + + return out +} + +func (d *DownloadManager) schedule() { + go func() { + defer close(d.pb) + for i := 0; ; i++ { + clipStart := time.Duration(i)*clipTime + d.Start + clipEnd := time.Duration(i+1)*clipTime + d.Start + + if clipStart >= d.End { + return + } + + dur := clipTime + if clipEnd > d.End { + dur = d.End - clipStart + } + + ch, err := d.download(clipStart, dur) + if err != nil { + log.Errorf("error setting up download: %q", err) + return + } + + d.pb <- ch + } + }() } diff --git a/downloader/downloader.go b/downloader/downloader.go index 793cd22..95c022f 100644 --- a/downloader/downloader.go +++ b/downloader/downloader.go @@ -75,18 +75,11 @@ func info(inUrl string) (*videoInfo, error) { return &v, err } -func Download(inUrl string, startTime time.Duration, duration time.Duration) (<-chan []byte, error) { - vInfo, err := info(inUrl) - if err != nil { - return nil, err - } - +func (d *DownloadManager) download(startTime, duration time.Duration) (<-chan []byte, error) { startSecond := int(startTime.Seconds()) - dur := int(duration.Seconds()) - args := []string{ "-ss", strconv.Itoa(startSecond), - "-i", vInfo.Url.String(), + "-i", d.info.Url.String(), "-c:a", "pcm_s16le", "-f", "wav", "-ar", "48000", @@ -94,7 +87,8 @@ func Download(inUrl string, startTime time.Duration, duration time.Duration) (<- "-vn", "-y", } - if dur > 0 { + dur := int(duration.Seconds()) + if dur > 0 && startTime+duration < d.info.Duration { args = append(args, "-t", strconv.Itoa(dur)) } @@ -1,17 +1,15 @@ package thulani import ( + "math/rand" "net/url" "os" "os/signal" "regexp" "strings" "syscall" - "time" - "math/rand" - "github.com/bwmarrin/discordgo" "github.com/mammothbane/thulani-go/downloader" ) @@ -20,6 +18,8 @@ var config *Config var regex *regexp.Regexp func Run(conf *Config) { + //defer profile.Start(profile.ProfilePath("."), profile.BlockProfile).Stop() + config = conf regex = regexp.MustCompile(`(?i)^[!/]` + conf.Trigger + " (.*)") @@ -112,20 +112,18 @@ func onMessage(s *discordgo.Session, m *discordgo.MessageCreate) { break } - ch, err := downloader.Download("https://www.youtube.com/watch?v=_K13GJkGvDw", time.Duration(rand.Intn(10*60))*time.Second, 5*time.Second) - if err != nil { - log.Errorf("unable to download video: %q", err) - break - } - conn.Speaking(true) - go func() { + go func(conn *discordgo.VoiceConnection) { defer conn.Speaking(false) - for i := range ch { - conn.OpusSend <- i + dl, err := downloader.NewDownload("https://www.youtube.com/watch?v=_K13GJkGvDw", time.Duration(rand.Intn(10*60))*time.Second, 5*time.Second) + if err != nil { + log.Errorf("unable to download video: %q", err) + return } - }() + + <-dl.SendOn(conn.OpusSend) + }(conn) break } |
