Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Stein Ivar Berghei | 8aa79a1e13 |
47
bot.go
47
bot.go
|
@ -9,17 +9,9 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/diamondburned/arikawa/v3/state"
|
|
||||||
"github.com/diamondburned/arikawa/v3/voice"
|
|
||||||
"github.com/faiface/beep"
|
|
||||||
"github.com/fhs/gompd/v2/mpd"
|
|
||||||
"github.com/gohugoio/hugo/cache/filecache"
|
"github.com/gohugoio/hugo/cache/filecache"
|
||||||
"github.com/jackc/pgx/v5"
|
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
"github.com/kataras/go-events"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"google.golang.org/api/youtube/v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -30,8 +22,9 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
app = new(App)
|
|
||||||
config = viper.GetViper()
|
config = viper.GetViper()
|
||||||
|
bfs = afero.NewBasePathFs(afero.NewOsFs(), "cache")
|
||||||
|
cache = filecache.NewCache(bfs, 1*time.Hour, "")
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -46,34 +39,12 @@ func init() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.plmutex = &sync.Mutex{}
|
mpd_mutex = &sync.Mutex{}
|
||||||
|
|
||||||
log.Println("bot.go done.")
|
log.Println("bot.go done.")
|
||||||
}
|
}
|
||||||
|
|
||||||
type App struct {
|
|
||||||
discord *state.State
|
|
||||||
voice *voice.Session
|
|
||||||
youtube *youtube.Service
|
|
||||||
ambiance beep.Mixer
|
|
||||||
curamb Ambiance
|
|
||||||
events events.EventEmmiter
|
|
||||||
db *pgx.Conn
|
|
||||||
router *httprouter.Router
|
|
||||||
active []string
|
|
||||||
plidx int
|
|
||||||
cache *filecache.Cache
|
|
||||||
mpdc context.CancelFunc
|
|
||||||
mpdw *mpd.Watcher
|
|
||||||
mpd *mpd.Client
|
|
||||||
plmutex *sync.Mutex
|
|
||||||
plcancel context.CancelFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
bfs := afero.NewBasePathFs(afero.NewOsFs(), "cache")
|
|
||||||
app.cache = filecache.NewCache(bfs, 1*time.Hour, "")
|
|
||||||
|
|
||||||
ticker := time.NewTicker(300 * time.Millisecond)
|
ticker := time.NewTicker(300 * time.Millisecond)
|
||||||
|
|
||||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
||||||
|
@ -82,15 +53,15 @@ func main() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
app.db.Close(ctx)
|
db.Close(ctx)
|
||||||
app.mpdw.Close()
|
mpdw.Close()
|
||||||
app.mpdc()
|
mpdcf()
|
||||||
app.voice.Leave(ctx)
|
dvoice.Leave(ctx)
|
||||||
dgvc()
|
dgvc()
|
||||||
app.discord.Close()
|
dstate.Close()
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
app.events.Emit("tick")
|
ev.Emit("tick")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
db.go
16
db.go
|
@ -8,11 +8,13 @@ import (
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var db *pgx.Conn
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.Println("db.go loading..")
|
log.Println("db.go loading..")
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
app.db, err = pgx.Connect(context.Background(), config.GetString("db.connstring"))
|
db, err = pgx.Connect(context.Background(), config.GetString("db.connstring"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -25,8 +27,8 @@ type Playlist struct {
|
||||||
Title string
|
Title string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app App) GetPlaylists() (playlists []Playlist, err error) {
|
func GetPlaylists() (playlists []Playlist, err error) {
|
||||||
rows, err := app.db.Query(context.Background(), "SELECT id, url, title FROM playlists")
|
rows, err := db.Query(context.Background(), "SELECT id, url, title FROM playlists")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -35,8 +37,8 @@ func (app App) GetPlaylists() (playlists []Playlist, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app App) GetPlaylist(id uuid.UUID) (*Playlist, error) {
|
func GetPlaylist(id uuid.UUID) (*Playlist, error) {
|
||||||
rows, err := app.db.Query(context.Background(), "SELECT id, url, title FROM playlists where id=$1 limit 1", id)
|
rows, err := db.Query(context.Background(), "SELECT id, url, title FROM playlists where id=$1 limit 1", id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -50,9 +52,9 @@ func (app App) GetPlaylist(id uuid.UUID) (*Playlist, error) {
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app App) AddPlaylist(title string, uri string) (uuid.UUID, error) {
|
func AddPlaylist(title string, uri string) (uuid.UUID, error) {
|
||||||
id := uuid.New()
|
id := uuid.New()
|
||||||
_, err := app.db.Exec(context.Background(), "INSERT INTO playlists VALUES ($1, $2, $3)", id, title, uri)
|
_, err := db.Exec(context.Background(), "INSERT INTO playlists VALUES ($1, $2, $3)", id, title, uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return *new(uuid.UUID), err
|
return *new(uuid.UUID), err
|
||||||
}
|
}
|
||||||
|
|
10
discord.go
10
discord.go
|
@ -11,7 +11,11 @@ import (
|
||||||
"github.com/diamondburned/arikawa/v3/voice/voicegateway"
|
"github.com/diamondburned/arikawa/v3/voice/voicegateway"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dgvc context.CancelFunc
|
var (
|
||||||
|
dstate *state.State
|
||||||
|
dvoice *voice.Session
|
||||||
|
dgvc context.CancelFunc
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.Println("discord.go loading..")
|
log.Println("discord.go loading..")
|
||||||
|
@ -47,8 +51,8 @@ func init() {
|
||||||
|
|
||||||
v.Speaking(ctx, voicegateway.NotSpeaking)
|
v.Speaking(ctx, voicegateway.NotSpeaking)
|
||||||
|
|
||||||
app.discord = s
|
dstate = s
|
||||||
app.voice = v
|
dvoice = v
|
||||||
|
|
||||||
discordspeaker.Init(v)
|
discordspeaker.Init(v)
|
||||||
|
|
||||||
|
|
162
events.go
162
events.go
|
@ -30,40 +30,46 @@ type SongInfo struct {
|
||||||
Song string `json:"song,omitempty"`
|
Song string `json:"song,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var l = rate.Sometimes{Interval: 800 * time.Millisecond}
|
var (
|
||||||
|
l = rate.Sometimes{Interval: 800 * time.Millisecond}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ev events.EventEmmiter
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.Println("events.go loading...")
|
log.Println("events.go loading...")
|
||||||
|
|
||||||
app.events = events.New()
|
ev = events.New()
|
||||||
|
|
||||||
app.events.On("load_playlist", app.loadPlaylist)
|
ev.On("load_playlist", loadPlaylist)
|
||||||
app.events.On("add_playlist", app.addPlaylist)
|
ev.On("add_playlist", addPlaylist)
|
||||||
|
|
||||||
//app.events.On("preload_song", app.preloadSong)
|
//ev.On("preload_song", app.preloadSong)
|
||||||
//app.events.On("song_over", app.songInfo)
|
//ev.On("song_over", app.songInfo)
|
||||||
//app.events.On("song_start", app.songInfo)
|
//ev.On("song_start", app.songInfo)
|
||||||
app.events.On("player", app.songInfo)
|
ev.On("player", songInfo)
|
||||||
//app.events.On("song_position", app.songPosition)
|
//ev.On("song_position", app.songPosition)
|
||||||
|
|
||||||
app.events.On("ambiance_play", app.ambiancePlay)
|
ev.On("ambiance_play", ambiancePlay)
|
||||||
app.events.On("ambiance_stop", app.ambianceStop)
|
ev.On("ambiance_stop", ambianceStop)
|
||||||
app.events.On("ambiance_add", app.ambianceAdd)
|
ev.On("ambiance_add", ambianceAdd)
|
||||||
|
|
||||||
app.events.On("stop", app.stop)
|
ev.On("stop", stop)
|
||||||
app.events.On("next", app.nextSong)
|
ev.On("next", nextSong)
|
||||||
app.events.On("prev", app.prevSong)
|
ev.On("prev", prevSong)
|
||||||
|
|
||||||
app.events.On("vol_up", app.volup)
|
ev.On("vol_up", volup)
|
||||||
app.events.On("vol_down", app.voldown)
|
ev.On("vol_down", voldown)
|
||||||
app.events.On("vol_set", app.volset)
|
ev.On("vol_set", volset)
|
||||||
|
|
||||||
//app.events.On("tick", app.checkQueue)
|
//ev.On("tick", app.checkQueue)
|
||||||
app.events.On("tick", app.songPosition)
|
ev.On("tick", songPosition)
|
||||||
//app.events.On("tick", app.checkTimeleft)
|
//ev.On("tick", app.checkTimeleft)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) volup(payload ...interface{}) {
|
func volup(payload ...interface{}) {
|
||||||
if !(len(payload) > 0) {
|
if !(len(payload) > 0) {
|
||||||
log.Println("volup called without a payload.")
|
log.Println("volup called without a payload.")
|
||||||
return
|
return
|
||||||
|
@ -91,7 +97,7 @@ func (app *App) volup(payload ...interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) voldown(payload ...interface{}) {
|
func voldown(payload ...interface{}) {
|
||||||
if !(len(payload) > 0) {
|
if !(len(payload) > 0) {
|
||||||
log.Println("voldown called without a payload.")
|
log.Println("voldown called without a payload.")
|
||||||
return
|
return
|
||||||
|
@ -119,7 +125,7 @@ func (app *App) voldown(payload ...interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) volset(payload ...interface{}) {
|
func volset(payload ...interface{}) {
|
||||||
if !(len(payload) > 0) {
|
if !(len(payload) > 0) {
|
||||||
log.Println("volset called without a payload.")
|
log.Println("volset called without a payload.")
|
||||||
return
|
return
|
||||||
|
@ -147,10 +153,10 @@ func (app *App) volset(payload ...interface{}) {
|
||||||
amb_volume.Volume = vol
|
amb_volume.Volume = vol
|
||||||
}
|
}
|
||||||
|
|
||||||
app.sendVolume()
|
sendVolume()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) sendVolume() {
|
func sendVolume() {
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
out := make(map[string]float64)
|
out := make(map[string]float64)
|
||||||
msg["event"] = "volume"
|
msg["event"] = "volume"
|
||||||
|
@ -160,16 +166,16 @@ func (app *App) sendVolume() {
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) songInfoEvent(event string) map[string]interface{} {
|
func songInfoEvent(event string) map[string]interface{} {
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
msg["event"] = event
|
msg["event"] = event
|
||||||
status, err := app.mpd.Status()
|
status, err := mpdc.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cur, err := app.mpd.CurrentSong()
|
cur, err := mpdc.CurrentSong()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return nil
|
return nil
|
||||||
|
@ -211,7 +217,7 @@ func (app *App) songInfoEvent(event string) map[string]interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
pl, err := app.GetPlaylist(plid)
|
pl, err := GetPlaylist(plid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return nil
|
return nil
|
||||||
|
@ -241,7 +247,7 @@ func (app *App) songInfoEvent(event string) map[string]interface{} {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) ambiancePlay(payload ...interface{}) {
|
func ambiancePlay(payload ...interface{}) {
|
||||||
if !(len(payload) > 0) {
|
if !(len(payload) > 0) {
|
||||||
log.Println("ambiance_play called without a payload.")
|
log.Println("ambiance_play called without a payload.")
|
||||||
return
|
return
|
||||||
|
@ -289,14 +295,14 @@ func (app *App) ambiancePlay(payload ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
discordspeaker.Lock()
|
discordspeaker.Lock()
|
||||||
app.ambiance.Clear()
|
amb_mixer.Clear()
|
||||||
app.ambiance.Add(volume)
|
amb_mixer.Add(volume)
|
||||||
discordspeaker.Unlock()
|
discordspeaker.Unlock()
|
||||||
|
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
out := make(map[string]interface{})
|
out := make(map[string]interface{})
|
||||||
|
|
||||||
app.curamb = amb
|
amb_curr = amb
|
||||||
|
|
||||||
msg["event"] = "ambiance_play"
|
msg["event"] = "ambiance_play"
|
||||||
out["id"] = id
|
out["id"] = id
|
||||||
|
@ -304,10 +310,10 @@ func (app *App) ambiancePlay(payload ...interface{}) {
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) ambianceStop(payload ...interface{}) {
|
func ambianceStop(payload ...interface{}) {
|
||||||
log.Println("Stopping ambiance")
|
log.Println("Stopping ambiance")
|
||||||
discordspeaker.Lock()
|
discordspeaker.Lock()
|
||||||
app.ambiance.Clear()
|
amb_mixer.Clear()
|
||||||
discordspeaker.Unlock()
|
discordspeaker.Unlock()
|
||||||
|
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
|
@ -316,7 +322,7 @@ func (app *App) ambianceStop(payload ...interface{}) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) ambianceAdd(payload ...interface{}) {
|
func ambianceAdd(payload ...interface{}) {
|
||||||
if !(len(payload) > 0) {
|
if !(len(payload) > 0) {
|
||||||
log.Println("addPlaylist called without a payload.")
|
log.Println("addPlaylist called without a payload.")
|
||||||
return
|
return
|
||||||
|
@ -359,8 +365,8 @@ func (app *App) ambianceAdd(payload ...interface{}) {
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) songPosition(payload ...interface{}) {
|
func songPosition(payload ...interface{}) {
|
||||||
status, err := app.mpd.Status()
|
status, err := mpdc.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
|
@ -395,24 +401,24 @@ func (app *App) songPosition(payload ...interface{}) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) songInfo(payload ...interface{}) {
|
func songInfo(payload ...interface{}) {
|
||||||
log.Println("song_info event received")
|
log.Println("song_info event received")
|
||||||
|
|
||||||
msg := app.songInfoEvent("song_info")
|
msg := songInfoEvent("song_info")
|
||||||
if msg != nil {
|
if msg != nil {
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) stop(payload ...interface{}) {
|
func stop(payload ...interface{}) {
|
||||||
log.Println("stop event received")
|
log.Println("stop event received")
|
||||||
|
|
||||||
app.plmutex.Lock()
|
mpd_mutex.Lock()
|
||||||
if app.plcancel != nil {
|
if mpd_plcf != nil {
|
||||||
app.plcancel()
|
mpd_plcf()
|
||||||
}
|
}
|
||||||
app.mpd.Stop()
|
mpdc.Stop()
|
||||||
app.plmutex.Unlock()
|
mpd_mutex.Unlock()
|
||||||
|
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
msg["event"] = "stop"
|
msg["event"] = "stop"
|
||||||
|
@ -420,28 +426,28 @@ func (app *App) stop(payload ...interface{}) {
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) prevSong(payload ...interface{}) {
|
func prevSong(payload ...interface{}) {
|
||||||
log.Println("prev_song event received")
|
log.Println("prev_song event received")
|
||||||
app.plmutex.Lock()
|
mpd_mutex.Lock()
|
||||||
err := app.mpd.Previous()
|
err := mpdc.Previous()
|
||||||
app.plmutex.Unlock()
|
mpd_mutex.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) nextSong(payload ...interface{}) {
|
func nextSong(payload ...interface{}) {
|
||||||
log.Println("next_song event received")
|
log.Println("next_song event received")
|
||||||
|
|
||||||
app.plmutex.Lock()
|
mpd_mutex.Lock()
|
||||||
err := app.mpd.Next()
|
err := mpdc.Next()
|
||||||
app.plmutex.Unlock()
|
mpd_mutex.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) addPlaylist(payload ...interface{}) {
|
func addPlaylist(payload ...interface{}) {
|
||||||
if !(len(payload) > 0) {
|
if !(len(payload) > 0) {
|
||||||
log.Println("addPlaylist called without a payload.")
|
log.Println("addPlaylist called without a payload.")
|
||||||
return
|
return
|
||||||
|
@ -481,12 +487,12 @@ func (app *App) addPlaylist(payload ...interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = app.Playlist(plid)
|
_, err = YTPlaylist(plid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error getting youtube playlist info,", plid)
|
log.Println("Error getting youtube playlist info,", plid)
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := app.AddPlaylist(pltitle, plid)
|
id, err := AddPlaylist(pltitle, plid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error getting youtube playlist info,", plid)
|
log.Println("Error getting youtube playlist info,", plid)
|
||||||
}
|
}
|
||||||
|
@ -499,7 +505,7 @@ func (app *App) addPlaylist(payload ...interface{}) {
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) loadPlaylist(payload ...interface{}) {
|
func loadPlaylist(payload ...interface{}) {
|
||||||
log.Println("load_playlist event received")
|
log.Println("load_playlist event received")
|
||||||
|
|
||||||
if !(len(payload) > 0) {
|
if !(len(payload) > 0) {
|
||||||
|
@ -526,13 +532,13 @@ func (app *App) loadPlaylist(payload ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Loading new playlist: ", id)
|
log.Println("Loading new playlist: ", id)
|
||||||
pl, err := app.GetPlaylist(id)
|
pl, err := GetPlaylist(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to find playlist with id,", id)
|
log.Println("Unable to find playlist with id,", id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
list, err := app.Playlist(pl.Url)
|
list, err := YTPlaylist(pl.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error getting playlist info,", id)
|
log.Println("Error getting playlist info,", id)
|
||||||
return
|
return
|
||||||
|
@ -543,16 +549,16 @@ func (app *App) loadPlaylist(payload ...interface{}) {
|
||||||
log.Println("Unable to shuffle playlist")
|
log.Println("Unable to shuffle playlist")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.plmutex.Lock()
|
mpd_mutex.Lock()
|
||||||
if app.plcancel != nil {
|
if mpd_plcf != nil {
|
||||||
app.plcancel()
|
mpd_plcf()
|
||||||
}
|
}
|
||||||
app.mpd.Stop()
|
mpdc.Stop()
|
||||||
app.mpd.Clear()
|
mpdc.Clear()
|
||||||
app.plmutex.Unlock()
|
mpd_mutex.Unlock()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
app.plcancel = cancel
|
mpd_plcf = cancel
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -560,13 +566,13 @@ func (app *App) loadPlaylist(payload ...interface{}) {
|
||||||
for _, vid := range list {
|
for _, vid := range list {
|
||||||
log.Printf("Adding %s", vid)
|
log.Printf("Adding %s", vid)
|
||||||
|
|
||||||
ytinfo, err := app.Video(vid)
|
ytinfo, err := YTVideo(vid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
_, yt, err := app.cache.GetOrCreateBytes(vid+".txt", func() ([]byte, error) {
|
_, yt, err := cache.GetOrCreateBytes(vid+".txt", func() ([]byte, error) {
|
||||||
uri, err := NewYTdl(vid)
|
uri, err := NewYTdl(vid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -580,8 +586,8 @@ func (app *App) loadPlaylist(payload ...interface{}) {
|
||||||
|
|
||||||
// Run as a local function so we can defer the mutex unlock incase one of these errors.
|
// Run as a local function so we can defer the mutex unlock incase one of these errors.
|
||||||
ok := func() (ok bool) {
|
ok := func() (ok bool) {
|
||||||
app.plmutex.Lock()
|
mpd_mutex.Lock()
|
||||||
defer app.plmutex.Unlock()
|
defer mpd_mutex.Unlock()
|
||||||
|
|
||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
return false
|
return false
|
||||||
|
@ -590,41 +596,41 @@ func (app *App) loadPlaylist(payload ...interface{}) {
|
||||||
ok = true
|
ok = true
|
||||||
|
|
||||||
// state:stop
|
// state:stop
|
||||||
songid, err := app.mpd.AddID(string(yt), 0)
|
songid, err := mpdc.AddID(string(yt), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mpdcmd := app.mpd.Command("%s %d %s %s", mpd.Quoted("addtagid"), songid, mpd.Quoted("artist"), ytinfo.Channel)
|
mpdcmd := mpdc.Command("%s %d %s %s", mpd.Quoted("addtagid"), songid, mpd.Quoted("artist"), ytinfo.Channel)
|
||||||
err = mpdcmd.OK()
|
err = mpdcmd.OK()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mpdcmd = app.mpd.Command("%s %d %s %s", mpd.Quoted("addtagid"), songid, mpd.Quoted("title"), ytinfo.Title)
|
mpdcmd = mpdc.Command("%s %d %s %s", mpd.Quoted("addtagid"), songid, mpd.Quoted("title"), ytinfo.Title)
|
||||||
err = mpdcmd.OK()
|
err = mpdcmd.OK()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mpdcmd = app.mpd.Command("%s %d %s %s", mpd.Quoted("addtagid"), songid, mpd.Quoted("location"), vid)
|
mpdcmd = mpdc.Command("%s %d %s %s", mpd.Quoted("addtagid"), songid, mpd.Quoted("location"), vid)
|
||||||
err = mpdcmd.OK()
|
err = mpdcmd.OK()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mpdcmd = app.mpd.Command("%s %d %s %s", mpd.Quoted("addtagid"), songid, mpd.Quoted("album"), pl.Id.String())
|
mpdcmd = mpdc.Command("%s %d %s %s", mpd.Quoted("addtagid"), songid, mpd.Quoted("album"), pl.Id.String())
|
||||||
err = mpdcmd.OK()
|
err = mpdcmd.OK()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mpd.Play(-1)
|
mpdc.Play(-1)
|
||||||
|
|
||||||
return
|
return
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/faiface/beep"
|
||||||
|
"github.com/faiface/beep/effects"
|
||||||
|
|
||||||
|
"dndmusicbot/ffmpeg"
|
||||||
|
discordspeaker "dndmusicbot/speaker"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
pl_volume *effects.Volume
|
||||||
|
amb_volume *effects.Volume
|
||||||
|
amb_mixer beep.Mixer
|
||||||
|
amb_curr Ambiance
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.Println("queue.go loading..")
|
||||||
|
|
||||||
|
amb_mixer = beep.Mixer{}
|
||||||
|
|
||||||
|
amb_volume = &effects.Volume{
|
||||||
|
Streamer: &amb_mixer,
|
||||||
|
Base: 2,
|
||||||
|
Volume: 2,
|
||||||
|
Silent: false,
|
||||||
|
}
|
||||||
|
discordspeaker.Play(amb_volume)
|
||||||
|
|
||||||
|
mpdstream, err := NewMPD()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pl_volume = &effects.Volume{
|
||||||
|
Streamer: mpdstream,
|
||||||
|
Base: 2,
|
||||||
|
Volume: -2,
|
||||||
|
Silent: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
discordspeaker.Play(pl_volume)
|
||||||
|
|
||||||
|
/*
|
||||||
|
app.queue = new(Queue)
|
||||||
|
app.queue.list = list.New()
|
||||||
|
app.queue.Events = app.events
|
||||||
|
discordspeaker.Play(app.queue)
|
||||||
|
*/
|
||||||
|
|
||||||
|
log.Println("queue.go done.")
|
||||||
|
}
|
||||||
|
|
||||||
|
type Song struct {
|
||||||
|
Title string
|
||||||
|
Channel string
|
||||||
|
VideoID string
|
||||||
|
Length time.Duration
|
||||||
|
PCM *ffmpeg.PCM
|
||||||
|
Playlist Playlist
|
||||||
|
DLuri string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Song) NewStream() (err error) {
|
||||||
|
s.PCM, err = ffmpeg.NewPCM(s.DLuri, sampleRate, channels)
|
||||||
|
return
|
||||||
|
}
|
27
mpd.go
27
mpd.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
@ -21,6 +22,14 @@ type MPD struct {
|
||||||
f beep.Format
|
f beep.Format
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
mpdcf context.CancelFunc
|
||||||
|
mpdw *mpd.Watcher
|
||||||
|
mpdc *mpd.Client
|
||||||
|
mpd_mutex *sync.Mutex
|
||||||
|
mpd_plcf context.CancelFunc
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.Println("mpd.go loading..")
|
log.Println("mpd.go loading..")
|
||||||
|
|
||||||
|
@ -62,7 +71,7 @@ func init() {
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
app.mpdc = cancel
|
mpdcf = cancel
|
||||||
|
|
||||||
cmd := exec.CommandContext(
|
cmd := exec.CommandContext(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -86,20 +95,20 @@ func init() {
|
||||||
// wait for mpd to start.
|
// wait for mpd to start.
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
app.mpd, err = mpd.Dial("unix", config.GetString("mpd.sock"))
|
mpdc, err = mpd.Dial("unix", config.GetString("mpd.sock"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mpd.Repeat(true)
|
mpdc.Repeat(true)
|
||||||
app.mpd.Random(true)
|
mpdc.Random(true)
|
||||||
|
|
||||||
err = app.mpd.EnableOutput(0)
|
err = mpdc.EnableOutput(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mpdw, err = mpd.NewWatcher("unix", config.GetString("mpd.sock"), "")
|
mpdw, err = mpd.NewWatcher("unix", config.GetString("mpd.sock"), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -107,9 +116,9 @@ func init() {
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case ev := <-app.mpdw.Event:
|
case e := <-mpdw.Event:
|
||||||
app.events.Emit(events.EventName(ev))
|
ev.Emit(events.EventName(e))
|
||||||
case err := <-app.mpdw.Error:
|
case err := <-mpdw.Error:
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
203
queue.go
203
queue.go
|
@ -1,203 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"container/list"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/faiface/beep"
|
|
||||||
"github.com/faiface/beep/effects"
|
|
||||||
"github.com/kataras/go-events"
|
|
||||||
|
|
||||||
"dndmusicbot/ffmpeg"
|
|
||||||
discordspeaker "dndmusicbot/speaker"
|
|
||||||
)
|
|
||||||
|
|
||||||
var pl_volume *effects.Volume
|
|
||||||
var amb_volume *effects.Volume
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.Println("queue.go loading..")
|
|
||||||
|
|
||||||
app.ambiance = beep.Mixer{}
|
|
||||||
|
|
||||||
amb_volume = &effects.Volume{
|
|
||||||
Streamer: &app.ambiance,
|
|
||||||
Base: 2,
|
|
||||||
Volume: 2,
|
|
||||||
Silent: false,
|
|
||||||
}
|
|
||||||
discordspeaker.Play(amb_volume)
|
|
||||||
|
|
||||||
mpdstream, err := NewMPD()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pl_volume = &effects.Volume{
|
|
||||||
Streamer: mpdstream,
|
|
||||||
Base: 2,
|
|
||||||
Volume: -2,
|
|
||||||
Silent: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
discordspeaker.Play(pl_volume)
|
|
||||||
|
|
||||||
/*
|
|
||||||
app.queue = new(Queue)
|
|
||||||
app.queue.list = list.New()
|
|
||||||
app.queue.Events = app.events
|
|
||||||
discordspeaker.Play(app.queue)
|
|
||||||
*/
|
|
||||||
|
|
||||||
log.Println("queue.go done.")
|
|
||||||
}
|
|
||||||
|
|
||||||
type Song struct {
|
|
||||||
Title string
|
|
||||||
Channel string
|
|
||||||
VideoID string
|
|
||||||
Length time.Duration
|
|
||||||
PCM *ffmpeg.PCM
|
|
||||||
Playlist Playlist
|
|
||||||
DLuri string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Song) NewStream() (err error) {
|
|
||||||
s.PCM, err = ffmpeg.NewPCM(s.DLuri, sampleRate, channels)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Queue struct {
|
|
||||||
Events events.EventEmmiter
|
|
||||||
playing bool
|
|
||||||
list *list.List
|
|
||||||
current *list.Element
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q Queue) IsPlaying() bool {
|
|
||||||
return q.playing
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Play() {
|
|
||||||
q.playing = true
|
|
||||||
if q.list.Len() > 0 {
|
|
||||||
play := q.list.Front()
|
|
||||||
q.current = play
|
|
||||||
app.events.Emit("song_start")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Add(s *Song) {
|
|
||||||
el := q.list.PushBack(s)
|
|
||||||
if el == q.list.Front() {
|
|
||||||
q.Play()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q Queue) QLen() int {
|
|
||||||
return q.list.Len()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q Queue) Current() *Song {
|
|
||||||
if q.current == nil {
|
|
||||||
return new(Song)
|
|
||||||
}
|
|
||||||
return q.current.Value.(*Song)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Reset() {
|
|
||||||
err := app.mpd.Clear()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Next() {
|
|
||||||
if q.current == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
next := q.current.Next()
|
|
||||||
if next == nil {
|
|
||||||
next = q.list.Front()
|
|
||||||
}
|
|
||||||
|
|
||||||
pcm := next.Value.(*Song).PCM
|
|
||||||
if pcm != nil && pcm.Position() != 0 {
|
|
||||||
err := next.Value.(*Song).NewStream()
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
q.current = next
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Prev() {
|
|
||||||
if q.current == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
prev := q.current.Prev()
|
|
||||||
if prev == nil {
|
|
||||||
prev = q.list.Back()
|
|
||||||
}
|
|
||||||
|
|
||||||
err := prev.Value.(*Song).NewStream()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
q.current = prev
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Preload() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Stream(samples [][2]float64) (n int, ok bool) {
|
|
||||||
// We use the filled variable to track how many samples we've
|
|
||||||
// successfully filled already. We loop until all samples are filled.
|
|
||||||
filled := 0
|
|
||||||
|
|
||||||
for filled < len(samples) {
|
|
||||||
// There are no streamers in the queue, so we stream silence.
|
|
||||||
if q.current == nil || q.list.Len() == 0 {
|
|
||||||
for i := range samples[filled:] {
|
|
||||||
samples[i][0] = 0
|
|
||||||
samples[i][1] = 0
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// We stream from the first streamer in the queue.
|
|
||||||
n, ok := q.current.Value.(*Song).PCM.Stream(samples[filled:])
|
|
||||||
// If it's drained, we pop it from the queue, thus continuing with
|
|
||||||
// the next streamer.
|
|
||||||
if !ok {
|
|
||||||
q.Next()
|
|
||||||
q.Events.Emit("song_over", nil)
|
|
||||||
}
|
|
||||||
// We update the number of filled samples.
|
|
||||||
filled += n
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(samples), true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Err() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queue) Position() int {
|
|
||||||
if q.current == nil || q.current.Value.(*Song).PCM == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return q.current.Value.(*Song).PCM.Position()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q Queue) Len() int {
|
|
||||||
if q.current == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return int(q.current.Value.(*Song).Length.Milliseconds())
|
|
||||||
}
|
|
36
routes.go
36
routes.go
|
@ -18,16 +18,18 @@ var upgrader = websocket.Upgrader{
|
||||||
WriteBufferSize: 1024,
|
WriteBufferSize: 1024,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var router *httprouter.Router
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
app.router = httprouter.New()
|
router = httprouter.New()
|
||||||
|
|
||||||
app.router.GET("/", app.Index)
|
router.GET("/", Index)
|
||||||
app.router.GET("/play/:playlist", app.Play)
|
router.GET("/play/:playlist", Play)
|
||||||
app.router.GET("/reset", app.Reset)
|
router.GET("/reset", Reset)
|
||||||
app.router.GET("/public/*js", app.ServeFiles)
|
router.GET("/public/*js", ServeFiles)
|
||||||
app.router.GET("/css/*css", app.ServeFiles)
|
router.GET("/css/*css", ServeFiles)
|
||||||
|
|
||||||
app.router.HandlerFunc("GET", "/ws", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
router.HandlerFunc("GET", "/ws", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("WS connection from %v\n", r.RemoteAddr)
|
log.Printf("WS connection from %v\n", r.RemoteAddr)
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -42,7 +44,7 @@ func init() {
|
||||||
}))
|
}))
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Fatal(http.ListenAndServe(":8824", app.router))
|
log.Fatal(http.ListenAndServe(":8824", router))
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ type IndexData struct {
|
||||||
Ambiance []Ambiance
|
Ambiance []Ambiance
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app App) ServeFiles(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
func ServeFiles(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
filePath := filepath.Join(".", r.URL.Path)
|
filePath := filepath.Join(".", r.URL.Path)
|
||||||
|
|
||||||
file, err := os.Open(filePath)
|
file, err := os.Open(filePath)
|
||||||
|
@ -73,8 +75,8 @@ func (app App) ServeFiles(w http.ResponseWriter, r *http.Request, _ httprouter.P
|
||||||
http.ServeContent(w, r, filename, t, file)
|
http.ServeContent(w, r, filename, t, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app App) Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
playlists, err := app.GetPlaylists()
|
playlists, err := GetPlaylists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Unable to get playlists. "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "Unable to get playlists. "+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
@ -94,11 +96,11 @@ func (app App) Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) Play(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
func Play(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
plname := p.ByName("playlist")
|
plname := p.ByName("playlist")
|
||||||
|
|
||||||
if plname == "reset" {
|
if plname == "reset" {
|
||||||
app.events.Emit("stop", nil)
|
ev.Emit("stop", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,14 +109,14 @@ func (app *App) Play(w http.ResponseWriter, r *http.Request, p httprouter.Params
|
||||||
http.Error(w, "Unable to parse uuid. "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "Unable to parse uuid. "+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.events.Emit("new_playlist", plid)
|
ev.Emit("new_playlist", plid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) Add(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
func Add(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) Reset(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
func Reset(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
app.events.Emit("stop", nil)
|
ev.Emit("stop", nil)
|
||||||
}
|
}
|
||||||
|
|
8
ws.go
8
ws.go
|
@ -64,7 +64,7 @@ func handleWS(c *websocket.Conn) error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
msg := app.songInfoEvent("song_info")
|
msg := songInfoEvent("song_info")
|
||||||
|
|
||||||
vol := make(map[string]interface{})
|
vol := make(map[string]interface{})
|
||||||
volout := make(map[string]float64)
|
volout := make(map[string]float64)
|
||||||
|
@ -77,11 +77,11 @@ func handleWS(c *websocket.Conn) error {
|
||||||
c.WriteJSON(msg)
|
c.WriteJSON(msg)
|
||||||
c.WriteJSON(vol)
|
c.WriteJSON(vol)
|
||||||
|
|
||||||
if app.ambiance.Len() > 0 {
|
if amb_mixer.Len() > 0 {
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
out := make(map[string]interface{})
|
out := make(map[string]interface{})
|
||||||
msg["event"] = "ambiance_play"
|
msg["event"] = "ambiance_play"
|
||||||
out["id"] = app.curamb.Id
|
out["id"] = amb_curr.Id
|
||||||
msg["payload"] = out
|
msg["payload"] = out
|
||||||
c.WriteJSON(msg)
|
c.WriteJSON(msg)
|
||||||
} else {
|
} else {
|
||||||
|
@ -97,6 +97,6 @@ func handleWS(c *websocket.Conn) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
app.events.Emit(events.EventName(msg.Event), msg.Payload)
|
ev.Emit(events.EventName(msg.Event), msg.Payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
48
youtube.go
48
youtube.go
|
@ -9,7 +9,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"math/big"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
mrand "math/rand"
|
mrand "math/rand"
|
||||||
|
@ -19,6 +18,8 @@ import (
|
||||||
"google.golang.org/api/youtube/v3"
|
"google.golang.org/api/youtube/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var yt_svc *youtube.Service
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.Println("youtube.go loading..")
|
log.Println("youtube.go loading..")
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ func init() {
|
||||||
|
|
||||||
apikey := config.GetString("youtube.apikey")
|
apikey := config.GetString("youtube.apikey")
|
||||||
|
|
||||||
app.youtube, err = youtube.NewService(context.Background(), option.WithAPIKey(apikey))
|
yt_svc, err = youtube.NewService(context.Background(), option.WithAPIKey(apikey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -46,39 +47,6 @@ func ShufflePlaylist(list []string) ([]string, error) {
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) GetSong(list []string) string {
|
|
||||||
return list[app.plidx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (app *App) GetNextSong(list []string) string {
|
|
||||||
app.plidx++
|
|
||||||
if app.plidx >= len(app.active) {
|
|
||||||
app.plidx = 0
|
|
||||||
}
|
|
||||||
return list[app.plidx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (app *App) GetPrevSong(list []string) string {
|
|
||||||
app.plidx--
|
|
||||||
if app.plidx < 0 {
|
|
||||||
app.plidx = len(list)
|
|
||||||
}
|
|
||||||
return list[app.plidx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetRandomSong(list []string) string {
|
|
||||||
if !(len(list) > 0) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(list)-1)))
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Failed to get random int, ", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return list[idx.Int64()]
|
|
||||||
}
|
|
||||||
|
|
||||||
type VideoInfo struct {
|
type VideoInfo struct {
|
||||||
Title string
|
Title string
|
||||||
Channel string
|
Channel string
|
||||||
|
@ -86,9 +54,9 @@ type VideoInfo struct {
|
||||||
Uri string
|
Uri string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app App) Video(vid string) (out VideoInfo, err error) {
|
func YTVideo(vid string) (out VideoInfo, err error) {
|
||||||
_, r, err := app.cache.GetOrCreate(vid+".videoinfo", func() (io.ReadCloser, error) {
|
_, r, err := cache.GetOrCreate(vid+".videoinfo", func() (io.ReadCloser, error) {
|
||||||
call := app.youtube.Videos.List([]string{"snippet", "contentDetails"})
|
call := yt_svc.Videos.List([]string{"snippet", "contentDetails"})
|
||||||
call.MaxResults(1)
|
call.MaxResults(1)
|
||||||
call.Id(vid)
|
call.Id(vid)
|
||||||
resp, err := call.Do()
|
resp, err := call.Do()
|
||||||
|
@ -128,8 +96,8 @@ func (app App) Video(vid string) (out VideoInfo, err error) {
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app App) Playlist(playlist string) ([]string, error) {
|
func YTPlaylist(playlist string) ([]string, error) {
|
||||||
call := app.youtube.PlaylistItems.List([]string{"contentDetails"})
|
call := yt_svc.PlaylistItems.List([]string{"contentDetails"})
|
||||||
pageToken := ""
|
pageToken := ""
|
||||||
call = call.MaxResults(50)
|
call = call.MaxResults(50)
|
||||||
call = call.PlaylistId(playlist)
|
call = call.PlaylistId(playlist)
|
||||||
|
|
Loading…
Reference in New Issue