summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Perry <avaglir@gmail.com>2017-07-28 22:13:56 -0400
committerNathan Perry <avaglir@gmail.com>2017-07-28 22:13:56 -0400
commit85d19683f6619150ff949822e1bb118472241d13 (patch)
tree806ca6b689c1ca4e39430685c37939d9ea5a20ad
parentf48248693839d803490ef92fc5ba89e25024ab96 (diff)
downloadmanager working
-rw-r--r--.gitignore2
-rw-r--r--downloader/download_manager.go84
-rw-r--r--downloader/downloader.go14
-rw-r--r--thulani.go24
4 files changed, 96 insertions, 28 deletions
diff --git a/.gitignore b/.gitignore
index d344ba6..5a7d72d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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))
}
diff --git a/thulani.go b/thulani.go
index 3e99c74..fe69338 100644
--- a/thulani.go
+++ b/thulani.go
@@ -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
}