Add asynchronous song download

pull/188/head
RichardNysater 2017-06-04 10:40:18 +02:00
parent 13e880e5ac
commit 44445f2e49
7 changed files with 29 additions and 5 deletions

View File

@ -11,6 +11,7 @@ import (
"time"
"github.com/RichardNysater/mumbledj/interfaces"
"sync"
)
// Track stores all metadata related to an audio track.
@ -27,6 +28,7 @@ type Track struct {
Duration time.Duration
PlaybackOffset time.Duration
Playlist interfaces.Playlist
WaitGroup sync.WaitGroup
}
// GetID returns the ID of the track.
@ -92,3 +94,8 @@ func (t Track) GetPlaybackOffset() time.Duration {
func (t Track) GetPlaylist() interfaces.Playlist {
return t.Playlist
}
// GetWaitGroup returns the WaitGroup the track is associated with.
func(t Track) GetWaitGroup() sync.WaitGroup {
return t.WaitGroup
}

View File

@ -42,13 +42,16 @@ func (yt *YouTubeDL) Download(t interfaces.Track) error {
// Check to see if track is already downloaded.
if _, err := os.Stat(filepath); os.IsNotExist(err) {
var cmd *exec.Cmd
t.GetWaitGroup().Wait()
//waitgroup.wait here
logrus.WithFields(logrus.Fields{
"url": t.GetURL(),
"download-path": filepath,
"format" : format,
"player" : player,
}).Infoln("Downloading track...")
var cmd *exec.Cmd
if t.GetService() == "Mixcloud" {
logrus.Infoln("Downloading from Mixcloud...")
cmd = exec.Command("youtube-dl", "--verbose", "--no-mtime", "--output", filepath, "--format", format, "--external-downloader", "aria2c", player, t.GetURL())
@ -64,7 +67,7 @@ func (yt *YouTubeDL) Download(t interfaces.Track) error {
logrus.Warnf("%s\n%s\nyoutube-dl: %s", args, string(output), err.Error())
return errors.New("Track download failed")
}
t.GetWaitGroup().Done()
if viper.GetBool("cache.enabled") {
DJ.Cache.CheckDirectorySize()
}

View File

@ -81,6 +81,9 @@ func (c *AddCommand) Execute(user *gumble.User, args ...string) (string, bool, e
lastTrackAdded = track
}
}
if DJ.Queue.Length() > 1{ // If the newly added song is not the next to be played then download it
go DJ.YouTubeDL.Download(lastTrackAdded)
}
if numAdded == 0 {
return "", true, errors.New(viper.GetString("commands.add.messages.tracks_too_long_error"))

View File

@ -7,7 +7,10 @@
package interfaces
import "time"
import (
"time"
"sync"
)
// Track is an interface of methods that must be implemented by tracks.
type Track interface {
@ -23,4 +26,5 @@ type Track interface {
GetDuration() time.Duration
GetPlaybackOffset() time.Duration
GetPlaylist() Playlist
GetWaitGroup() sync.WaitGroup
}

View File

@ -18,6 +18,7 @@ import (
"layeh.com/gumble/gumble"
"github.com/RichardNysater/mumbledj/bot"
"github.com/RichardNysater/mumbledj/interfaces"
"sync"
)
// Mixcloud is a wrapper around the Mixcloud API.
@ -92,7 +93,7 @@ func (mc *Mixcloud) GetTracks(url string, submitter *gumble.User) ([]interfaces.
// Track has no artwork, using profile avatar instead.
thumbnail, _ = v.GetString("user", "pictures", "large")
}
var wg sync.WaitGroup
track := bot.Track{
ID: id,
URL: trackURL,
@ -106,6 +107,7 @@ func (mc *Mixcloud) GetTracks(url string, submitter *gumble.User) ([]interfaces.
Duration: duration,
PlaybackOffset: offset,
Playlist: nil,
WaitGroup: wg,
}
tracks = append(tracks, track)

View File

@ -21,6 +21,7 @@ import (
"github.com/RichardNysater/mumbledj/bot"
"github.com/RichardNysater/mumbledj/interfaces"
"github.com/spf13/viper"
"sync"
)
// SoundCloud is a wrapper around the SoundCloud API.
@ -174,7 +175,7 @@ func (sc *SoundCloud) getTrack(obj *jason.Object, offset time.Duration, submitte
// Track has no artwork, using profile avatar instead.
thumbnail, _ = obj.GetString("user", "avatar_url")
}
var wg sync.WaitGroup
return bot.Track{
ID: id,
URL: url,
@ -188,5 +189,6 @@ func (sc *SoundCloud) getTrack(obj *jason.Object, offset time.Duration, submitte
Duration: duration,
PlaybackOffset: offset,
Playlist: nil,
WaitGroup: wg,
}, nil
}

View File

@ -22,6 +22,7 @@ import (
"github.com/RichardNysater/mumbledj/bot"
"github.com/RichardNysater/mumbledj/interfaces"
"github.com/spf13/viper"
"sync"
)
// YouTube is a wrapper around the YouTube Data API.
@ -230,6 +231,7 @@ func (yt *YouTube) getTrack(id string, submitter *gumble.User, offset time.Durat
durationString, _ := item.GetString("contentDetails", "duration")
durationConverted, _ := duration.FromString(durationString)
duration := durationConverted.ToDuration()
var wg sync.WaitGroup
return bot.Track{
ID: id,
@ -243,5 +245,6 @@ func (yt *YouTube) getTrack(id string, submitter *gumble.User, offset time.Durat
Duration: duration,
PlaybackOffset: offset,
Playlist: nil,
WaitGroup: wg,
}, nil
}