diff --git a/events.go b/events.go index ace6953..7af1fa3 100644 --- a/events.go +++ b/events.go @@ -3,7 +3,9 @@ package main import ( "context" "dndmusicbot/ffmpeg" + "dndmusicbot/loop" discordspeaker "dndmusicbot/speaker" + "dndmusicbot/ytdl" "encoding/json" "fmt" "log" @@ -40,8 +42,10 @@ func init() { app.events.On("preload_song", app.preloadSong) app.events.On("song_over", app.songOver) //app.events.On("song_position", app.songPosition) + app.events.On("ambiance_play", app.ambiancePlay) app.events.On("ambiance_stop", app.ambianceStop) + app.events.On("ambiance_add", app.ambianceAdd) app.events.On("stop", app.stop) app.events.On("next", app.nextSong) @@ -127,7 +131,9 @@ func (app *App) ambiancePlay(payload ...interface{}) { if app.ambiance.IsPlaying() { app.ambiance.Reset() } - app.ambiance.Add(play) + + loop := loop.Loop(-1, play) + app.ambiance.Add(loop) discordspeaker.Unlock() msg := make(map[string]interface{}) @@ -153,6 +159,48 @@ func (app *App) ambianceStop(payload ...interface{}) { } +func (app *App) ambianceAdd(payload ...interface{}) { + if !(len(payload) > 0) { + log.Println("addPlaylist called without a payload.") + return + } + + log.Println("ambiance_add event received") + + var data map[string]string + switch js := payload[0].(type) { + case json.RawMessage: + json.Unmarshal(js, &data) + default: + log.Println("newPlaylist called with invalid payload.") + return + } + + amburl, ok := data["url"] + if !ok { + log.Println("addPlaylist without url") + return + } + ambtitle, ok := data["title"] + if !ok { + log.Println("addPlaylist without title") + return + } + + err := ytdl.DownloadAmbiance(amburl, ambtitle) + if err != nil { + log.Println(err) + return + } + + msg := make(map[string]interface{}) + out := make(map[string]interface{}) + msg["event"] = "ambiance_add" + out["type"] = ambtitle + msg["payload"] = out + ws_msg <- msg +} + func (app *App) songPosition(payload ...interface{}) { if !app.queue.IsPlaying() { return @@ -256,16 +304,6 @@ func (app *App) nextSong(payload ...interface{}) { return } - for { - time.Sleep(1 * time.Second) - if app.queue.QLen() == 0 { - log.Println("retrying...") - song = app.GetSong(app.active) - } else { - break - } - } - discordspeaker.Lock() app.queue.Reset() app.queue.Add(f) diff --git a/ffmpeg/ffmpeg.go b/ffmpeg/ffmpeg.go index f2e89be..2606ed4 100644 --- a/ffmpeg/ffmpeg.go +++ b/ffmpeg/ffmpeg.go @@ -24,6 +24,7 @@ type FFmpeg struct { PMutex *sync.RWMutex ProcessState *os.ProcessState err chan error + fb chan bool } func NewFFmpeg(uri string, sampleRate int, channels int) (ff *FFmpeg, err error) { @@ -42,6 +43,7 @@ func NewFFmpeg(uri string, sampleRate int, channels int) (ff *FFmpeg, err error) time.Sleep(500 * time.Millisecond) } +RETRY: ff = new(FFmpeg) ff.PMutex = &sync.RWMutex{} ff.Len = yt.Len @@ -53,6 +55,7 @@ func NewFFmpeg(uri string, sampleRate int, channels int) (ff *FFmpeg, err error) ff.Cmd = exec.CommandContext( ctx, "ffmpeg", + "-xerror", "-i", yt.Url, "-f", "s16le", "-v", "error", @@ -71,18 +74,23 @@ func NewFFmpeg(uri string, sampleRate int, channels int) (ff *FFmpeg, err error) ff.Out = bytes.NewBuffer(make([]byte, 43920)) ff.Cmd.Stdout = ff.Out - ff.Start() + exitctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() - return -} - -func (ff *FFmpeg) Start() { go func() { ff.Cmd.Start() ff.err <- ff.Cmd.Wait() }() - ff.Started = true + select { + case <-exitctx.Done(): + ff.Started = true + case <-ff.err: + log.Println("ffmpeg exited early, retry...") + goto RETRY + } + + return } func (ff *FFmpeg) Close() error { diff --git a/go.mod b/go.mod index 852a373..bc5cd8d 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module dndmusicbot go 1.19 -replace github.com/3d0c/gmf => /home/steino/dev/go/gmf - require ( github.com/bwmarrin/discordgo v0.26.1 github.com/dpup/gohubbub v0.0.0-20140517235056-2dc6969d22d8 diff --git a/js/script.js b/js/script.js index 677ed3c..e1e132b 100644 --- a/js/script.js +++ b/js/script.js @@ -122,12 +122,32 @@ window.onload = function() { } } + document.querySelector("#addambiance").addEventListener("click", (e) => { + e.preventDefault() + + output.innerText = "" + var title = document.querySelector("#inputambiance > input[name='title']") + var url = document.querySelector("#inputambiance > input[name='url']") + if (title.value == "" || url.value == "") { + output.innerText = "Title or Url is empty!" + return + } + + ws.send(JSON.stringify({ + "event": "ambiance_add", + "payload": { + "title": title.value, + "url": url.value + } + })) + }) + submit.addEventListener("click", (e) => { e.preventDefault() output.innerText = "" - var title = document.querySelector(".container2 input[name='title'") - var url = document.querySelector(".container2 input[name='url'") + var title = document.querySelector("#inputplaylist > input[name='title']") + var url = document.querySelector("#inputplaylist > input[name='url']") if (title.value == "" || url.value == "") { output.innerText = "Title or Url is empty!" return @@ -140,6 +160,9 @@ window.onload = function() { "url": url.value } })) + + title.innerText = "" + url.innerText = "" }) document.querySelectorAll("#items").forEach(item => item.addEventListener("click", (e) => { diff --git a/tmpl/index.tmpl b/tmpl/index.tmpl index ab63d69..3312da4 100644 --- a/tmpl/index.tmpl +++ b/tmpl/index.tmpl @@ -5,8 +5,8 @@